From 3c7f88556902e942f4969fa7b07a8874fa9595dd Mon Sep 17 00:00:00 2001 From: Joshua Bevan Date: Mon, 13 Feb 2017 11:45:32 -0500 Subject: [PATCH 1/9] initial mesh interaction "starter" function --- boxtree/mesh_interaction.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 boxtree/mesh_interaction.py diff --git a/boxtree/mesh_interaction.py b/boxtree/mesh_interaction.py new file mode 100644 index 0000000..2f84e7a --- /dev/null +++ b/boxtree/mesh_interaction.py @@ -0,0 +1,36 @@ +import numpy as np + +def mesh_and_target_area_intersection(mesh, area_type='box', k=1): + #potentially could produce multiple area types if needed later + for i in range(len(mesh.groups)): + #for now, just lump all mesh groups together + nodes = np.r_['1',mesh.groups[i].nodes] + if area_type=='box': + #k param: how many local mesh widths to extend tgt box out in each dir + lb = np.amin(nodes[0,:,:],axis=1) + rb = np.amax(nodes[0,:,:],axis=1) + tb = np.amax(nodes[1,:,:],axis=1) + bb = np.amin(nodes[1,:,:],axis=1) + hx = rb-lb + hy = tb-bb + tgt_lb = lb-k*hx + tgt_rb = rb+k*hx + tgt_tb = tb+k*hy + tgt_bb = bb-k*hy + + na = np.newaxis + #row number=elem number + intersecting = np.logical_and( + np.logical_or( + np.logical_and(tgt_lb[:,na] Date: Mon, 13 Feb 2017 11:49:30 -0500 Subject: [PATCH 2/9] Initial inoperative mesh_interaction test script --- test/test_mesh_interaction.py | 47 +++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 test/test_mesh_interaction.py diff --git a/test/test_mesh_interaction.py b/test/test_mesh_interaction.py new file mode 100644 index 0000000..ddb2e6d --- /dev/null +++ b/test/test_mesh_interaction.py @@ -0,0 +1,47 @@ +import numpy as np +import pyopencl as cl + +order = 3 + +cl_ctx = cl.create_some_context() +queue = cl.CommandQueue(cl_ctx) + +from meshmode.mesh.io import read_gmsh +mesh = read_gmsh("blob-2d.msh",force_ambient_dim=2) + +from meshmode.discretization import Discretization +from meshmode.discretization.poly_element import InterpolatoryQuadratureSimplexGroupFactory +discr = Discretization(cl_ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(order)) + +#Useful vis for debuging +#from meshmode.mesh.visualization import draw_2d_mesh +#draw_2d_mesh(mesh, set_bounding_box=True, draw_vertex_numbers=False, draw_element_numbers=True) +#import matplotlib.pyplot as pt +#pt.show() +#n=discr.nodes().get(queue) +#plt.plot(n[0,],n[1,],'o') + +from boxtree.mesh_interaction import mesh_and_target_area_intersection +intersection, intersection_starts = mesh_and_target_area_intersection(mesh,area_type='box', k=1) + +from boxtree import TreeBuilder +tb = TreeBuilder(cl_ctx) + +#from pytools.obj_array import make_obj_array +#particles = make_obj_array([ +# discr.nodes()[i,].get(queue) +# for i in range(2)]) + +#tree, _ = tb(queue, particles, max_particles_in_box=10) + +#dims = 2 +#nparticles = 10**3 +# +#from pyopencl.clrandom import RanluxGenerator +#rng = RanluxGenerator(queue, seed=15) +#from pytools.obj_array import make_obj_array +#particles = make_obj_array([ +# rng.normal(queue, nparticles, dtype=np.float64) +# for i in range(dims)]) +# +#tree, _ = tb(queue, particles, max_particles_in_box=10) \ No newline at end of file -- GitLab From c0bf2afcf07e2e236a545b6deeebbc4bfb2ba981 Mon Sep 17 00:00:00 2001 From: Joshua Bevan Date: Mon, 13 Feb 2017 11:50:59 -0500 Subject: [PATCH 3/9] blob_2d .msh file for test script, perhaps to later be replaced by .step and gmsh generation if necessary? --- test/blob-2d.msh | 446 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 446 insertions(+) create mode 100644 test/blob-2d.msh diff --git a/test/blob-2d.msh b/test/blob-2d.msh new file mode 100644 index 0000000..d9d2f7c --- /dev/null +++ b/test/blob-2d.msh @@ -0,0 +1,446 @@ +$MeshFormat +2.2 0 8 +$EndMeshFormat +$Nodes +146 +1 -0.4725430905820004 0.1646517366169589 0 +2 -0.4767799430995929 0.1159304601168752 0 +3 -0.4767322166399771 0.06703688281240093 0 +4 -0.4702937700635583 0.01860086453797516 0 +5 -0.4538183776589282 -0.02729702900844069 0 +6 -0.4227369483017478 -0.0645819673749298 0 +7 -0.378438447476652 -0.08434169531943977 0 +8 -0.3297463531825587 -0.08755782429564593 0 +9 -0.2809922952332325 -0.08369971986917121 0 +10 -0.2323017027563748 -0.07902694381423922 0 +11 -0.1834319137022549 -0.07737353247625005 0 +12 -0.1347544746852848 -0.08171236732517156 0 +13 -0.08738693003876633 -0.09373390024415561 0 +14 -0.04169550328514776 -0.1111600381215554 0 +15 0.002930509478649007 -0.1311869920451043 0 +16 0.04743753303695913 -0.1514793872925139 0 +17 0.09323408996811799 -0.1685627310701821 0 +18 0.1414012341904861 -0.1710396922413012 0 +19 0.1732607869944924 -0.1361155792046744 0 +20 0.1831467818070197 -0.08838035357878156 0 +21 0.1831714242748896 -0.03950825402407249 0 +22 0.1771778625795523 0.009016005361491941 0 +23 0.166382378736668 0.05670673201188711 0 +24 0.1509706129502917 0.1031089155841279 0 +25 0.130397032983188 0.147451038094475 0 +26 0.103223173029645 0.1880361965098842 0 +27 0.06689182739503687 0.2204692212154625 0 +28 0.02197249056993197 0.23937220789002 0 +29 -0.02607919267527611 0.2483400416739637 0 +30 -0.07461773801025579 0.2544025145406534 0 +31 -0.1228489382886651 0.26248503488488 0 +32 -0.1703906535398324 0.2739771483445165 0 +33 -0.217649103296364 0.2866029236958204 0 +34 -0.2651766562306084 0.2981559866619584 0 +35 -0.3134270431714214 0.3060437840417993 0 +36 -0.3622390050029438 0.3059949681103042 0 +37 -0.4084081447638059 0.2909021121876902 0 +38 -0.4431589393839811 0.2570920965607918 0 +39 -0.462998838028793 0.2125712775436452 0 +40 -0.2933233764464115 0.1138267430790992 0 +41 -0.02847814951822331 0.06951342048909848 0 +42 -0.1507175526648517 0.1305814351685241 0 +43 0.05671910460881946 -0.0196559247139545 0 +44 -0.208826701719056 0.03246116157417323 0 +45 -0.3556479917501454 0.2018958929113452 0 +46 -0.3549866101923704 0.01732350767456248 0 +47 -0.1074529364327065 0.01319266311729878 0 +48 -0.2267260446319173 0.1934357802301528 0 +49 -0.0610745157004064 0.1600077687266293 0 +50 -0.3883524208181273 0.111183209576144 0 +51 0.05889041499476744 0.0776338687461553 0 +52 -0.03286645100321878 -0.02369398759946384 0 +53 0.02221409155934051 0.1462759232954491 0 +54 0.1017024117139075 -0.08755561321413979 0 +55 -0.2818538361061502 -0.003939447723841805 0 +56 -0.2930198526593978 0.2348511079107199 0 +57 -0.157597301662713 0.1988376537868406 0 +58 -0.09688546668750414 0.08681191013630563 0 +59 -0.2142058556152331 0.110169343185449 0 +60 0.1156514499997027 0.02848427806311571 0 +61 -0.4128986346885033 0.05443782465991698 0 +62 -0.4105147942411019 0.167280714103395 0 +63 0.01444774030469731 -0.05474763972018154 0 +64 -0.1634807173903056 -0.01695751457175493 0 +65 0.02472101487767853 0.02682173602829646 0 +66 -0.2982134796793256 0.1589279384008412 0 +67 -0.1550565803827874 0.0684071791682978 0 +68 -0.2570833955478836 0.04937180456916568 0 +69 -0.3352936721186352 0.07765851422549841 0 +70 -0.3305251100090268 -0.02912650765304481 0 +71 0.1232712319791713 -0.03998024696762692 0 +72 -0.1076089234619594 0.2134617374872078 0 +73 -0.01516041919738775 0.1973989129999587 0 +74 -0.3385876211475933 0.2528280561940174 0 +75 -0.2298161207061463 -0.02377906621915205 0 +76 0.07896208292736451 0.1298042755458195 0 +77 -0.4003774279055767 -0.01332706007358847 0 +78 -0.08435996183459216 -0.03781976387024838 0 +79 -0.3928732020052436 0.2331762588758936 0 +80 -0.05414129333359385 0.02275864500842628 0 +81 -0.3357226788150336 0.1314877635332329 0 +82 -0.02350537513687817 0.1234217083348019 0 +83 -0.1983295584050745 0.2336241273464102 0 +84 0.01304169938750516 0.09946768053857757 0 +85 -0.1977627582096242 0.1488792465547518 0 +86 -0.2499853987658275 0.1446668696974264 0 +87 0.04461051284959683 -0.1014584649369309 0 +88 -0.3086956668329468 0.03722270104251224 0 +89 -0.1055760958322025 0.1255049994839639 0 +90 0.1130605683101332 0.07003350494559785 0 +91 -0.4378396886896197 0.09157841975878761 0 +92 0.1316517540122663 -0.1218607719810022 0 +93 -0.05636558772024425 0.213898693008732 0 +94 0.0569057946782392 0.1670282746351865 0 +95 -0.251903797242819 0.244749207547547 0 +96 -0.04259864331817997 -0.06864874578755542 0 +97 0.07341201162712796 0.02794716069702885 0 +98 -0.1264008156441787 0.1664595192975996 0 +99 0.01109293989880011 -0.0129221658506799 0 +100 -0.1598541394438701 0.02896921228600524 0 +101 -0.2637389593339061 -0.04467477554652227 0 +102 0.1440120687448451 -0.07491671079570661 0 +103 0.0694145640978272 -0.05811944733703039 0 +104 -0.06343932078857029 0.1043590166527328 0 +105 -0.1271358308635849 -0.0395834938425037 0 +106 -0.4376053423594887 0.1328175270655886 0 +107 -0.3683443825353412 0.1605091809389714 0 +108 -0.3699274481945085 -0.04333102157057589 0 +109 0.08372726031616951 -0.1261833936989538 0 +110 -0.4297533132363489 0.01689241587734225 0 +111 -0.3733449446096971 0.06072851240081606 0 +112 -0.2385189574430036 0.01359841853098009 0 +113 -0.2945221907608757 0.2701665757127336 0 +114 0.02456850236467112 0.1911285890934324 0 +115 -0.4233094992106001 0.2071281720893554 0 +116 -0.1195246723542033 0.0567883060803262 0 +117 -0.0123133767320886 0.02402921316156392 0 +118 0.106456142433149 0.1056063205832351 0 +119 -0.2722512494827684 0.1964713698426759 0 +120 -0.3764171768348171 0.2685581126800726 0 +121 -0.07454773947258309 0.0594726504849552 0 +122 -0.1525098712549517 0.2376580258697706 0 +123 -0.1770334590520359 0.1008255546664961 0 +124 -0.3147863335002259 0.2020469892040668 0 +125 0.1413610205651505 0.0005033077372428307 0 +126 0.09390072603782196 -0.01260533241814538 0 +127 -0.201453729815424 0.06870113952150303 0 +128 -0.2973713107729749 -0.04979965501764522 0 +129 -0.2514828412664952 0.09296096822316524 0 +130 -0.1940130779682059 -0.04195144039536036 0 +131 -0.1318637160510444 0.09692995937266657 0 +132 -0.2909730970379276 0.07265145874631751 0 +133 -0.1916138009097272 0.1860347080318873 0 +134 -0.3942721861264993 0.02721104010780984 0 +135 -0.004461076794076924 -0.09344037612226547 0 +136 -0.164671330921184 0.1652013944062097 0 +137 -0.3901379739484865 0.1939980437837921 0 +138 -0.0107330904392276 0.1584094356536605 0 +139 -0.3190153057851235 0.005370063335047026 0 +140 -0.3335300684063315 0.1699261292740086 0 +141 -0.4472878422202458 0.04745912661657253 0 +142 -0.1964707115921482 -0.002085237742636636 0 +143 -0.0716416676821785 -0.005570624691587089 0 +144 0.04333753573999888 0.1182635314722547 0 +145 -0.1594972907009092 -0.05220175449839765 0 +146 0.005791678686025703 0.06169763089370611 0 +$EndNodes +$Elements +291 +1 15 2 0 1 1 +2 1 2 0 1 1 2 +3 1 2 0 1 2 3 +4 1 2 0 1 3 4 +5 1 2 0 1 4 5 +6 1 2 0 1 5 6 +7 1 2 0 1 6 7 +8 1 2 0 1 7 8 +9 1 2 0 1 8 9 +10 1 2 0 1 9 10 +11 1 2 0 1 10 11 +12 1 2 0 1 11 12 +13 1 2 0 1 12 13 +14 1 2 0 1 13 14 +15 1 2 0 1 14 15 +16 1 2 0 1 15 16 +17 1 2 0 1 16 17 +18 1 2 0 1 17 18 +19 1 2 0 1 18 19 +20 1 2 0 1 19 20 +21 1 2 0 1 20 21 +22 1 2 0 1 21 22 +23 1 2 0 1 22 23 +24 1 2 0 1 23 24 +25 1 2 0 1 24 25 +26 1 2 0 1 25 26 +27 1 2 0 1 26 27 +28 1 2 0 1 27 28 +29 1 2 0 1 28 29 +30 1 2 0 1 29 30 +31 1 2 0 1 30 31 +32 1 2 0 1 31 32 +33 1 2 0 1 32 33 +34 1 2 0 1 33 34 +35 1 2 0 1 34 35 +36 1 2 0 1 35 36 +37 1 2 0 1 36 37 +38 1 2 0 1 37 38 +39 1 2 0 1 38 39 +40 1 2 0 1 39 1 +41 2 2 0 1 52 63 96 +42 2 2 0 1 46 70 108 +43 2 2 0 1 19 92 20 +44 2 2 0 1 46 108 77 +45 2 2 0 1 49 98 72 +46 2 2 0 1 20 92 102 +47 2 2 0 1 23 60 90 +48 2 2 0 1 23 125 60 +49 2 2 0 1 1 115 62 +50 2 2 0 1 25 76 26 +51 2 2 0 1 49 89 98 +52 2 2 0 1 13 105 78 +53 2 2 0 1 48 119 95 +54 2 2 0 1 12 105 13 +55 2 2 0 1 31 72 122 +56 2 2 0 1 48 95 83 +57 2 2 0 1 30 72 31 +58 2 2 0 1 51 90 97 +59 2 2 0 1 60 97 90 +60 2 2 0 1 40 81 66 +61 2 2 0 1 50 106 62 +62 2 2 0 1 26 76 94 +63 2 2 0 1 63 135 96 +64 2 2 0 1 54 103 71 +65 2 2 0 1 68 129 127 +66 2 2 0 1 44 68 127 +67 2 2 0 1 1 39 115 +68 2 2 0 1 45 79 74 +69 2 2 0 1 40 66 86 +70 2 2 0 1 57 122 72 +71 2 2 0 1 50 61 91 +72 2 2 0 1 47 105 64 +73 2 2 0 1 40 69 81 +74 2 2 0 1 52 99 63 +75 2 2 0 1 43 63 99 +76 2 2 0 1 35 74 36 +77 2 2 0 1 50 111 61 +78 2 2 0 1 67 100 127 +79 2 2 0 1 47 116 121 +80 2 2 0 1 1 62 106 +81 2 2 0 1 50 81 69 +82 2 2 0 1 28 73 29 +83 2 2 0 1 37 79 38 +84 2 2 0 1 127 100 44 +85 2 2 0 1 47 121 80 +86 2 2 0 1 43 103 63 +87 2 2 0 1 71 103 126 +88 2 2 0 1 50 62 107 +89 2 2 0 1 15 135 87 +90 2 2 0 1 47 64 100 +91 2 2 0 1 51 65 146 +92 2 2 0 1 8 108 70 +93 2 2 0 1 51 76 118 +94 2 2 0 1 5 77 6 +95 2 2 0 1 46 139 70 +96 2 2 0 1 55 88 68 +97 2 2 0 1 43 65 97 +98 2 2 0 1 63 87 135 +99 2 2 0 1 51 97 65 +100 2 2 0 1 43 99 65 +101 2 2 0 1 21 71 125 +102 2 2 0 1 22 125 23 +103 2 2 0 1 59 127 129 +104 2 2 0 1 46 69 88 +105 2 2 0 1 15 87 16 +106 2 2 0 1 41 117 80 +107 2 2 0 1 51 118 90 +108 2 2 0 1 6 77 108 +109 2 2 0 1 50 91 106 +110 2 2 0 1 49 72 93 +111 2 2 0 1 37 120 79 +112 2 2 0 1 49 93 73 +113 2 2 0 1 45 74 124 +114 2 2 0 1 56 124 74 +115 2 2 0 1 21 102 71 +116 2 2 0 1 47 78 105 +117 2 2 0 1 41 146 117 +118 2 2 0 1 66 119 86 +119 2 2 0 1 7 108 8 +120 2 2 0 1 35 113 74 +121 2 2 0 1 53 84 82 +122 2 2 0 1 57 83 122 +123 2 2 0 1 50 69 111 +124 2 2 0 1 55 128 70 +125 2 2 0 1 10 75 130 +126 2 2 0 1 51 146 84 +127 2 2 0 1 56 95 119 +128 2 2 0 1 41 82 84 +129 2 2 0 1 57 133 83 +130 2 2 0 1 30 93 72 +131 2 2 0 1 55 68 112 +132 2 2 0 1 44 112 68 +133 2 2 0 1 76 144 94 +134 2 2 0 1 53 94 144 +135 2 2 0 1 29 73 93 +136 2 2 0 1 48 86 119 +137 2 2 0 1 17 92 18 +138 2 2 0 1 38 79 115 +139 2 2 0 1 32 83 33 +140 2 2 0 1 23 90 24 +141 2 2 0 1 21 125 22 +142 2 2 0 1 28 114 73 +143 2 2 0 1 59 86 85 +144 2 2 0 1 2 91 3 +145 2 2 0 1 54 71 102 +146 2 2 0 1 10 101 75 +147 2 2 0 1 57 72 98 +148 2 2 0 1 56 74 113 +149 2 2 0 1 6 108 7 +150 2 2 0 1 46 111 69 +151 2 2 0 1 8 70 128 +152 2 2 0 1 40 132 69 +153 2 2 0 1 48 85 86 +154 2 2 0 1 55 70 139 +155 2 2 0 1 41 104 82 +156 2 2 0 1 49 73 138 +157 2 2 0 1 53 138 114 +158 2 2 0 1 5 110 77 +159 2 2 0 1 55 75 101 +160 2 2 0 1 47 143 78 +161 2 2 0 1 13 78 96 +162 2 2 0 1 36 74 120 +163 2 2 0 1 51 144 76 +164 2 2 0 1 46 77 134 +165 2 2 0 1 52 96 78 +166 2 2 0 1 55 112 75 +167 2 2 0 1 3 91 141 +168 2 2 0 1 73 114 138 +169 2 2 0 1 54 102 92 +170 2 2 0 1 52 78 143 +171 2 2 0 1 44 100 142 +172 2 2 0 1 45 137 79 +173 2 2 0 1 50 107 81 +174 2 2 0 1 25 118 76 +175 2 2 0 1 41 121 104 +176 2 2 0 1 20 102 21 +177 2 2 0 1 10 130 11 +178 2 2 0 1 52 143 80 +179 2 2 0 1 32 122 83 +180 2 2 0 1 38 115 39 +181 2 2 0 1 49 82 104 +182 2 2 0 1 63 103 87 +183 2 2 0 1 74 79 120 +184 2 2 0 1 58 121 116 +185 2 2 0 1 18 92 19 +186 2 2 0 1 33 83 95 +187 2 2 0 1 48 83 133 +188 2 2 0 1 17 109 92 +189 2 2 0 1 42 123 85 +190 2 2 0 1 59 85 123 +191 2 2 0 1 47 80 143 +192 2 2 0 1 43 126 103 +193 2 2 0 1 61 141 91 +194 2 2 0 1 33 95 34 +195 2 2 0 1 59 129 86 +196 2 2 0 1 49 138 82 +197 2 2 0 1 29 93 30 +198 2 2 0 1 66 81 140 +199 2 2 0 1 49 104 89 +200 2 2 0 1 52 80 117 +201 2 2 0 1 41 80 121 +202 2 2 0 1 40 86 129 +203 2 2 0 1 53 114 94 +204 2 2 0 1 13 96 14 +205 2 2 0 1 65 117 146 +206 2 2 0 1 51 84 144 +207 2 2 0 1 26 94 27 +208 2 2 0 1 55 101 128 +209 2 2 0 1 9 101 10 +210 2 2 0 1 4 110 5 +211 2 2 0 1 53 144 84 +212 2 2 0 1 34 95 113 +213 2 2 0 1 64 142 100 +214 2 2 0 1 42 98 89 +215 2 2 0 1 16 87 109 +216 2 2 0 1 16 109 17 +217 2 2 0 1 54 87 103 +218 2 2 0 1 56 113 95 +219 2 2 0 1 53 82 138 +220 2 2 0 1 1 106 2 +221 2 2 0 1 54 109 87 +222 2 2 0 1 2 106 91 +223 2 2 0 1 43 97 126 +224 2 2 0 1 58 89 104 +225 2 2 0 1 27 114 28 +226 2 2 0 1 14 96 135 +227 2 2 0 1 55 139 88 +228 2 2 0 1 8 128 9 +229 2 2 0 1 58 131 89 +230 2 2 0 1 42 89 131 +231 2 2 0 1 68 88 132 +232 2 2 0 1 60 126 97 +233 2 2 0 1 58 104 121 +234 2 2 0 1 75 112 142 +235 2 2 0 1 69 132 88 +236 2 2 0 1 41 84 146 +237 2 2 0 1 54 92 109 +238 2 2 0 1 44 142 112 +239 2 2 0 1 27 94 114 +240 2 2 0 1 48 133 85 +241 2 2 0 1 42 85 136 +242 2 2 0 1 34 113 35 +243 2 2 0 1 24 118 25 +244 2 2 0 1 36 120 37 +245 2 2 0 1 24 90 118 +246 2 2 0 1 31 122 32 +247 2 2 0 1 46 88 139 +248 2 2 0 1 67 131 116 +249 2 2 0 1 14 135 15 +250 2 2 0 1 11 145 12 +251 2 2 0 1 71 126 125 +252 2 2 0 1 60 125 126 +253 2 2 0 1 58 116 131 +254 2 2 0 1 3 141 4 +255 2 2 0 1 56 119 124 +256 2 2 0 1 66 124 119 +257 2 2 0 1 67 116 100 +258 2 2 0 1 52 117 99 +259 2 2 0 1 47 100 116 +260 2 2 0 1 65 99 117 +261 2 2 0 1 45 107 137 +262 2 2 0 1 62 137 107 +263 2 2 0 1 67 123 131 +264 2 2 0 1 42 131 123 +265 2 2 0 1 68 132 129 +266 2 2 0 1 40 129 132 +267 2 2 0 1 46 134 111 +268 2 2 0 1 61 111 134 +269 2 2 0 1 9 128 101 +270 2 2 0 1 57 98 136 +271 2 2 0 1 42 136 98 +272 2 2 0 1 12 145 105 +273 2 2 0 1 45 140 107 +274 2 2 0 1 81 107 140 +275 2 2 0 1 67 127 123 +276 2 2 0 1 77 110 134 +277 2 2 0 1 61 134 110 +278 2 2 0 1 64 105 145 +279 2 2 0 1 4 141 110 +280 2 2 0 1 61 110 141 +281 2 2 0 1 79 137 115 +282 2 2 0 1 62 115 137 +283 2 2 0 1 59 123 127 +284 2 2 0 1 45 124 140 +285 2 2 0 1 66 140 124 +286 2 2 0 1 64 130 142 +287 2 2 0 1 75 142 130 +288 2 2 0 1 57 136 133 +289 2 2 0 1 85 133 136 +290 2 2 0 1 64 145 130 +291 2 2 0 1 11 130 145 +$EndElements -- GitLab From 058b2235ce67ee5e06c9164d3810c05f59daa053 Mon Sep 17 00:00:00 2001 From: userjjb Date: Mon, 20 Feb 2017 12:53:08 -0600 Subject: [PATCH 4/9] Updated mesh_interaction test to work, start of constant one test, formatting, and changes to mesh-target intersection --- boxtree/mesh_interaction.py | 34 ++-- ...est_mesh_and_target_area_intersection.pckl | Bin 0 -> 60901 bytes test/test_mesh_interaction.py | 145 ++++++++++++++---- 3 files changed, 128 insertions(+), 51 deletions(-) create mode 100644 test/test_mesh_and_target_area_intersection.pckl diff --git a/boxtree/mesh_interaction.py b/boxtree/mesh_interaction.py index 2f84e7a..7467cec 100644 --- a/boxtree/mesh_interaction.py +++ b/boxtree/mesh_interaction.py @@ -1,36 +1,36 @@ import numpy as np + def mesh_and_target_area_intersection(mesh, area_type='box', k=1): #potentially could produce multiple area types if needed later for i in range(len(mesh.groups)): #for now, just lump all mesh groups together - nodes = np.r_['1',mesh.groups[i].nodes] - if area_type=='box': + nodes = np.r_['1', mesh.groups[i].nodes] + if area_type == 'box': #k param: how many local mesh widths to extend tgt box out in each dir - lb = np.amin(nodes[0,:,:],axis=1) - rb = np.amax(nodes[0,:,:],axis=1) - tb = np.amax(nodes[1,:,:],axis=1) - bb = np.amin(nodes[1,:,:],axis=1) + #TODO: convert to dim independent, looping over each dim + #TODO: pull out area generation, separate from intersection detection + lb = np.amin(nodes[0, :, :], axis=1) + rb = np.amax(nodes[0, :, :], axis=1) + tb = np.amax(nodes[1, :, :], axis=1) + bb = np.amin(nodes[1, :, :], axis=1) hx = rb-lb hy = tb-bb tgt_lb = lb-k*hx tgt_rb = rb+k*hx tgt_tb = tb+k*hy tgt_bb = bb-k*hy - + na = np.newaxis #row number=elem number - intersecting = np.logical_and( - np.logical_or( - np.logical_and(tgt_lb[:,na]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 literal 0 HcmV?d00001 diff --git a/test/test_mesh_interaction.py b/test/test_mesh_interaction.py index ddb2e6d..738c440 100644 --- a/test/test_mesh_interaction.py +++ b/test/test_mesh_interaction.py @@ -1,47 +1,124 @@ -import numpy as np +import numpy as np # noqa used in commented code import pyopencl as cl -order = 3 +from pyopencl.tools import ( # noqa + pytest_generate_tests_for_pyopencl as pytest_generate_tests) -cl_ctx = cl.create_some_context() -queue = cl.CommandQueue(cl_ctx) -from meshmode.mesh.io import read_gmsh -mesh = read_gmsh("blob-2d.msh",force_ambient_dim=2) +def test_mesh_and_target_area_intersection(): + from meshmode.mesh.io import read_gmsh + mesh = read_gmsh("blob-2d.msh", force_ambient_dim=2) -from meshmode.discretization import Discretization -from meshmode.discretization.poly_element import InterpolatoryQuadratureSimplexGroupFactory -discr = Discretization(cl_ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(order)) + from boxtree.mesh_interaction import mesh_and_target_area_intersection + intersection, intersection_starts = mesh_and_target_area_intersection( + mesh, area_type='box', k=1) -#Useful vis for debuging -#from meshmode.mesh.visualization import draw_2d_mesh -#draw_2d_mesh(mesh, set_bounding_box=True, draw_vertex_numbers=False, draw_element_numbers=True) -#import matplotlib.pyplot as pt -#pt.show() -#n=discr.nodes().get(queue) -#plt.plot(n[0,],n[1,],'o') + import pickle + f = open('test_mesh_and_target_area_intersection.pckl', 'rb') + test_intersection, test_intersection_starts = pickle.load(f) + f.close() -from boxtree.mesh_interaction import mesh_and_target_area_intersection -intersection, intersection_starts = mesh_and_target_area_intersection(mesh,area_type='box', k=1) + assert(all(test_intersection == intersection)) + assert(all(test_intersection_starts == intersection_starts)) -from boxtree import TreeBuilder -tb = TreeBuilder(cl_ctx) -#from pytools.obj_array import make_obj_array -#particles = make_obj_array([ -# discr.nodes()[i,].get(queue) -# for i in range(2)]) +def test_constant_one_fmm(ctx_getter): + discr_order = 3 -#tree, _ = tb(queue, particles, max_particles_in_box=10) + ctx = ctx_getter() + queue = cl.CommandQueue(ctx) -#dims = 2 -#nparticles = 10**3 + from meshmode.mesh.io import read_gmsh + mesh = read_gmsh("blob-2d.msh", force_ambient_dim=2) + + from boxtree.mesh_interaction import mesh_and_target_area_intersection + intersection, intersection_starts = mesh_and_target_area_intersection( + mesh, area_type='box', k=1) + + from meshmode.discretization import Discretization + from meshmode.discretization.poly_element import ( + InterpolatoryQuadratureSimplexGroupFactory) + discr = Discretization( + ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(discr_order)) + + #Useful vis for debuging + #from meshmode.mesh.visualization import draw_2d_mesh + #draw_2d_mesh(mesh, set_bounding_box=True, draw_vertex_numbers=False, + # draw_element_numbers=True) + #import matplotlib.pyplot as pt + #pt.show() + #n=discr.nodes().get(queue) + #plt.plot(n[0,],n[1,],'o') + + from boxtree import TreeBuilder + #'tb' and 'particles' will be eventually used, noqa'ed until rest works + tb = TreeBuilder(ctx) # noqa + + from pytools.obj_array import make_obj_array + particles = make_obj_array([ # noqa + discr.nodes()[i, ].with_queue(queue).copy() + for i in range(2)]) + + tree, _ = tb(queue, particles, max_particles_in_box=10) + + #^^This^^ throws " AttributeError: 'numpy.ndarray' object has no attribute + #'base_data' " but yet the 'particles' object created looks like the same + #thing as the example snippet \/below, which does work + +# dims = 2 +# nparticles = discr.nodes().shape[1] +# +# from pyopencl.clrandom import RanluxGenerator +# rng = RanluxGenerator(queue, seed=15) +# from pytools.obj_array import make_obj_array +# particles = make_obj_array([ +# rng.normal(queue, nparticles, dtype=np.float64) +# for i in range(dims)]) +# +# tree, _ = tb(queue, particles, max_particles_in_box=10) +# +# from boxtree.traversal import FMMTraversalBuilder +# tbuild = FMMTraversalBuilder(ctx) +# trav, _ = tbuild(queue, tree, debug=True) +# if trav.sep_close_smaller_starts is not None: +# trav = trav.merge_close_lists(queue) # -#from pyopencl.clrandom import RanluxGenerator -#rng = RanluxGenerator(queue, seed=15) -#from pytools.obj_array import make_obj_array -#particles = make_obj_array([ -# rng.normal(queue, nparticles, dtype=np.float64) -# for i in range(dims)]) +# weights = discr.quad_weights(queue).get(queue) +# weights_sum = np.sum(weights) # -#tree, _ = tb(queue, particles, max_particles_in_box=10) \ No newline at end of file +# host_trav = trav.get(queue=queue) +# host_tree = host_trav.tree +# +# from test_fmm import ConstantOneExpansionWrangler +# #Modify Wrangler class to eliminate eval_direct? +# wrangler = ConstantOneExpansionWrangler(host_tree) +# +# from boxtree.fmm import drive_fmm +# pot = drive_fmm(host_trav, wrangler, weights) +# +# from boxtree.mesh_interaction import mesh_and_target_area_intersection +# intersection, intersection_starts = mesh_and_target_area_intersection( +# mesh, area_type='box', k=1) +# +# pot_qbx = SUM_WEIGHTS_ASSOCIATED_WITH_ELEMENTS_IN_TARGET_INTERSECTION +# +# pot = pot + pot_qbx - DOUBLY_INCLUDED_STUFF +# +# rel_err = la.norm((pot - weights_sum) / nsources) +# good = rel_err < 1e-8 +# +# assert good + +# You can test individual routines by typing +# $ python test_fmm.py 'test_routine(cl.create_some_context)' + + +if __name__ == "__main__": + import sys + if len(sys.argv) > 1: + exec(sys.argv[1]) + else: + from py.test.cmdline import main + main([__file__]) + +# vim: fdm=marker -- GitLab From c5ed917601c9f66bc22aee79871a9b7459b1111c Mon Sep 17 00:00:00 2001 From: "userjjb@gmail.com" Date: Mon, 20 Mar 2017 02:54:44 -0500 Subject: [PATCH 5/9] Added necessary mesh-interaction functions for constant_one test(should also work for non-trivial quadrature/kernels), got constant_one test working/passed. Updated .pckl test file for modified test. --- boxtree/mesh_interaction.py | 97 +++++++--- ...est_mesh_and_target_area_intersection.pckl | Bin 60901 -> 706254 bytes test/test_mesh_interaction.py | 180 +++++++++++------- 3 files changed, 186 insertions(+), 91 deletions(-) diff --git a/boxtree/mesh_interaction.py b/boxtree/mesh_interaction.py index 7467cec..cd0f357 100644 --- a/boxtree/mesh_interaction.py +++ b/boxtree/mesh_interaction.py @@ -1,36 +1,89 @@ import numpy as np -def mesh_and_target_area_intersection(mesh, area_type='box', k=1): - #potentially could produce multiple area types if needed later +def mesh_and_target_area_intersection(mesh, tgt_areas, area_type='box'): + #potentially could accept multiple area types, if needed later for i in range(len(mesh.groups)): #for now, just lump all mesh groups together - nodes = np.r_['1', mesh.groups[i].nodes] + elem = np.r_['1', mesh.groups[i].nodes] if area_type == 'box': - #k param: how many local mesh widths to extend tgt box out in each dir - #TODO: convert to dim independent, looping over each dim - #TODO: pull out area generation, separate from intersection detection - lb = np.amin(nodes[0, :, :], axis=1) - rb = np.amax(nodes[0, :, :], axis=1) - tb = np.amax(nodes[1, :, :], axis=1) - bb = np.amin(nodes[1, :, :], axis=1) - hx = rb-lb - hy = tb-bb - tgt_lb = lb-k*hx - tgt_rb = rb+k*hx - tgt_tb = tb+k*hy - tgt_bb = bb-k*hy + #tgt_area consists of two arrays, the upper and lower bounds for each dim + tgt_lb = tgt_areas[0] + tgt_ub = tgt_areas[1] na = np.newaxis - #row number=elem number - intersecting = ((((tgt_lb[:, na] < lb) & (lb < tgt_rb[:, na])) | - ((tgt_lb[:, na] < rb) & (rb < tgt_rb[:, na]))) & - (((tgt_bb[:, na] < tb) & (tb < tgt_tb[:, na])) | - ((tgt_bb[:, na] < bb) & (bb < tgt_tb[:, na])))) + intersecting = True + for i in range(mesh.dim): + lb = np.amin(elem[i, :, :], axis=1) + ub = np.amax(elem[i, :, :], axis=1) + intersecting = (intersecting & + (((tgt_lb[:, i, na] < lb) & (lb < tgt_ub[:, i, na])) | + ((tgt_lb[:, i, na] < ub) & (ub < tgt_ub[:, i, na])))) + intersecting = np.argwhere(intersecting) intersection = intersecting[:, 1] - intersection_starts = np.argwhere(np.diff(intersecting[:, 0]))+1 + intersection_starts = np.argwhere(np.diff(intersecting[:, 0]))[:, 0]+1 + intersection_starts = np.r_[0, intersection_starts, intersection.size] #returns mesh element numbers, associated with target elem number return intersection, intersection_starts else: raise RuntimeError('Not a valid area search type') + + +def target_and_neighbor_sources(tree, trav, queue): + #ordered like target_boxes + bss = tree.box_source_starts.get(queue) + bscc = tree.box_source_counts_cumul.get(queue) + nsbs = trav.neighbor_source_boxes_starts.get(queue) + nsbl = trav.neighbor_source_boxes_lists.get(queue) + + tgt_L1_srcs = np.array([], dtype=np.int) + tgt_L1_srcs_starts = np.array([0], dtype=np.int) + for box in range(trav.target_boxes.size): + for neighbor in range(nsbs[box], nsbs[box+1]): + L1 = nsbl[neighbor] + tgt_L1_srcs = np.append(tgt_L1_srcs, bss[L1] + np.arange(bscc[L1])) + tgt_L1_srcs_starts = np.append(tgt_L1_srcs_starts, tgt_L1_srcs.size) + return tgt_L1_srcs, tgt_L1_srcs_starts + + +def target_area_fmm_neighbors_difference(tree, trav, queue, nunit_nodes, + intersection, intersection_starts): + target_boxes = trav.target_boxes.get(queue) + bsst = tree.box_source_starts.get(queue)[target_boxes] + bscct = tree.box_source_counts_cumul.get(queue)[target_boxes] + user_source_ids = tree.user_source_ids.get(queue) + + tgt_L1_srcs, tgt_L1_srcs_starts = target_and_neighbor_sources(tree, trav, queue) + + #Preprocessing step to determine the space needed for each tgt's 'area_L1_diff' + L1_box_size = np.diff(tgt_L1_srcs_starts) + L1_size = np.zeros(tree.nsources) + area_size = nunit_nodes*np.diff(intersection_starts) + for box in range(trav.target_boxes.size): + L1_size[bsst[box] + np.arange(bscct[box])] = L1_box_size[box] + area_L1_diff_starts = np.append(0, np.cumsum(area_size - L1_size).astype(int)) + + area_L1_diff = np.zeros(area_L1_diff_starts[-1], dtype=np.int) + elem_by_node_num = np.arange(nunit_nodes) + for box in range(trav.target_boxes.size): + L1_set = tgt_L1_srcs[tgt_L1_srcs_starts[box]:tgt_L1_srcs_starts[box+1]] + L1_set = user_source_ids[L1_set] # convert to user source ordering + for tgt in bsst[box] + np.arange(bscct[box]): + #'intersection' gives us the *element nums* that are in the set + #associated with the 'tgt' point (in tree ordering), but we need the + #source nums of sources contained in each of the elements. This is easy + #to get in user ordering, since the user source order ascends in the same + #order as element ordering. + area_set = np.ravel(elem_by_node_num + nunit_nodes * intersection[ + intersection_starts[tgt]:intersection_starts[tgt+1], np.newaxis]) + + area_L1_diff[area_L1_diff_starts[tgt]:area_L1_diff_starts[tgt+1]] =\ + np.setdiff1d(area_set, L1_set, assume_unique=True) + subset = np.setdiff1d(L1_set, area_set, assume_unique=True).size + assert subset == 0, 'Area too small for L1, for tgt num: ' + str(tgt) +\ + ', box: ' + str(box) + '. ' + str(subset) + '/' + str(area_set.size)\ + + ' points not in area' + + #returns, in tree target ordering, the user source ids in the diff for the tgt + return area_L1_diff, area_L1_diff_starts diff --git a/test/test_mesh_and_target_area_intersection.pckl b/test/test_mesh_and_target_area_intersection.pckl index 38f5cc0fd591f357fa10e1bc9c132a3c08fd2c5b..dd721de794c000607bd93d2d67cce49894a7797f 100644 GIT binary patch literal 706254 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 delta 6951 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 LXUSRf?+E-GMnBM7 diff --git a/test/test_mesh_interaction.py b/test/test_mesh_interaction.py index 738c440..14398e7 100644 --- a/test/test_mesh_interaction.py +++ b/test/test_mesh_interaction.py @@ -1,17 +1,72 @@ -import numpy as np # noqa used in commented code +import numpy as np +import numpy.linalg as la import pyopencl as cl from pyopencl.tools import ( # noqa pytest_generate_tests_for_pyopencl as pytest_generate_tests) +from test_fmm import ConstantOneExpansionWrangler + + +#Modify existing ConsantOneExpansionWrangler and zero out eval_direct, to be +#replaced by a LocalQuadrature-like local eval +class LocalQuadratureConstantOneExpansionWrangler(ConstantOneExpansionWrangler): + def eval_direct(self, target_boxes, neighbor_sources_starts, + neighbor_sources_lists, src_weights): + pot = self.potential_zeros() + + return pot + + +#Define a test area that could be used: a region over which local quadrature is +#necessary. This example has the quad area proportional to the local mesh size, a +#decent choice for locally refined meshes to attempt to bound the number of mesh +#elements intersecting the quad area (likely need more QBX expansion terms to work) +def local_quadrature_area(mesh, discr, user_source_ids, queue, k): + for i in range(len(mesh.groups)): + #for now, just lump all mesh groups together + elem = np.r_['1', mesh.groups[i].nodes] + + nunit_nodes = discr.groups[0].nunit_nodes + nodes = discr.nodes().get(queue) + tgt_lb = np.zeros((discr.nnodes, mesh.dim)) + tgt_ub = tgt_lb.copy() + for i in range(mesh.dim): + lb = np.amin(elem[i, :, :], axis=1) + ub = np.amax(elem[i, :, :], axis=1) + h = np.repeat(ub-lb, nunit_nodes) + + tgt_lb[:, i] = nodes[i, :]-k*h + tgt_ub[:, i] = nodes[i, :]+k*h + + #reorder from user to tree ordering, what mesh_interaction expects + #is user_source_ids correct or is inverse of sorted_target_ids better? + tgt_lb = tgt_lb[user_source_ids, :] + tgt_ub = tgt_ub[user_source_ids, :] + + return [tgt_lb, tgt_ub] + + +def test_mesh_and_target_area_intersection(ctx_getter): + discr_order = 3 + + ctx = ctx_getter() + queue = cl.CommandQueue(ctx) -def test_mesh_and_target_area_intersection(): from meshmode.mesh.io import read_gmsh mesh = read_gmsh("blob-2d.msh", force_ambient_dim=2) + from meshmode.discretization import Discretization + from meshmode.discretization.poly_element import ( + InterpolatoryQuadratureSimplexGroupFactory) + discr = Discretization( + ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(discr_order)) + + user_source_ids = np.arange(discr.nnodes) + tgt_areas = local_quadrature_area(mesh, discr, user_source_ids, queue, k=1.7) from boxtree.mesh_interaction import mesh_and_target_area_intersection intersection, intersection_starts = mesh_and_target_area_intersection( - mesh, area_type='box', k=1) + mesh, tgt_areas, area_type='box') import pickle f = open('test_mesh_and_target_area_intersection.pckl', 'rb') @@ -31,88 +86,75 @@ def test_constant_one_fmm(ctx_getter): from meshmode.mesh.io import read_gmsh mesh = read_gmsh("blob-2d.msh", force_ambient_dim=2) - from boxtree.mesh_interaction import mesh_and_target_area_intersection - intersection, intersection_starts = mesh_and_target_area_intersection( - mesh, area_type='box', k=1) - from meshmode.discretization import Discretization from meshmode.discretization.poly_element import ( InterpolatoryQuadratureSimplexGroupFactory) discr = Discretization( ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(discr_order)) - #Useful vis for debuging - #from meshmode.mesh.visualization import draw_2d_mesh - #draw_2d_mesh(mesh, set_bounding_box=True, draw_vertex_numbers=False, - # draw_element_numbers=True) - #import matplotlib.pyplot as pt - #pt.show() - #n=discr.nodes().get(queue) - #plt.plot(n[0,],n[1,],'o') - from boxtree import TreeBuilder - #'tb' and 'particles' will be eventually used, noqa'ed until rest works - tb = TreeBuilder(ctx) # noqa + tb = TreeBuilder(ctx) from pytools.obj_array import make_obj_array - particles = make_obj_array([ # noqa + sources = make_obj_array([ # noqa discr.nodes()[i, ].with_queue(queue).copy() for i in range(2)]) + nsources = len(sources[0]) + nunit_nodes = discr.groups[0].nunit_nodes + + tree, _ = tb(queue, sources, max_particles_in_box=nunit_nodes) + + from boxtree.traversal import FMMTraversalBuilder + tbuild = FMMTraversalBuilder(ctx) + trav, _ = tbuild(queue, tree, debug=True) + if trav.sep_close_smaller_starts is not None: + trav = trav.merge_close_lists(queue) + + weights = discr.quad_weights(queue).get(queue) + weights_sum = np.sum(weights) + + host_trav = trav.get(queue=queue) + host_tree = host_trav.tree + + wrangler = LocalQuadratureConstantOneExpansionWrangler(host_tree) + + from boxtree.fmm import drive_fmm + pot_fmm = drive_fmm(host_trav, wrangler, weights) + + user_source_ids = host_tree.user_source_ids + tgt_areas = local_quadrature_area(mesh, discr, user_source_ids, queue, k=1.7) + from boxtree.mesh_interaction import mesh_and_target_area_intersection + intersection, intersection_starts = mesh_and_target_area_intersection( + mesh, tgt_areas, area_type='box') + + #Normally: perform quadrature over the elements in the intersection + #For this test script we know the quadrature will return 2 for each element + #So the total pot from qbx is just the total intersecting elems for tgt + pot_qbx = 2*np.diff(intersection_starts) + + #pot_qbx replaces what would have been done by eval_direct, but includes + #some stuff already included elsewhere by the fmm, we need to subtract that + from boxtree.mesh_interaction import target_area_fmm_neighbors_difference + area_L1_diff, area_L1_diff_starts =\ + target_area_fmm_neighbors_difference(tree, trav, queue, nunit_nodes, + intersection, intersection_starts) + + pot_diff_fmm_qbx = np.zeros(area_L1_diff_starts.size-1) + for i in range(area_L1_diff_starts.size-1): + remove = area_L1_diff[area_L1_diff_starts[i]:area_L1_diff_starts[i+1]] + pot_diff_fmm_qbx[i] = np.sum(weights[remove]) + + pot = pot_fmm + (pot_qbx - pot_diff_fmm_qbx)[host_tree.sorted_target_ids] + + rel_err = la.norm((pot - weights_sum) / nsources) + good = rel_err < 1e-8 + + assert good - tree, _ = tb(queue, particles, max_particles_in_box=10) - - #^^This^^ throws " AttributeError: 'numpy.ndarray' object has no attribute - #'base_data' " but yet the 'particles' object created looks like the same - #thing as the example snippet \/below, which does work - -# dims = 2 -# nparticles = discr.nodes().shape[1] -# -# from pyopencl.clrandom import RanluxGenerator -# rng = RanluxGenerator(queue, seed=15) -# from pytools.obj_array import make_obj_array -# particles = make_obj_array([ -# rng.normal(queue, nparticles, dtype=np.float64) -# for i in range(dims)]) -# -# tree, _ = tb(queue, particles, max_particles_in_box=10) -# -# from boxtree.traversal import FMMTraversalBuilder -# tbuild = FMMTraversalBuilder(ctx) -# trav, _ = tbuild(queue, tree, debug=True) -# if trav.sep_close_smaller_starts is not None: -# trav = trav.merge_close_lists(queue) -# -# weights = discr.quad_weights(queue).get(queue) -# weights_sum = np.sum(weights) -# -# host_trav = trav.get(queue=queue) -# host_tree = host_trav.tree -# -# from test_fmm import ConstantOneExpansionWrangler -# #Modify Wrangler class to eliminate eval_direct? -# wrangler = ConstantOneExpansionWrangler(host_tree) -# -# from boxtree.fmm import drive_fmm -# pot = drive_fmm(host_trav, wrangler, weights) -# -# from boxtree.mesh_interaction import mesh_and_target_area_intersection -# intersection, intersection_starts = mesh_and_target_area_intersection( -# mesh, area_type='box', k=1) -# -# pot_qbx = SUM_WEIGHTS_ASSOCIATED_WITH_ELEMENTS_IN_TARGET_INTERSECTION -# -# pot = pot + pot_qbx - DOUBLY_INCLUDED_STUFF -# -# rel_err = la.norm((pot - weights_sum) / nsources) -# good = rel_err < 1e-8 -# -# assert good # You can test individual routines by typing # $ python test_fmm.py 'test_routine(cl.create_some_context)' - if __name__ == "__main__": import sys if len(sys.argv) > 1: -- GitLab From 2a7ab5c23c8016cd98487970eb278d169aee3f19 Mon Sep 17 00:00:00 2001 From: "userjjb@gmail.com" Date: Mon, 20 Mar 2017 03:23:27 -0500 Subject: [PATCH 6/9] Added meshmode to requirements.txt, fixed flake8 complaint about uppercase letters in variable name --- boxtree/mesh_interaction.py | 40 +++++++++++++++++------------------ requirements.txt | 1 + test/test_mesh_interaction.py | 8 +++---- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/boxtree/mesh_interaction.py b/boxtree/mesh_interaction.py index cd0f357..b3c443b 100644 --- a/boxtree/mesh_interaction.py +++ b/boxtree/mesh_interaction.py @@ -37,14 +37,14 @@ def target_and_neighbor_sources(tree, trav, queue): nsbs = trav.neighbor_source_boxes_starts.get(queue) nsbl = trav.neighbor_source_boxes_lists.get(queue) - tgt_L1_srcs = np.array([], dtype=np.int) - tgt_L1_srcs_starts = np.array([0], dtype=np.int) + tgt_l1_srcs = np.array([], dtype=np.int) + tgt_l1_srcs_starts = np.array([0], dtype=np.int) for box in range(trav.target_boxes.size): for neighbor in range(nsbs[box], nsbs[box+1]): - L1 = nsbl[neighbor] - tgt_L1_srcs = np.append(tgt_L1_srcs, bss[L1] + np.arange(bscc[L1])) - tgt_L1_srcs_starts = np.append(tgt_L1_srcs_starts, tgt_L1_srcs.size) - return tgt_L1_srcs, tgt_L1_srcs_starts + l1 = nsbl[neighbor] + tgt_l1_srcs = np.append(tgt_l1_srcs, bss[l1] + np.arange(bscc[l1])) + tgt_l1_srcs_starts = np.append(tgt_l1_srcs_starts, tgt_l1_srcs.size) + return tgt_l1_srcs, tgt_l1_srcs_starts def target_area_fmm_neighbors_difference(tree, trav, queue, nunit_nodes, @@ -54,21 +54,21 @@ def target_area_fmm_neighbors_difference(tree, trav, queue, nunit_nodes, bscct = tree.box_source_counts_cumul.get(queue)[target_boxes] user_source_ids = tree.user_source_ids.get(queue) - tgt_L1_srcs, tgt_L1_srcs_starts = target_and_neighbor_sources(tree, trav, queue) + tgt_l1_srcs, tgt_l1_srcs_starts = target_and_neighbor_sources(tree, trav, queue) - #Preprocessing step to determine the space needed for each tgt's 'area_L1_diff' - L1_box_size = np.diff(tgt_L1_srcs_starts) - L1_size = np.zeros(tree.nsources) + #Preprocessing step to determine the space needed for each tgt's 'area_l1_diff' + l1_box_size = np.diff(tgt_l1_srcs_starts) + l1_size = np.zeros(tree.nsources) area_size = nunit_nodes*np.diff(intersection_starts) for box in range(trav.target_boxes.size): - L1_size[bsst[box] + np.arange(bscct[box])] = L1_box_size[box] - area_L1_diff_starts = np.append(0, np.cumsum(area_size - L1_size).astype(int)) + l1_size[bsst[box] + np.arange(bscct[box])] = l1_box_size[box] + area_l1_diff_starts = np.append(0, np.cumsum(area_size - l1_size).astype(int)) - area_L1_diff = np.zeros(area_L1_diff_starts[-1], dtype=np.int) + area_l1_diff = np.zeros(area_l1_diff_starts[-1], dtype=np.int) elem_by_node_num = np.arange(nunit_nodes) for box in range(trav.target_boxes.size): - L1_set = tgt_L1_srcs[tgt_L1_srcs_starts[box]:tgt_L1_srcs_starts[box+1]] - L1_set = user_source_ids[L1_set] # convert to user source ordering + l1_set = tgt_l1_srcs[tgt_l1_srcs_starts[box]:tgt_l1_srcs_starts[box+1]] + l1_set = user_source_ids[l1_set] # convert to user source ordering for tgt in bsst[box] + np.arange(bscct[box]): #'intersection' gives us the *element nums* that are in the set #associated with the 'tgt' point (in tree ordering), but we need the @@ -78,12 +78,12 @@ def target_area_fmm_neighbors_difference(tree, trav, queue, nunit_nodes, area_set = np.ravel(elem_by_node_num + nunit_nodes * intersection[ intersection_starts[tgt]:intersection_starts[tgt+1], np.newaxis]) - area_L1_diff[area_L1_diff_starts[tgt]:area_L1_diff_starts[tgt+1]] =\ - np.setdiff1d(area_set, L1_set, assume_unique=True) - subset = np.setdiff1d(L1_set, area_set, assume_unique=True).size - assert subset == 0, 'Area too small for L1, for tgt num: ' + str(tgt) +\ + area_l1_diff[area_l1_diff_starts[tgt]:area_l1_diff_starts[tgt+1]] =\ + np.setdiff1d(area_set, l1_set, assume_unique=True) + subset = np.setdiff1d(l1_set, area_set, assume_unique=True).size + assert subset == 0, 'Area too small for l1, for tgt num: ' + str(tgt) +\ ', box: ' + str(box) + '. ' + str(subset) + '/' + str(area_set.size)\ + ' points not in area' #returns, in tree target ordering, the user source ids in the diff for the tgt - return area_L1_diff, area_L1_diff_starts + return area_l1_diff, area_l1_diff_starts diff --git a/requirements.txt b/requirements.txt index e36a43a..10d0d5e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,4 @@ git+git://github.com/pyopencl/pyopencl git+git://github.com/inducer/islpy git+git://github.com/inducer/loopy git+git://github.com/inducer/pyfmmlib +git+https://github.com/inducer/meshmode.git diff --git a/test/test_mesh_interaction.py b/test/test_mesh_interaction.py index 14398e7..0b5eaa1 100644 --- a/test/test_mesh_interaction.py +++ b/test/test_mesh_interaction.py @@ -135,13 +135,13 @@ def test_constant_one_fmm(ctx_getter): #pot_qbx replaces what would have been done by eval_direct, but includes #some stuff already included elsewhere by the fmm, we need to subtract that from boxtree.mesh_interaction import target_area_fmm_neighbors_difference - area_L1_diff, area_L1_diff_starts =\ + area_l1_diff, area_l1_diff_starts =\ target_area_fmm_neighbors_difference(tree, trav, queue, nunit_nodes, intersection, intersection_starts) - pot_diff_fmm_qbx = np.zeros(area_L1_diff_starts.size-1) - for i in range(area_L1_diff_starts.size-1): - remove = area_L1_diff[area_L1_diff_starts[i]:area_L1_diff_starts[i+1]] + pot_diff_fmm_qbx = np.zeros(area_l1_diff_starts.size-1) + for i in range(area_l1_diff_starts.size-1): + remove = area_l1_diff[area_l1_diff_starts[i]:area_l1_diff_starts[i+1]] pot_diff_fmm_qbx[i] = np.sum(weights[remove]) pot = pot_fmm + (pot_qbx - pot_diff_fmm_qbx)[host_tree.sorted_target_ids] -- GitLab From 57b509905c6305899aacc45414e653c0e347a506 Mon Sep 17 00:00:00 2001 From: "userjjb@gmail.com" Date: Mon, 20 Mar 2017 21:42:46 -0500 Subject: [PATCH 7/9] Changed test .pckl file to older Python2 compatible pickle protocol --- ...est_mesh_and_target_area_intersection.pckl | Bin 706254 -> 750046 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/test/test_mesh_and_target_area_intersection.pckl b/test/test_mesh_and_target_area_intersection.pckl index dd721de794c000607bd93d2d67cce49894a7797f..97d62cd80bbd37f0e194eb35da0fbc0b66e9afe0 100644 GIT binary patch literal 750046 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 H_v!xtj)~Z9 literal 706254 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 -- GitLab From 5b659dea3106d403d7faed897f6fc7e7fbaf697e Mon Sep 17 00:00:00 2001 From: "userjjb@gmail.com" Date: Tue, 2 May 2017 02:35:01 -0500 Subject: [PATCH 8/9] Created test for sumpy constant one kernel. Created 'local quad' fmm driver, expects several new user routines from wrangler for handling generic local quadrature. Both sumpy and test-fmm constant one tests have been updated to use the local quad fmm driver. Minor change to mesh_intersection func to move away from one 'mega func' for all area intersection types. --- boxtree/fmm.py | 138 ++++++++++++++++++++ boxtree/mesh_interaction.py | 41 +++--- test/test_mesh_interaction.py | 237 +++++++++++++++++++++++++++------- 3 files changed, 347 insertions(+), 69 deletions(-) diff --git a/boxtree/fmm.py b/boxtree/fmm.py index 2d18a7b..6309271 100644 --- a/boxtree/fmm.py +++ b/boxtree/fmm.py @@ -185,6 +185,144 @@ def drive_fmm(traversal, expansion_wrangler, src_weights): return result +def drive_fmm_local_quad(intersection, intersection_starts, area_l1_diff, + area_l1_diff_starts, tree, traversal, expansion_wrangler, + src_weights): + """Top-level driver routine for a fast multipole calculation. + + In part, this is intended as a template for custom FMMs, in the sense that + you may copy and paste its + `source code `_ + as a starting point. + + Nonetheless, many common applications (such as point-to-point FMMs) can be + covered by supplying the right *expansion_wrangler* to this routine. + + :arg traversal: A :class:`boxtree.traversal.FMMTraversalInfo` instance. + :arg expansion_wrangler: An object exhibiting the + :class:`ExpansionWranglerInterface`. + :arg src_weights: Source 'density/weights/charges'. + Passed unmodified to *expansion_wrangler*. + + Returns the potentials computed by *expansion_wrangler*. + """ + wrangler = expansion_wrangler + + # Interface guidelines: Attributes of the tree are assumed to be known + # to the expansion wrangler and should not be passed. + + logger.info("start fmm") + + logger.debug("reorder source weights") + + src_weights_user = src_weights.copy() + src_weights = wrangler.reorder_sources(src_weights) + + # {{{ "Step 2.1:" Construct local multipoles + + logger.debug("construct local multipoles") + mpole_exps = wrangler.form_multipoles( + traversal.level_start_source_box_nrs, + traversal.source_boxes, + src_weights) + + # }}} + + # {{{ "Step 2.2:" Propagate multipoles upward + + logger.debug("propagate multipoles upward") + wrangler.coarsen_multipoles( + traversal.level_start_source_parent_box_nrs, + traversal.source_parent_boxes, + mpole_exps) + + # mpole_exps is called Phi in [1] + + # }}} + + # {{{ "Stage 3MOD:" Direct evaluation from neighbor source boxes ("list 1") + + logger.debug("Perform local quadrature") + + pot_local = wrangler.local_quadrature(intersection, intersection_starts) + pot_diff = wrangler.pot_diff_fmm_local(area_l1_diff, area_l1_diff_starts, + src_weights_user) + + # }}} + + # {{{ "Stage 4:" translate separated siblings' ("list 2") mpoles to local + + logger.debug("translate separated siblings' ('list 2') mpoles to local") + local_exps = wrangler.multipole_to_local( + traversal.level_start_target_or_target_parent_box_nrs, + traversal.target_or_target_parent_boxes, + traversal.sep_siblings_starts, + traversal.sep_siblings_lists, + mpole_exps) + + # local_exps represents both Gamma and Delta in [1] + + # }}} + + # {{{ "Stage 5:" evaluate sep. smaller mpoles ("list 3") at particles + + logger.debug("evaluate sep. smaller mpoles at particles ('list 3 far')") + + # (the point of aiming this stage at particles is specifically to keep its + # contribution *out* of the downward-propagating local expansions) + + potentials = wrangler.eval_multipoles( + traversal.level_start_target_box_nrs, + traversal.target_boxes, + traversal.sep_smaller_by_level, + mpole_exps) + + # these potentials are called beta in [1] + # }}} + + # {{{ "Stage 6:" form locals for separated bigger mpoles ("list 4") + + logger.debug("form locals for separated bigger mpoles ('list 4 far')") + + local_exps = local_exps + wrangler.form_locals( + traversal.level_start_target_or_target_parent_box_nrs, + traversal.target_or_target_parent_boxes, + traversal.sep_bigger_starts, + traversal.sep_bigger_lists, + src_weights) + + # }}} + + # {{{ "Stage 7:" propagate local_exps downward + + logger.debug("propagate local_exps downward") + + wrangler.refine_locals( + traversal.level_start_target_or_target_parent_box_nrs, + traversal.target_or_target_parent_boxes, + local_exps) + + # }}} + + # {{{ "Stage 8:" evaluate locals + + logger.debug("evaluate locals") + + potentials = potentials + wrangler.eval_locals( + traversal.level_start_target_box_nrs, + traversal.target_boxes, + local_exps) + + # }}} + + logger.debug("reorder potentials") + result = wrangler.reorder_potentials(potentials) + result = result + (pot_local - pot_diff) + + logger.info("fmm complete") + return result + + # {{{ expansion wrangler interface class ExpansionWranglerInterface: diff --git a/boxtree/mesh_interaction.py b/boxtree/mesh_interaction.py index b3c443b..1ac0628 100644 --- a/boxtree/mesh_interaction.py +++ b/boxtree/mesh_interaction.py @@ -1,33 +1,30 @@ import numpy as np -def mesh_and_target_area_intersection(mesh, tgt_areas, area_type='box'): - #potentially could accept multiple area types, if needed later +def mesh_and_target_area_intersection_box(mesh, tgt_areas): + # Returns intersection of box tgt_area and mesh for i in range(len(mesh.groups)): #for now, just lump all mesh groups together elem = np.r_['1', mesh.groups[i].nodes] - if area_type == 'box': - #tgt_area consists of two arrays, the upper and lower bounds for each dim - tgt_lb = tgt_areas[0] - tgt_ub = tgt_areas[1] + #tgt_area consists of two arrays, the upper and lower bounds for each dim + tgt_lb = tgt_areas[0] + tgt_ub = tgt_areas[1] - na = np.newaxis - intersecting = True - for i in range(mesh.dim): - lb = np.amin(elem[i, :, :], axis=1) - ub = np.amax(elem[i, :, :], axis=1) - intersecting = (intersecting & - (((tgt_lb[:, i, na] < lb) & (lb < tgt_ub[:, i, na])) | - ((tgt_lb[:, i, na] < ub) & (ub < tgt_ub[:, i, na])))) + na = np.newaxis + intersecting = True + for i in range(mesh.dim): + lb = np.amin(elem[i, :, :], axis=1) + ub = np.amax(elem[i, :, :], axis=1) + intersecting = (intersecting & + (((tgt_lb[:, i, na] < lb) & (lb < tgt_ub[:, i, na])) | + ((tgt_lb[:, i, na] < ub) & (ub < tgt_ub[:, i, na])))) - intersecting = np.argwhere(intersecting) - intersection = intersecting[:, 1] - intersection_starts = np.argwhere(np.diff(intersecting[:, 0]))[:, 0]+1 - intersection_starts = np.r_[0, intersection_starts, intersection.size] - #returns mesh element numbers, associated with target elem number - return intersection, intersection_starts - else: - raise RuntimeError('Not a valid area search type') + intersecting = np.argwhere(intersecting) + intersection = intersecting[:, 1] + intersection_starts = np.argwhere(np.diff(intersecting[:, 0]))[:, 0]+1 + intersection_starts = np.r_[0, intersection_starts, intersection.size] + #returns mesh element numbers, associated with target elem number + return intersection, intersection_starts def target_and_neighbor_sources(tree, trav, queue): diff --git a/test/test_mesh_interaction.py b/test/test_mesh_interaction.py index 0b5eaa1..7a056a3 100644 --- a/test/test_mesh_interaction.py +++ b/test/test_mesh_interaction.py @@ -1,34 +1,98 @@ import numpy as np import numpy.linalg as la import pyopencl as cl - from pyopencl.tools import ( # noqa pytest_generate_tests_for_pyopencl as pytest_generate_tests) +from sumpy.kernel import one_kernel_2d +from sumpy.expansion.multipole import VolumeTaylorMultipoleExpansion +from sumpy.expansion.local import VolumeTaylorLocalExpansion -from test_fmm import ConstantOneExpansionWrangler +import pytest +import logging +logger = logging.getLogger(__name__) -#Modify existing ConsantOneExpansionWrangler and zero out eval_direct, to be -#replaced by a LocalQuadrature-like local eval -class LocalQuadratureConstantOneExpansionWrangler(ConstantOneExpansionWrangler): - def eval_direct(self, target_boxes, neighbor_sources_starts, - neighbor_sources_lists, src_weights): - pot = self.potential_zeros() +try: + import faulthandler +except ImportError: + pass +else: + faulthandler.enable() - return pot + +# See comment on SumpyExpansionWranglerLocalQuad below +from test_fmm import ConstantOneExpansionWrangler -#Define a test area that could be used: a region over which local quadrature is -#necessary. This example has the quad area proportional to the local mesh size, a -#decent choice for locally refined meshes to attempt to bound the number of mesh -#elements intersecting the quad area (likely need more QBX expansion terms to work) -def local_quadrature_area(mesh, discr, user_source_ids, queue, k): +class LocalQuadratureConstantOneExpansionWrangler(ConstantOneExpansionWrangler): + def __init__(self, tree, queue): + self.tree = tree + self.queue = queue + + def local_quadrature(self, intersection, intersection_starts): + return 2*np.diff(intersection_starts)[self.tree.sorted_target_ids] + + def pot_diff_fmm_local(self, area_l1_diff, area_l1_diff_starts, weights): + result = np.zeros(area_l1_diff_starts.size-1) + for i in range(area_l1_diff_starts.size-1): + remove = area_l1_diff[area_l1_diff_starts[i]:area_l1_diff_starts[i+1]] + result[i] = np.sum(weights[remove]) + return result[self.tree.sorted_target_ids] + + +# Modified code container that redirects to our modified local quad wrangler +from sumpy.fmm import SumpyExpansionWranglerCodeContainer + + +class SumpyExpansionWranglerLQCodeContainer(SumpyExpansionWranglerCodeContainer): + def get_wrangler(self, queue, tree, dtype, fmm_level_to_order, + source_extra_kwargs={}, + kernel_extra_kwargs=None): + return SumpyExpansionWranglerLocalQuad(self, queue, tree, dtype, + fmm_level_to_order, source_extra_kwargs, kernel_extra_kwargs) + + +# Local quad FMM driver expects two new funcs: one for local quadrature, and one for +# pointwise evaluation of sources in the diff set. Info provided to the FMM driver +# and therefore available to the wrangler are CSR-like lists (for each target point) +# of: 1) elements in the mesh/area intersection and 2) source ids in the diff set +from sumpy.fmm import SumpyExpansionWrangler + + +class SumpyExpansionWranglerLocalQuad(SumpyExpansionWrangler): + def local_quadrature(self, intersection, intersection_starts): + # drive_fmm expects potentials as device object arrays, convert before return + sorted_target_ids = self.tree.sorted_target_ids.get(self.queue) + result = 2*np.diff(intersection_starts)[sorted_target_ids] + result = cl.array.to_device(self.queue, result) + from pytools.obj_array import make_obj_array + result = make_obj_array([result]) + return result + + def pot_diff_fmm_local(self, area_l1_diff, area_l1_diff_starts, weights): + result = np.zeros(area_l1_diff_starts.size-1) + for i in range(area_l1_diff_starts.size-1): + remove = area_l1_diff[area_l1_diff_starts[i]:area_l1_diff_starts[i+1]] + result[i] = np.sum(weights.get(self.queue)[remove]) + # drive_fmm expects potentials as device object arrays, convert before return + sorted_target_ids = self.tree.sorted_target_ids.get(self.queue) + result = cl.array.to_device(self.queue, result[sorted_target_ids]) + from pytools.obj_array import make_obj_array + result = make_obj_array([result]) + return result + + +# Define a test area that could be used: a region over which local quadrature is +# necessary. This example has the quad area proportional to the local mesh size, a +# decent choice for locally refined meshes to attempt to bound the number of mesh +# elements intersecting the quad area (likely need more QBX expansion terms to work) +def local_quadrature_area(mesh, discr, user_source_ids, nodes, k): for i in range(len(mesh.groups)): - #for now, just lump all mesh groups together + # for now, just lump all mesh groups together elem = np.r_['1', mesh.groups[i].nodes] nunit_nodes = discr.groups[0].nunit_nodes - nodes = discr.nodes().get(queue) + # nodes = discr.nodes().get(queue) tgt_lb = np.zeros((discr.nnodes, mesh.dim)) tgt_ub = tgt_lb.copy() for i in range(mesh.dim): @@ -39,8 +103,8 @@ def local_quadrature_area(mesh, discr, user_source_ids, queue, k): tgt_lb[:, i] = nodes[i, :]-k*h tgt_ub[:, i] = nodes[i, :]+k*h - #reorder from user to tree ordering, what mesh_interaction expects - #is user_source_ids correct or is inverse of sorted_target_ids better? + # reorder from user to tree ordering, what mesh_interaction expects + # is user_source_ids correct or is inverse of sorted_target_ids better? tgt_lb = tgt_lb[user_source_ids, :] tgt_ub = tgt_ub[user_source_ids, :] @@ -59,14 +123,15 @@ def test_mesh_and_target_area_intersection(ctx_getter): from meshmode.discretization import Discretization from meshmode.discretization.poly_element import ( InterpolatoryQuadratureSimplexGroupFactory) - discr = Discretization( - ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(discr_order)) + discr = Discretization(ctx, mesh, + InterpolatoryQuadratureSimplexGroupFactory(discr_order)) user_source_ids = np.arange(discr.nnodes) - tgt_areas = local_quadrature_area(mesh, discr, user_source_ids, queue, k=1.7) - from boxtree.mesh_interaction import mesh_and_target_area_intersection - intersection, intersection_starts = mesh_and_target_area_intersection( - mesh, tgt_areas, area_type='box') + dnodes = discr.nodes().get(queue) + tgt_areas = local_quadrature_area(mesh, discr, user_source_ids, dnodes, k=1.7) + from boxtree.mesh_interaction import mesh_and_target_area_intersection_box + intersection, intersection_starts = mesh_and_target_area_intersection_box(mesh, + tgt_areas) import pickle f = open('test_mesh_and_target_area_intersection.pckl', 'rb') @@ -96,7 +161,7 @@ def test_constant_one_fmm(ctx_getter): tb = TreeBuilder(ctx) from pytools.obj_array import make_obj_array - sources = make_obj_array([ # noqa + sources = make_obj_array([ # noqa discr.nodes()[i, ].with_queue(queue).copy() for i in range(2)]) nsources = len(sources[0]) @@ -116,35 +181,24 @@ def test_constant_one_fmm(ctx_getter): host_trav = trav.get(queue=queue) host_tree = host_trav.tree - wrangler = LocalQuadratureConstantOneExpansionWrangler(host_tree) - - from boxtree.fmm import drive_fmm - pot_fmm = drive_fmm(host_trav, wrangler, weights) + wrangler = LocalQuadratureConstantOneExpansionWrangler(host_tree, queue) user_source_ids = host_tree.user_source_ids - tgt_areas = local_quadrature_area(mesh, discr, user_source_ids, queue, k=1.7) - from boxtree.mesh_interaction import mesh_and_target_area_intersection - intersection, intersection_starts = mesh_and_target_area_intersection( - mesh, tgt_areas, area_type='box') - - #Normally: perform quadrature over the elements in the intersection - #For this test script we know the quadrature will return 2 for each element - #So the total pot from qbx is just the total intersecting elems for tgt - pot_qbx = 2*np.diff(intersection_starts) - - #pot_qbx replaces what would have been done by eval_direct, but includes - #some stuff already included elsewhere by the fmm, we need to subtract that + dnodes = discr.nodes().get(queue) + tgt_areas = local_quadrature_area(mesh, discr, user_source_ids, dnodes, k=1.7) + from boxtree.mesh_interaction import mesh_and_target_area_intersection_box + intersection, intersection_starts = mesh_and_target_area_intersection_box( + mesh, tgt_areas) + from boxtree.mesh_interaction import target_area_fmm_neighbors_difference area_l1_diff, area_l1_diff_starts =\ target_area_fmm_neighbors_difference(tree, trav, queue, nunit_nodes, intersection, intersection_starts) - pot_diff_fmm_qbx = np.zeros(area_l1_diff_starts.size-1) - for i in range(area_l1_diff_starts.size-1): - remove = area_l1_diff[area_l1_diff_starts[i]:area_l1_diff_starts[i+1]] - pot_diff_fmm_qbx[i] = np.sum(weights[remove]) - - pot = pot_fmm + (pot_qbx - pot_diff_fmm_qbx)[host_tree.sorted_target_ids] + from boxtree.fmm import drive_fmm_local_quad + pot = drive_fmm_local_quad(intersection, intersection_starts, area_l1_diff, + area_l1_diff_starts, tree, host_trav, wrangler, + weights) rel_err = la.norm((pot - weights_sum) / nsources) good = rel_err < 1e-8 @@ -152,6 +206,95 @@ def test_constant_one_fmm(ctx_getter): assert good +@pytest.mark.parametrize("knl, local_expn_class, mpole_expn_class", [ + (one_kernel_2d, VolumeTaylorLocalExpansion, VolumeTaylorMultipoleExpansion), + ]) +def test_sumpy_fmm(ctx_getter, knl, local_expn_class, mpole_expn_class): + logging.basicConfig(level=logging.INFO) + + ctx = ctx_getter() + queue = cl.CommandQueue(ctx) + + from meshmode.mesh.io import read_gmsh + mesh = read_gmsh("blob-2d.msh", force_ambient_dim=2) + + discr_order = 3 + from meshmode.discretization import Discretization + from meshmode.discretization.poly_element import ( + InterpolatoryQuadratureSimplexGroupFactory) + discr = Discretization( + ctx, mesh, InterpolatoryQuadratureSimplexGroupFactory(discr_order)) + + from boxtree import TreeBuilder + tb = TreeBuilder(ctx) + + from pytools.obj_array import make_obj_array + sources = make_obj_array([ # noqa + discr.nodes()[i, ].with_queue(queue).copy() + for i in range(2)]) + nunit_nodes = discr.groups[0].nunit_nodes + + tree, _ = tb(queue, sources, max_particles_in_box=nunit_nodes, debug=True) + + from boxtree.traversal import FMMTraversalBuilder + tbuild = FMMTraversalBuilder(ctx) + trav, _ = tbuild(queue, tree, debug=True) + + weights = discr.quad_weights(queue).get(queue) + weights = cl.array.to_device(queue, weights) + + logger.info("computing direct (reference) result") + + extra_kwargs = {} + dtype = np.float64 + order_values = [1, 2, 3] + + # Mesh-interaction variables that don't change if source locs don't + # We need to only calc these once, each new FMM won't need these updated + tgt_areas = local_quadrature_area(mesh, discr, tree.user_source_ids.get(queue), + discr.nodes().get(queue), k=1.7) + + from boxtree.mesh_interaction import mesh_and_target_area_intersection_box + intersection, intersection_starts = mesh_and_target_area_intersection_box( + mesh, tgt_areas) + + from boxtree.mesh_interaction import target_area_fmm_neighbors_difference + area_l1_diff, area_l1_diff_starts =\ + target_area_fmm_neighbors_difference(tree, trav, queue, nunit_nodes, + intersection, intersection_starts) + + from functools import partial + for order in order_values: + out_kernels = [knl] + + wcc = SumpyExpansionWranglerLQCodeContainer( + ctx, + partial(mpole_expn_class, knl), + partial(local_expn_class, knl), + out_kernels) + wrangler = wcc.get_wrangler(queue, tree, dtype, + fmm_level_to_order=lambda lev: order, + kernel_extra_kwargs=extra_kwargs) + + from boxtree.fmm import drive_fmm_local_quad + pot, = drive_fmm_local_quad(intersection, intersection_starts, area_l1_diff, + area_l1_diff_starts, tree, trav, wrangler, + weights) + + from sumpy import P2P + p2p = P2P(ctx, out_kernels, exclude_self=False) + evt, (ref_pot,) = p2p(queue, sources, sources, (weights,), + **extra_kwargs) + + pot = pot.get() + ref_pot = ref_pot.get() + + rel_err = la.norm(pot - ref_pot) / la.norm(ref_pot) + logger.info("order %d -> relative l2 error: %g" % (order, rel_err)) + + assert rel_err < 1e-8 + + # You can test individual routines by typing # $ python test_fmm.py 'test_routine(cl.create_some_context)' -- GitLab From 95fab4277c1b8f4d1e8421c8f934649fe1837b2e Mon Sep 17 00:00:00 2001 From: "userjjb@gmail.com" Date: Tue, 2 May 2017 02:43:34 -0500 Subject: [PATCH 9/9] Added sumpy to requirements.txt for install, now needed for sumpy kernel mesh-interaction tests --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 10d0d5e..7ce323e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,4 @@ git+git://github.com/inducer/islpy git+git://github.com/inducer/loopy git+git://github.com/inducer/pyfmmlib git+https://github.com/inducer/meshmode.git +git+https://github.com/inducer/sumpy.git -- GitLab