diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..df7e41e73 --- /dev/null +++ b/LICENSE @@ -0,0 +1,26 @@ +Copyright 2018-21 scikit-fem developers + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/LICENSE.md b/LICENSE.md deleted file mode 100644 index 103c0a8bb..000000000 --- a/LICENSE.md +++ /dev/null @@ -1,55 +0,0 @@ -This document describes the licensing of Python source code in the [scikit-fem -Github repository](https://github.com/kinnala/scikit-fem). - -The following license applies to all source code unless otherwise mentioned -later in this document or at the beginning of the respective files. - -> Copyright 2018-2020 scikit-fem developers -> -> Redistribution and use in source and binary forms, with or without -> modification, are permitted provided that the following conditions are met: -> -> 1. Redistributions of source code must retain the above copyright notice, this -> list of conditions and the following disclaimer. -> -> 2. Redistributions in binary form must reproduce the above copyright notice, -> this list of conditions and the following disclaimer in the documentation -> and/or other materials provided with the distribution. -> -> 3. Neither the name of the copyright holder nor the names of its contributors -> may be used to endorse or promote products derived from this software without -> specific prior written permission. -> -> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -> ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -> WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -> DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -> FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -> DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -> SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -> HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -> LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -> OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -Some examples under `docs/examples/` are licensed differently. In particular, -they have a GPL-licensed dependency and, therefore, are also GPL-licensed. - -- docs/examples/ex{28}.py - -> Copyright 2018-2020 scikit-fem developers -> -> This program is free software: you can redistribute it and/or modify -> it under the terms of the GNU General Public License as published by -> the Free Software Foundation, either version 3 of the License, or -> (at your option) any later version. -> -> This program is distributed in the hope that it will be useful, -> but WITHOUT ANY WARRANTY; without even the implied warranty of -> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -> GNU General Public License for more details. -> -> You should have received a copy of the GNU General Public License -> along with this program. If not, see . - -The contents of `skfem/` are distributed via Python Package Index as the package -`scikit-fem`. This distribution contains only BSD-licensed source code. diff --git a/README.md b/README.md index 613e806ba..918e0eef8 100644 --- a/README.md +++ b/README.md @@ -250,6 +250,13 @@ with respect to documented and/or tested features. ### Unreleased +- Added: `Mesh.save`/`Mesh.load` now exports/imports `Mesh.subdomains` and + `Mesh.boundaries` +- Added: `Mesh.load` now optionally writes any mesh data to a list passed via + the keyword argument `out` +- Added: `Mesh.with_boundaries` now allows the definition of internal boundaries/interfaces + via the flag `boundaries_only=False` + ### [3.2.0] - 2021-08-02 - Added: `ElementTriCCR` and `ElementTetCCR`, conforming Crouzeix-Raviart finite elements diff --git a/docs/examples/ex28.py b/docs/examples/ex28.py index 987ce837a..a3e708849 100644 --- a/docs/examples/ex28.py +++ b/docs/examples/ex28.py @@ -1,9 +1,5 @@ r"""Conjugate heat transfer. -.. note:: - This example requires the external package - `pygmsh `_. - The forced convection example can be extended to conjugate heat transfer by giving a finite thickness and thermal conductivity to one of the walls. @@ -54,24 +50,6 @@ 14th International Conference on Heat Transfer, Fluid Mechanics and Thermodynamics, Wicklow, Ireland. -License -------- - -Copyright 2018-2020 scikit-fem developers - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - """ from packaging import version from pathlib import Path @@ -85,10 +63,6 @@ from matplotlib.pyplot import subplots import numpy as np -import pygmsh - - -geometrycontext = pygmsh.geo.Geometry() halfheight = 1. length = 10. @@ -98,53 +72,7 @@ peclet = 357. - -def make_mesh(halfheight: float, # mm - length: float, - thickness: float) -> MeshTri: - with geometrycontext as geom: - - points = [] - lines = [] - - lcar = halfheight / 2 ** 2 - - for xy in [(0., halfheight), - (0., -halfheight), - (length, -halfheight), - (length, halfheight), - (0., -halfheight - thickness), - (length, -halfheight - thickness)]: - points.append(geom.add_point([*xy, 0.], lcar)) - - lines.append(geom.add_line(*points[:2])) - geom.add_physical(lines[-1], 'fluid-inlet') - - lines.append(geom.add_line(*points[1:3])) - - lines.append(geom.add_line(*points[2:4])) - geom.add_physical(lines[-1], 'fluid-outlet') - - lines.append(geom.add_line(points[3], points[0])) - - geom.add_physical(geom.add_plane_surface(geom.add_curve_loop(lines)), - 'fluid') - - lines.append(geom.add_line(points[1], points[4])) - geom.add_physical(lines[-1], 'solid-inlet') - - lines.append(geom.add_line(*points[4:6])) - geom.add_physical(lines[-1], 'heated') - - lines.append(geom.add_line(points[5], points[2])) - geom.add_physical(lines[-1], 'solid-outlet') - - geom.add_physical(geom.add_plane_surface(geom.add_curve_loop( - [*lines[-3:], -lines[1]])), 'solid') - - return from_meshio(geom.generate_mesh(dim=2)) - -mesh = from_file(Path(__file__).parent / 'meshes' / 'ex28.json') +mesh = Mesh.load(Path(__file__).parent / 'meshes' / 'ex28.msh') element = ElementTriP1() basis = { 'heat': Basis(mesh, element), diff --git a/docs/examples/meshes/ex28.json b/docs/examples/meshes/ex28.json deleted file mode 100644 index 8ae4b61ed..000000000 --- a/docs/examples/meshes/ex28.json +++ /dev/null @@ -1 +0,0 @@ -{"p": [[0.0, 1.0], [0.0, -1.0], [10.0, -1.0], [10.0, 1.0], [0.0, -2.0], [10.0, -2.0], [0.0, 0.7500000000006933], [0.0, 0.5000000000013871], [0.0, 0.2500000000020808], [0.0, 2.7527979895580756e-12], [0.0, -0.24999999999791922], [0.0, -0.4999999999986129], [0.0, -0.7499999999993063], [0.249999999999819, -1.0], [0.49999999999955125, -1.0], [0.7499999999993636, -1.0], [0.9999999999991893, -1.0], [1.2499999999989715, -1.0], [1.4999999999982851, -1.0], [1.749999999997556, -1.0], [1.9999999999968268, -1.0], [2.2499999999960973, -1.0], [2.499999999995368, -1.0], [2.749999999994639, -1.0], [2.9999999999939098, -1.0], [3.2499999999931806, -1.0], [3.499999999992451, -1.0], [3.7499999999917217, -1.0], [3.9999999999910267, -1.0], [4.249999999991268, -1.0], [4.499999999991649, -1.0], [4.74999999999203, -1.0], [4.9999999999924105, -1.0], [5.249999999992791, -1.0], [5.499999999993172, -1.0], [5.749999999993553, -1.0], [5.999999999993932, -1.0], [6.249999999994314, -1.0], [6.499999999994694, -1.0], [6.749999999995076, -1.0], [6.999999999995455, -1.0], [7.249999999995835, -1.0], [7.499999999996216, -1.0], [7.749999999996597, -1.0], [7.9999999999969775, -1.0], [8.249999999997355, -1.0], [8.499999999997733, -1.0], [8.749999999998112, -1.0], [8.99999999999849, -1.0], [9.249999999998867, -1.0], [9.499999999999245, -1.0], [9.749999999999622, -1.0], [10.0, -0.7500000000006933], [10.0, -0.5000000000013871], [10.0, -0.2500000000020808], [10.0, -2.7527979895580756e-12], [10.0, 0.24999999999791922], [10.0, 0.4999999999986129], [10.0, 0.7499999999993063], [9.75, 1.0], [9.499999999999998, 1.0], [9.249999999999998, 1.0], [8.999999999999998, 1.0], [8.749999999999996, 1.0], [8.499999999999996, 1.0], [8.249999999999996, 1.0], [7.999999999999996, 1.0], [7.749999999999995, 1.0], [7.499999999999995, 1.0], [7.249999999999995, 1.0], [6.999999999999994, 1.0], [6.749999999999993, 1.0], [6.499999999999993, 1.0], [6.249999999999992, 1.0], [5.999999999999991, 1.0], [5.749999999999991, 1.0], [5.49999999999999, 1.0], [5.24999999999999, 1.0], [4.999999999999989, 1.0], [4.749999999999989, 1.0], [4.4999999999999885, 1.0], [4.249999999999988, 1.0], [3.9999999999999876, 1.0], [3.7499999999999867, 1.0], [3.4999999999999867, 1.0], [3.249999999999986, 1.0], [2.999999999999985, 1.0], [2.749999999999985, 1.0], [2.499999999999984, 1.0], [2.249999999999984, 1.0], [1.9999999999999822, 1.0], [1.749999999999984, 1.0], [1.4999999999999876, 1.0], [1.2499999999999893, 1.0], [0.9999999999999911, 1.0], [0.7499999999999929, 1.0], [0.49999999999999645, 1.0], [0.24999999999999645, 1.0], [0.0, -1.25], [0.0, -1.5], [0.0, -1.75], [0.249999999999819, -2.0], [0.49999999999955125, -2.0], [0.7499999999993636, -2.0], [0.9999999999991893, -2.0], [1.2499999999989715, -2.0], [1.4999999999982851, -2.0], [1.749999999997556, -2.0], [1.9999999999968268, -2.0], [2.2499999999960973, -2.0], [2.499999999995368, -2.0], [2.749999999994639, -2.0], [2.9999999999939098, -2.0], [3.2499999999931806, -2.0], [3.499999999992451, -2.0], [3.7499999999917217, -2.0], [3.9999999999910267, -2.0], [4.249999999991268, -2.0], [4.499999999991649, -2.0], [4.74999999999203, -2.0], [4.9999999999924105, -2.0], [5.249999999992791, -2.0], [5.499999999993172, -2.0], [5.749999999993553, -2.0], [5.999999999993932, -2.0], [6.249999999994314, -2.0], [6.499999999994694, -2.0], [6.749999999995076, -2.0], [6.999999999995455, -2.0], [7.249999999995835, -2.0], [7.499999999996216, -2.0], [7.749999999996597, -2.0], [7.9999999999969775, -2.0], [8.249999999997355, -2.0], [8.499999999997733, -2.0], [8.749999999998112, -2.0], [8.99999999999849, -2.0], [9.249999999998867, -2.0], [9.499999999999245, -2.0], [9.749999999999622, -2.0], [10.0, -1.75], [10.0, -1.5], [10.0, -1.25], [1.3402242657711239, -0.7624997797030815], [2.145093568119333, -0.7616177095872402], [2.8749999999942744, -0.7834936490545219], [3.628758316706895, -0.7856635142214312], [8.88148770239354, 0.8297703075884469], [8.140739206369304, 0.8217973157450791], [7.3673703342467896, 0.7787420939922962], [6.625722838749337, 0.7795371220473675], [5.894862361237831, 0.7761813627761471], [5.157818242404232, 0.7623935517444774], [4.3529295299571835, 0.7617472787545793], [3.128744783727079, 0.7856557009468019], [2.371502904051198, 0.7872458372342978], [1.612339684278599, 0.7830928597531575], [4.886178153857974, -0.7828832896573785], [5.628059616839505, -0.7774108793205257], [6.379120004352967, -0.7875851520814634], [7.099724237492936, -0.7746561198953816], [7.874999999996794, -0.794293815599016], [8.643113454019362, -0.7614848922723154], [0.8696525081544475, 0.7780752304923583], [0.21650635094611262, -0.12499999999786955], [9.77019527994085, -0.12500000000007017], [0.8718102737867899, -0.7785501216467958], [4.362420026897872, -0.7521334963777592], [3.61804517363366, 0.7875090199286667], [9.108338161173904, -0.7613856639804962], [9.780802235330814, 0.38529214711633225], [0.21403008521882871, 0.38021629287474823], [9.395863620515154, 0.7807519317786085], [0.2165063509467102, -0.6249999999989597], [9.626088359517642, -0.7850280136258854], [0.40668413119495694, 0.781029615623878], [0.21777972049767835, -0.3812875982745326], [0.4326493513902654, -0.25568478143033363], [0.4329521434748641, -0.0009474635700792433], [0.6472506365576086, -0.12991201445066805], [0.6468387089137888, 0.1276954155640626], [0.8656045908407775, -0.0001884862979020857], [0.8633794341194501, -0.2546567237416727], [1.0820206242946697, -0.1258075350047135], [1.082376430832742, 0.12483399645104243], [1.298927029952992, -0.00016225642375274535], [1.2989937057382435, 0.2499452900060492], [1.5155185440107728, 0.12496383893222421], [1.5155216252320598, -0.1250330695797504], [1.73204869282255, -3.0035481560298362e-06], [1.7320466498777924, -0.25000601218556506], [1.9485564117940362, -0.1250010732990292], [1.946211223734832, 0.12093686833495801], [2.1646723958753125, -0.000677367491758211], [2.1649981994079237, -0.2501130734625233], [2.3814937897982613, -0.12513174015657744], [2.3814919963722367, 0.12486514872737889], [2.5980762113494302, 3.5449780741905894e-12], [2.6038239688852443, 0.23999963929901885], [2.810359036343627, 0.11435867700394794], [2.813878641303365, -0.12677355382940692], [3.0250861865429037, -0.011043742350550074], [3.0299711386261112, -0.2521362160271158], [3.2464085139679875, -0.12719665972691055], [3.247438831754426, 0.13301625989995278], [3.4692003981405426, -0.008249161294318342], [2.3815462969612287, -0.3750408022669938], [3.4641016151326776, -0.24999999999573974], [3.679379199664269, -0.12277468248110292], [3.6865756156271923, 0.11477693138082953], [3.8979041308801543, -0.0013329585140260621], [3.898240560925104, 0.24807399548035863], [4.113940010929818, 0.12445683949704457], [3.892483628115461, -0.23288899750942754], [2.8461971926703287, 0.36135865677460155], [1.082005571379509, -0.37591070978880087], [4.1138615991137195, 0.37458847249882316], [4.330220397933589, 0.24984088533529192], [4.330195805912571, -0.00011704585862268996], [4.546660397531475, 0.12495397324877458], [4.546649338973454, -0.1250271787657074], [4.7631468869387525, -1.2200916828640032e-05], [4.763145419775234, 0.24999029539138476], [4.979648215937736, 0.12499634908181798], [4.979647623473806, -0.12500264196991048], [5.196153038684843, -1.0488119731496177e-06], [5.196152783985006, -0.25000061512778055], [5.4126589365254105, -0.1250002773206152], [5.412658903457729, 0.12499977898072825], [5.629165173375111, -8.305387702115899e-08], [5.629165154358969, 0.24999994932404637], [5.845671488631087, 0.12499997771455917], [5.847678615861956, -0.12798653200089], [6.062529097035821, -0.00046875588749917263], [6.06223637375964, 0.24992187030749874], [6.278752480402976, 0.12490885240629941], [6.278770851333296, -0.12506431408671428], [6.495216357857327, -2.5910277103903995e-05], [6.4960108575447215, -0.2611795870763991], [6.711837905765854, -0.12686758288929356], [6.711724688644896, 0.12468441780871564], [6.928231369564782, -0.0003638608436777509], [6.92882016438172, 0.2530884515089581], [7.144817093451543, 0.12545409844742206], [7.144732189805577, -0.1249849603963532], [7.361237618967537, 7.818967840154956e-05], [7.361223314729273, -0.24998446178330824], [7.577727128005053, -0.12498437868091827], [7.577726705059846, 0.125015635169635], [7.794230178530534, 5.2094181669052695e-06], [7.794228996448418, 0.2500012660752728], [8.010735302813675, 0.12500107925243653], [8.004787738098148, -0.13530042328431263], [8.226250181100065, -0.0017165573350874281], [8.220137378371387, -0.26230430149929207], [8.442398501490894, -0.12733680980212028], [8.443357630186284, 0.12432443881418231], [8.65996416415593, -0.0005020618275481947], [6.711696879325233, -0.3749999999958271], [8.660140716108888, 0.2498037295016048], [8.87669318955125, 0.12488361128293077], [8.876700876634253, -0.12510307508696938], [9.093261242398176, -9.521366020175476e-06], [9.093254623638272, 0.24997901499024838], [9.313829861827962, 0.13034581354010816], [9.310448302982323, -0.12411061796677852], [6.278694964017751, 0.3749856056767492], [4.331347897872863, -0.2479338800329386], [8.443663790488168, 0.37485469472304256], [4.546633369862621, -0.3749999999961583], [7.574398548362566, -0.37652339004005836], [5.4126588002433635, 0.37499995472036074], [7.144709581217452, 0.37500000000491795], [5.412658861007847, -0.3750001487389202], [1.0824984674232263, 0.37496321441072034], [6.278684177432644, -0.37499999999597866], [7.5777230805002915, 0.3750028168775965], [8.445844173834711, -0.371368751129483], [8.22878435567944, -0.5365131502025081], [7.791762354857093, 0.4957286248169931], [2.810618819627442, -0.36931210284209676], [1.2964344150302782, 0.49549745262967115], [4.982359117067535, 0.37030090587927883], [4.759259061428566, 0.5356677016171852], [5.198864235595832, -0.4953032591071527], [1.5129492156709328, -0.3705192155176872], [1.7375106615775393, -0.5357347532354938], [6.7116968793249505, 0.3750000000047516], [2.378389837580686, 0.3768509849225052], [7.14895334865759, -0.3676531405726791], [9.321028438372617, 0.37999241811629336], [3.651605575887115, 0.36658344679140364], [5.624340855467118, 0.4984287312479935], [9.10124861702242, 0.49261767374878884], [8.659458515707836, 0.49833605218741917], [8.434142380696047, 0.6103130298569056], [3.014903333267484, -0.5413286365281681], [6.041735098989762, 0.5392404809097031], [6.266764022557701, 0.6015529943214486], [5.405432385801437, 0.6250644820710431], [8.230313170644518, 0.4808662371109209], [4.3446792749396455, -0.4892456014220519], [4.33012701891641, 0.5000000000039367], [4.113620667970283, 0.6250000000038849], [9.536232943913062, 0.006390097195847294], [9.533156025714364, -0.24878675345849305], [9.307459541581938, -0.36846236147596123], [9.523473491289694, -0.5369049585223774], [2.165063509458209, -0.4999999999958262], [2.377142632872282, -0.6199890490694919], [0.8650290426814824, -0.5134257933247337], [1.0900076672223147, -0.6259621600307644], [0.6444711790136646, -0.6436628111066254], [5.408488021791318, -0.6210980348339146], [5.62992515993205, -0.5102549314179566], [5.863726416899414, -0.6397327345620538], [5.857613785714802, -0.39309310562250177], [6.0704931185276525, -0.5217315416224724], [1.0872574234396408, 0.6210233761602839], [0.8658857541316164, 0.5116151925887598], [0.6430799295266296, 0.6438422668945067], [0.6357659639922424, 0.3970319713993681], [7.583016229223255, 0.6209744385329388], [5.170887914824659, -0.7576507445122311], [9.77297802352166, 0.13313127198411134], [9.551952204393832, 0.2607998738433278], [9.53775905854196, 0.5433152596234295], [9.746007095142375, -0.374999999992997], [1.3258401897149716, 0.7576830876866447], [7.77997508001764, 0.7285277245189463], [0.6427472411601405, -0.3934205103710753], [0.4268320270570077, 0.528753161039401], [4.124999999991147, -0.7834936490540867], [0.4308740172192859, 0.2549106613365719], [9.092982848686642, -0.24878092931405754], [8.87670315492144, -0.3748140007298969], [9.091764015808588, -0.49438662549065404], [8.875862137293979, -0.6209000639734267], [8.661092784903985, -0.4945231839317386], [9.382706668613018, -0.7785325722629397], [2.5930136623425026, -0.49188413356311034], [2.6089682995842463, -0.7593722087817786], [1.3003394814762381, -0.4992610750871215], [1.948557158512442, -0.37499999999622347], [3.8756263861105453, -0.783855293248732], [3.7540409257931637, -0.574413905550511], [3.4868254101248404, -0.5371413133462385], [3.991736029054076, -0.58389646775817], [5.196152422701226, 0.5000000000043351], [6.501745105306556, 0.5392578293257879], [7.3612159321637325, 0.5000000000051078], [7.1341907889914395, 0.6340010087436349], [6.928828291196883, 0.5147427464922998], [3.248099274923158, -0.38485747923912184], [3.249069927332469, -0.6153194156763085], [0.21650635094598997, 0.1250000000018735], [4.624999999991855, -0.7834936490535711], [4.757476820361909, -0.5450343658498134], [3.3749999999999574, 0.7834936490539082], [3.25062413062117, 0.5673476400900322], [2.999931922042098, 0.5804513052450071], [3.1198653461805934, 0.36480120531364746], [2.7497941549106573, 0.610899096978738], [3.377595230045766, 0.36557021370861675], [3.499999999999958, 0.5669872981078773], [1.2986272580010667, -0.24944897690030435], [5.845671475539944, 0.3750000000044202], [8.008369551789695, 0.3668274788656768], [2.5976497463906707, -0.24948555864687236], [8.660254037841728, -0.24999999999452827], [7.361238335226732, 0.2500917900305134], [2.1230073862384273, 0.7849329416277173], [1.8750000000000446, 0.7834936490538895], [1.7384884799675944, 0.5296107578747584], [2.0042992799487154, 0.5727592780871638], [3.8874358857757487, 0.7623927463378372], [8.227114937837065, 0.2450262285718619], [6.496305079259075, 0.25646846582419996], [6.6224361911010305, -0.7884171814360533], [6.499023611167887, -0.5387364608906189], [6.855143466854928, -0.7759183817835528], [7.632554655541626, -0.7896553592238155], [7.7709370589303015, -0.5531752976018127], [7.365566421880263, -0.7483454704239164], [6.101865652272447, -0.7690943654216559], [5.196605083015405, 0.24921598997575792], [8.368612926867298, -0.7783438478365294], [8.1249999999972, -0.7834936490535711], [3.8955058885790095, 0.4946196974114385], [7.786104644637188, -0.2650937034010762], [8.001791862618912, -0.3973625288948011], [1.6249999999979203, -0.7834936490544973], [4.874999999999987, 0.7834936490538903], [4.62499999999999, 0.783493649053902], [5.6243609330742, 0.7590279761192761], [6.898684901940076, 0.7667924180059633], [5.631616755402863, -0.25522251302579346], [1.8722173615083035, -0.7798554053686546], [4.54663336986253, 0.3750000000039789], [7.361215932164137, -0.4999999999956425], [4.97964607175501, -0.37499999999624606], [6.928942487231765, -0.24914492411559636], [1.730382634744447, 0.25018895807402786], [0.8631616526890655, 0.25599188401934186], [9.627312013958194, 0.7863764194040981], [9.11714974160963, 0.7529115533489019], [4.762200018560925, -0.25751273124911067], [8.882317318945148, 0.3658307074301449], [4.1138379668167975, -0.12371039401695155], [2.1548070209244647, 0.23374597350662932], [1.5155444566202687, 0.3750000000023435], [6.949299965219929, -0.5308227110009414], [6.062278296370646, -0.24982598105172332], [8.634426315519214, 0.7778127152124783], [2.2502277936988664, 0.588812932646001], [0.4265019379640514, -0.5127205676395573], [0.40485778477585, -0.7772677046558177], [9.786815776201452, -0.6186835174788705], [4.104162706196867, -0.38820203585859825], [0.20565382711784883, 0.617733287744906], [6.134179592962703, 0.7879328206581023], [9.79611896449845, 0.6289672895863943], [2.628223475837566, 0.7959707548216524], [2.5017964644458495, 0.5999853822761345], [3.685161735931665, -0.3568743683828086], [2.882216574069914, 0.7957732336879885], [3.39018644481271, -0.7946231258524663], [3.1114672930960476, -0.7943824593097293], [1.9400039953807033, 0.35265183170274983], [8.024951207409787, 0.6283045622185581], [1.501167902659374, -0.5952429326225679], [1.4983781750866414, 0.5910052258081928], [4.997840885335976, -0.5927870343852293], [4.9949987801949565, 0.5935291840908183], [6.387552074085163, 0.7896590984129794], [6.729412186173038, -0.5958414928899007], [6.73333560330356, 0.595066023175234], [6.26583731275072, -0.5984295040024378], [4.526759022814509, -0.5905766211416883], [4.522789796032936, 0.5911817258867166], [1.9736884518351652, -0.5904415736366877], [8.469489539060959, -0.588446765074515], [9.282748375693428, -0.5879344363464857], [9.294609895212355, 0.5899177673232044], [8.374109237656642, 0.8237081911659263], [2.78050082296319, -0.5890781461539352], [1.1249999999990803, -0.8309285975229164], [5.374999999999992, 0.8314424223589346], [3.708856074854203, 0.5922610410466406], [5.81039322604785, 0.5874337456884529], [4.124999999999986, 0.8331606810722306], [2.375323016477858, -0.8319534197356564], [8.874999999998305, -0.8333292013721667], [7.184951981082971, -0.5842954883777122], [7.542189783344858, -0.5934306146359366], [8.89692327235167, 0.5898239553303506], [5.388017389207309, -0.8297332548940367], [1.1090247491968033, 0.8285810304590409], [7.596072328697535, 0.8256488514088363], [5.874999999993746, -0.8430748134111247], [0.6249999999994574, -0.8453248909474808], [0.6249999999999947, 0.84532489094973], [3.004994550354191, 0.19428802914811244], [3.4911628195352513, 0.1945089555429248], [7.126840089298701, 0.8433134178331549], [8.000302655444528, -0.6129676882703419], [0.1830127018926412, -0.8169872981071244], [9.816987298107312, -0.816987298107605], [0.18301270189233473, 0.8169872981078496], [9.818341406386619, 0.8183414063864298], [2.620754694240717, 0.43847987633688934], [2.12359226067306, 0.42987491969865277], [4.182075087123125, -0.6044637385967745], [3.874999999990964, -0.43236835487190084], [8.24085104055526, 0.6729978672194781], [7.939133098759342, 0.8357259204965168], [3.3749999999927955, -1.2165063509455085], [2.124999999996462, -1.2165063509454779], [1.624999999997954, -1.2165063509455516], [2.6249999999950036, -1.216506350945478], [3.874999999991374, -1.783493649054507], [1.1249999999990374, -1.2165063509457812], [0.6249999999995624, -1.216506350946033], [4.355301264173285, -1.7807208457221844], [9.374999999999062, -1.2165063509464322], [8.874999999998304, -1.7834936490535633], [8.124999999997167, -1.2165063509464367], [5.874999999993743, -1.216506350946438], [6.874999999995262, -1.7834936490535611], [4.855301264173939, -1.2192791542774857], [6.371595709945972, -1.2169825264523295], [5.40099319841891, -1.220953581560331], [7.37499999999603, -1.2165063509464393], [1.8490068015711014, -1.7790464184394992], [2.3749999999957327, -1.7834936490545221], [3.124999999993545, -1.794086428283647], [1.3749999999986287, -1.7834936490545032], [0.8749999999992764, -1.7834936490540658], [4.124999999991273, -1.2165063509458527], [8.624999999997922, -1.2165063509464362], [7.874999999996789, -1.794086428283148], [8.400993198423471, -1.7790464184396657], [6.1249999999941185, -1.7834936490535571], [5.624999999993358, -1.7834936490535611], [5.124999999992584, -1.766499840694572], [9.374999999999055, -1.7834936490535642], [6.902578230140842, -1.2113087505559241], [7.3749999999960245, -1.7834936490535542], [0.1962683918106696, -1.6438176895763386], [9.802323440804077, -1.6408098265831321], [3.874999999991572, -1.2165063509458647], [3.9999999999914153, -1.4224199226624004], [3.749999999991803, -1.4206544594572927], [4.249999999990941, -1.43301270189164], [4.124999999991141, -1.6495190528375052], [0.8749999999993322, -1.216506350945899], [0.9999999999993375, -1.4224199226623266], [1.2499999999988964, -1.4206544594573463], [1.124999999999283, -1.6495190528372439], [0.7499999999996204, -1.4206544594576518], [0.49931175578741727, -1.4163320805841701], [0.6249999999999136, -1.6495190528379107], [0.3757268138163032, -1.2123445674083566], [3.624999999992115, -1.2144466438732888], [3.511341268495029, -1.4240618258837243], [3.251620181207798, -1.4363722570524924], [3.6249999999916445, -1.6495190528368562], [1.374999999998591, -1.2144466438733175], [1.499999999998387, -1.4200169310775836], [1.7445769123953496, -1.4288682687753638], [1.6249999999983291, -1.6495190528365753], [4.621716877355448, -1.783031515165026], [4.507731540766196, -1.5740667164034705], [4.749999999991897, -1.566987298107198], [4.6249999999917435, -1.3504809471608494], [7.124999999995641, -1.783493649053557], [7.249999999995829, -1.5775800773367106], [7.5275782301418035, -1.5736981526732914], [7.011341268498594, -1.5753006457352954], [6.7519998966050565, -1.551316537384713], [7.128977773753134, -1.3536077970690839], [8.874999999998298, -1.2165063509464435], [8.749999999998105, -1.4224199226632854], [8.999999999998492, -1.4206544594583561], [8.480301264179458, -1.4347046093841318], [8.624999999997923, -1.649519052839311], [8.124999999997176, -1.7834936490535533], [7.958333333330252, -1.5962633462227782], [8.235225740700507, -1.5626706686824756], [5.8749999999937375, -1.7834936490535596], [5.749999999993542, -1.577580077336716], [5.505423087595558, -1.571027478151981], [5.624999999993335, -1.3504809471606876], [5.999999999993926, -1.5793455405416434], [6.249999999994305, -1.5796397844091292], [6.124999999994109, -1.3504809471606798], [6.374999999994501, -1.7856023967705612], [9.62394065767922, -1.2116930112642215], [9.50135892180214, -1.4057457355040621], [9.250226486966028, -1.41581572119273], [9.125013756495719, -1.2147112086277772], [9.124999999998685, -1.649519052839314], [2.874999999994274, -1.785259112259376], [3.026224652879297, -1.5647854671504835], [2.7543707754755364, -1.5775073493792215], [2.8749999999942766, -1.3504809471635653], [7.874999999996793, -1.2059135717168474], [7.636341268499564, -1.208193003318267], [7.749999999996625, -1.4330127018928787], [2.12066780025878, -1.7827524439520182], [2.249277966706484, -1.5774565431544225], [2.5006081236939153, -1.5810782933907657], [2.3749999999957336, -1.3504809471635661], [2.015658761421234, -1.5922155046807038], [2.6258298165249103, -1.787889734013981], [6.489435048887668, -1.5841343716140328], [7.629596371687339, -1.7969703672491106], [3.402578230137835, -1.7902045036189025], [6.638964056135736, -1.1980772571752614], [5.126049077093876, -1.2177096899372621], [5.015875853199998, -1.4086677969860188], [5.236319688115223, -1.4055489076575622], [8.371716877361166, -1.2061955562987192], [4.863111544382968, -1.7871322097688884], [6.624999999994893, -1.7834936490535698], [5.3872451164298525, -1.7878825954244486], [3.10546658878934, -1.2196219660286647], [1.862754883560822, -1.2092677276698933], [4.400993198417379, -1.2209535815600654], [9.639658653685702, -1.8068885364640876], [9.776304173319307, -1.3931257826399546], [0.22981236287287418, -1.3976918832992762], [0.3917806563882752, -1.796504603019012], [3.249920380837692, -1.6327805694326174], [2.374999999995733, -1.1529496755707045], [2.1352698738705174, -1.4226371409105454], [2.625995779830893, -1.4152107776085194], [2.8749999999942744, -1.1529496755707056], [1.6249999999979206, -1.847050324429375], [3.624999999992085, -1.8470503244295329], [1.374999999998705, -1.5846406290526502], [3.8749999999914757, -1.5851212273697124], [1.1249999999990803, -1.8470503244298422], [4.124999999991147, -1.8470503244300702], [0.8749999999994862, -1.5851212273698396], [0.6249999999994575, -1.8470503244302245], [4.624999999991836, -1.152949675568975], [9.370746655995516, -1.5752199083647391], [9.124999999998675, -1.8470503244311223], [8.624999999997916, -1.8470503244311294], [5.1253136487540125, -1.5664557870792555], [5.624999999993359, -1.1529496755688855], [8.032259845669786, -1.397303777662788], [6.753367360830577, -1.3617232936995367], [5.874999999993731, -1.4148787726292331], [8.874999999998302, -1.585121227370766], [6.124999999994125, -1.152949675568877], [7.124999999995647, -1.1529496755688853], [6.3636630222219726, -1.4214327306058043], [7.371371944984849, -1.4204561454936355], [7.748101587030561, -1.6388061992642413], [8.248900745581617, -1.3634761925949104], [0.40305753395603616, -1.5977895705091392], [9.816987298107442, -1.1830127018924501], [0.18301270189204807, -1.1830127018920966], [9.816987298107732, -1.8169872981078383], [0.17806165951143782, -1.8234153990471529], [9.589456500883701, -1.600259137267605], [3.064577855717678, -1.3928151593488014], [1.9412715818696853, -1.4033697172501745], [1.824263063068218, -1.593275037500288], [3.4180793260982165, -1.593343100203082], [4.313992333216874, -1.598772249251494], [4.428722231096977, -1.404588536726621], [4.814416339486895, -1.4003288811823398], [4.940626117882261, -1.5942358449474763], [5.426560380247136, -1.4072573590859332], [8.431952388978843, -1.6062746046465697], [5.30933810889128, -1.5949671505831664], [6.909652905965641, -1.4106514048889107], [7.532058288723775, -1.3703732708649026], [6.559610396742764, -1.3907162395279917]], "t": [[92, 156, 328], [160, 380, 411], [294, 413, 455], [32, 157, 323], [160, 411, 453], [147, 413, 455], [151, 297, 420], [207, 346, 353], [143, 311, 342], [252, 254, 390], [152, 299, 348], [151, 297, 449], [174, 307, 339], [278, 386, 387], [286, 391, 397], [373, 402, 410], [172, 326, 443], [283, 392, 393], [145, 296, 427], [357, 400, 406], [238, 275, 379], [172, 326, 404], [150, 349, 434], [238, 258, 379], [143, 311, 446], [290, 326, 443], [269, 357, 406], [382, 389, 390], [152, 299, 447], [156, 328, 431], [153, 302, 303], [373, 402, 428], [270, 382, 389], [92, 93, 328], [346, 353, 354], [207, 346, 424], [290, 325, 326], [144, 308, 309], [32, 33, 323], [351, 352, 395], [145, 296, 445], [214, 360, 361], [157, 323, 432], [252, 389, 390], [254, 278, 390], [315, 317, 384], [162, 337, 338], [307, 339, 442], [169, 336, 337], [278, 386, 441], [174, 307, 417], [291, 363, 364], [175, 320, 331], [286, 397, 440], [23, 145, 341], [165, 304, 305], [303, 375, 388], [264, 304, 325], [283, 393, 439], [298, 349, 434], [53, 54, 327], [55, 56, 324], [176, 177, 415], [315, 384, 459], [22, 23, 341], [293, 405, 455], [150, 349, 436], [214, 361, 462], [171, 331, 333], [175, 320, 461], [25, 426, 427], [73, 420, 434], [296, 354, 427], [87, 422, 425], [283, 392, 433], [149, 350, 351], [166, 310, 312], [163, 319, 320], [158, 314, 315], [286, 391, 430], [373, 410, 431], [153, 303, 450], [158, 313, 314], [292, 299, 394], [291, 363, 463], [351, 395, 464], [264, 290, 325], [166, 310, 311], [163, 318, 319], [179, 182, 330], [383, 399, 453], [275, 317, 412], [180, 321, 403], [165, 304, 324], [165, 305, 327], [321, 331, 333], [297, 298, 420], [149, 322, 350], [144, 309, 451], [278, 387, 465], [272, 351, 352], [357, 400, 432], [304, 324, 325], [147, 405, 455], [294, 295, 413], [54, 165, 327], [55, 165, 324], [56, 170, 324], [232, 316, 396], [292, 394, 449], [272, 350, 351], [177, 330, 415], [162, 337, 452], [316, 317, 412], [242, 287, 352], [307, 327, 417], [169, 337, 452], [354, 426, 427], [298, 420, 434], [319, 321, 403], [242, 272, 352], [177, 179, 330], [182, 310, 330], [214, 360, 362], [362, 422, 425], [180, 321, 333], [314, 316, 396], [173, 176, 415], [373, 374, 428], [312, 415, 416], [143, 342, 430], [53, 327, 417], [232, 316, 412], [169, 336, 442], [293, 405, 443], [162, 338, 441], [152, 348, 433], [303, 375, 450], [144, 308, 440], [275, 379, 437], [160, 383, 453], [167, 301, 438], [153, 302, 439], [13, 14, 416], [380, 411, 435], [204, 361, 363], [375, 388, 448], [319, 320, 321], [314, 315, 316], [383, 399, 454], [167, 301, 472], [310, 312, 330], [145, 341, 445], [258, 379, 435], [345, 346, 424], [151, 394, 449], [305, 307, 327], [170, 324, 325], [320, 321, 331], [315, 316, 317], [171, 331, 419], [170, 325, 326], [164, 176, 177], [10, 164, 176], [9, 10, 164], [171, 333, 355], [8, 171, 355], [9, 164, 355], [11, 173, 176], [28, 29, 332], [277, 338, 369], [10, 11, 176], [8, 9, 355], [164, 177, 178], [280, 340, 368], [27, 28, 344], [49, 169, 339], [164, 178, 355], [28, 332, 344], [285, 342, 365], [261, 262, 334], [27, 146, 344], [335, 338, 369], [300, 367, 376], [29, 167, 332], [200, 280, 368], [190, 286, 343], [261, 334, 335], [265, 304, 305], [178, 333, 355], [11, 12, 173], [372, 373, 374], [188, 285, 365], [50, 51, 174], [50, 174, 339], [251, 367, 376], [156, 372, 373], [287, 349, 377], [15, 16, 166], [264, 265, 304], [91, 156, 372], [240, 287, 377], [282, 348, 385], [190, 191, 343], [203, 207, 353], [359, 363, 364], [358, 359, 364], [96, 97, 175], [168, 358, 364], [30, 167, 356], [84, 168, 358], [262, 265, 334], [29, 30, 167], [272, 350, 370], [56, 57, 170], [255, 256, 257], [185, 188, 365], [48, 49, 169], [359, 360, 361], [230, 292, 366], [371, 372, 374], [206, 308, 309], [202, 280, 296], [154, 358, 359], [262, 264, 265], [237, 240, 377], [335, 336, 337], [248, 276, 370], [200, 202, 280], [194, 206, 308], [197, 200, 368], [190, 285, 286], [40, 160, 380], [157, 356, 357], [188, 190, 285], [256, 257, 259], [223, 282, 385], [44, 161, 387], [161, 381, 382], [223, 225, 385], [94, 95, 163], [154, 359, 360], [251, 253, 376], [222, 283, 398], [83, 168, 375], [49, 50, 339], [309, 340, 341], [334, 335, 336], [200, 201, 202], [296, 353, 354], [194, 195, 206], [261, 335, 369], [43, 161, 381], [90, 371, 372], [276, 350, 370], [31, 157, 356], [89, 155, 371], [85, 154, 358], [188, 189, 190], [191, 194, 343], [42, 381, 383], [230, 231, 366], [197, 199, 200], [191, 193, 194], [245, 248, 370], [279, 322, 329], [359, 361, 363], [253, 255, 256], [90, 91, 372], [250, 276, 279], [159, 378, 379], [85, 86, 154], [276, 279, 322], [88, 89, 155], [266, 297, 298], [83, 84, 168], [240, 242, 287], [91, 92, 156], [260, 261, 262], [37, 159, 384], [248, 250, 276], [185, 187, 188], [271, 292, 299], [30, 31, 356], [234, 266, 297], [230, 271, 292], [206, 340, 368], [177, 178, 179], [228, 230, 271], [260, 262, 263], [215, 311, 342], [248, 249, 250], [203, 205, 207], [242, 243, 272], [89, 90, 371], [240, 241, 242], [202, 203, 353], [206, 309, 340], [332, 344, 347], [39, 378, 380], [215, 342, 365], [234, 235, 266], [194, 308, 343], [38, 159, 378], [41, 160, 383], [182, 183, 215], [225, 228, 385], [271, 348, 385], [84, 85, 358], [259, 268, 294], [250, 251, 367], [255, 277, 369], [39, 40, 380], [228, 229, 230], [215, 310, 311], [195, 206, 368], [202, 296, 353], [201, 202, 203], [237, 239, 240], [43, 44, 161], [245, 247, 248], [222, 282, 283], [40, 41, 160], [37, 38, 159], [31, 32, 157], [41, 42, 383], [243, 245, 370], [268, 294, 295], [34, 35, 158], [42, 43, 381], [250, 279, 367], [46, 162, 386], [271, 299, 348], [82, 83, 375], [199, 200, 201], [189, 190, 191], [193, 194, 195], [231, 233, 234], [46, 47, 162], [225, 227, 228], [231, 234, 366], [243, 272, 370], [38, 39, 378], [36, 37, 384], [44, 45, 387], [268, 300, 376], [256, 259, 268], [234, 297, 366], [276, 322, 350], [249, 250, 251], [266, 298, 349], [253, 254, 255], [228, 271, 385], [235, 237, 377], [241, 242, 243], [183, 215, 365], [222, 223, 282], [247, 248, 249], [233, 234, 235], [45, 386, 387], [187, 188, 189], [239, 240, 241], [229, 230, 231], [255, 257, 369], [268, 295, 300], [227, 228, 229], [146, 345, 346], [216, 303, 388], [183, 185, 365], [257, 259, 260], [253, 256, 376], [219, 221, 222], [182, 215, 310], [45, 46, 386], [263, 290, 293], [146, 344, 345], [195, 197, 368], [265, 305, 306], [216, 302, 303], [235, 266, 377], [256, 268, 376], [221, 222, 223], [251, 252, 253], [235, 236, 237], [274, 318, 319], [243, 244, 245], [254, 255, 277], [273, 314, 396], [237, 238, 239], [245, 246, 247], [231, 232, 233], [209, 211, 291], [78, 79, 392], [62, 63, 147], [273, 313, 314], [77, 78, 152], [80, 81, 153], [225, 226, 227], [71, 72, 150], [74, 75, 151], [68, 69, 149], [65, 66, 148], [195, 196, 197], [18, 19, 391], [197, 198, 199], [191, 192, 193], [17, 18, 143], [249, 251, 252], [241, 243, 244], [266, 349, 377], [233, 235, 236], [247, 249, 389], [75, 76, 394], [229, 231, 232], [181, 182, 183], [178, 180, 333], [335, 337, 338], [179, 181, 182], [218, 220, 267], [249, 252, 389], [252, 253, 254], [219, 222, 398], [246, 247, 270], [244, 245, 246], [79, 80, 393], [70, 71, 395], [238, 239, 258], [236, 237, 238], [216, 217, 302], [185, 186, 187], [223, 224, 225], [262, 263, 264], [227, 229, 396], [78, 152, 392], [267, 269, 301], [183, 184, 185], [257, 260, 261], [226, 227, 273], [239, 241, 401], [211, 216, 388], [236, 238, 275], [244, 246, 289], [211, 291, 388], [224, 226, 400], [26, 27, 146], [23, 24, 145], [20, 21, 144], [263, 293, 407], [218, 267, 408], [227, 273, 396], [19, 20, 397], [79, 392, 393], [221, 223, 224], [239, 258, 401], [254, 277, 278], [80, 153, 393], [203, 204, 205], [224, 225, 226], [181, 183, 184], [226, 273, 284], [257, 261, 369], [241, 244, 401], [75, 151, 394], [201, 203, 204], [305, 306, 307], [247, 270, 389], [193, 195, 196], [189, 191, 192], [229, 232, 396], [212, 216, 217], [284, 313, 323], [273, 284, 313], [71, 150, 395], [178, 179, 180], [212, 217, 218], [219, 220, 221], [211, 212, 216], [179, 180, 181], [61, 62, 405], [217, 302, 398], [226, 284, 400], [246, 270, 399], [217, 218, 219], [246, 289, 399], [274, 319, 403], [259, 294, 407], [198, 199, 214], [220, 267, 269], [18, 143, 391], [196, 197, 198], [220, 221, 406], [244, 289, 401], [217, 219, 398], [218, 219, 220], [184, 185, 186], [186, 187, 410], [7, 8, 171], [62, 147, 405], [260, 263, 407], [209, 210, 211], [19, 391, 397], [192, 193, 409], [196, 198, 288], [184, 186, 274], [54, 55, 165], [210, 211, 212], [187, 189, 402], [193, 196, 409], [274, 281, 318], [263, 264, 290], [221, 224, 406], [20, 144, 397], [220, 269, 406], [208, 210, 213], [59, 60, 404], [186, 274, 281], [205, 207, 208], [224, 400, 406], [60, 61, 172], [180, 181, 403], [281, 318, 328], [259, 260, 407], [189, 192, 402], [187, 402, 410], [181, 184, 403], [196, 288, 409], [186, 281, 410], [265, 306, 334], [210, 212, 408], [210, 213, 408], [208, 209, 210], [212, 218, 408], [306, 334, 336], [184, 274, 403], [205, 208, 209], [61, 172, 405], [258, 401, 411], [289, 401, 411], [344, 345, 347], [60, 172, 404], [300, 429, 474], [232, 233, 412], [236, 275, 412], [233, 236, 412], [155, 414, 423], [63, 64, 413], [52, 53, 417], [155, 371, 414], [63, 147, 413], [346, 354, 426], [269, 357, 438], [288, 414, 423], [148, 429, 474], [352, 395, 436], [267, 301, 418], [213, 408, 418], [299, 394, 447], [73, 74, 420], [312, 416, 460], [170, 326, 421], [57, 170, 421], [360, 362, 425], [166, 311, 446], [371, 374, 414], [312, 330, 415], [278, 390, 465], [6, 7, 419], [87, 88, 422], [208, 213, 424], [154, 360, 425], [86, 87, 425], [25, 26, 426], [146, 346, 426], [326, 404, 421], [7, 171, 419], [24, 25, 427], [192, 409, 428], [300, 367, 429], [279, 329, 429], [156, 373, 431], [285, 286, 430], [281, 328, 431], [382, 390, 465], [284, 323, 432], [282, 283, 433], [158, 315, 459], [22, 341, 451], [64, 413, 444], [166, 312, 460], [163, 320, 461], [204, 363, 463], [149, 351, 464], [267, 408, 418], [175, 331, 419], [72, 73, 434], [173, 415, 416], [158, 313, 456], [317, 384, 437], [204, 361, 462], [169, 339, 442], [172, 405, 443], [283, 398, 439], [286, 343, 440], [74, 151, 420], [362, 422, 423], [277, 278, 441], [306, 307, 442], [157, 357, 432], [295, 413, 444], [65, 148, 444], [280, 296, 445], [340, 341, 445], [162, 386, 441], [16, 166, 446], [17, 143, 446], [77, 152, 447], [76, 394, 447], [168, 375, 448], [57, 58, 421], [287, 349, 436], [297, 366, 449], [82, 375, 450], [81, 153, 450], [21, 144, 451], [48, 169, 452], [47, 162, 452], [289, 411, 453], [67, 329, 475], [381, 383, 454], [294, 407, 455], [144, 397, 440], [35, 158, 459], [36, 384, 459], [15, 166, 460], [96, 175, 461], [95, 163, 461], [199, 214, 462], [201, 204, 462], [288, 409, 471], [209, 291, 463], [204, 205, 463], [69, 149, 464], [70, 395, 464], [161, 382, 465], [2, 51, 467], [2, 52, 467], [1, 13, 466], [1, 12, 466], [0, 97, 468], [0, 6, 468], [66, 67, 475], [198, 288, 470], [167, 356, 438], [153, 393, 439], [13, 416, 466], [167, 332, 472], [163, 318, 457], [159, 384, 437], [3, 58, 469], [3, 59, 469], [150, 395, 436], [378, 380, 435], [88, 155, 422], [207, 208, 424], [287, 352, 436], [288, 414, 471], [275, 317, 437], [86, 154, 425], [26, 146, 426], [213, 418, 473], [291, 364, 448], [24, 145, 427], [155, 422, 423], [34, 158, 456], [192, 402, 428], [149, 322, 458], [288, 423, 470], [378, 379, 435], [279, 367, 429], [152, 392, 433], [309, 341, 451], [301, 418, 472], [143, 391, 430], [285, 342, 430], [281, 410, 431], [94, 163, 457], [284, 400, 432], [282, 348, 433], [159, 379, 437], [270, 382, 454], [356, 357, 438], [68, 149, 458], [347, 418, 473], [72, 150, 434], [67, 329, 458], [258, 411, 435], [93, 328, 457], [33, 323, 456], [269, 301, 438], [302, 398, 439], [347, 418, 472], [308, 343, 440], [67, 68, 458], [277, 338, 441], [306, 336, 442], [290, 293, 443], [291, 388, 448], [270, 399, 454], [93, 94, 457], [64, 65, 444], [280, 340, 445], [33, 34, 456], [329, 429, 475], [214, 362, 470], [362, 423, 470], [16, 17, 446], [76, 77, 447], [168, 364, 448], [14, 416, 460], [292, 366, 449], [81, 82, 450], [21, 22, 451], [47, 48, 452], [289, 399, 453], [52, 417, 467], [381, 382, 454], [293, 407, 455], [313, 323, 456], [213, 424, 473], [318, 328, 457], [173, 416, 466], [322, 329, 458], [35, 36, 459], [14, 15, 460], [95, 96, 461], [199, 201, 462], [409, 428, 471], [205, 209, 463], [69, 70, 464], [161, 387, 465], [59, 404, 469], [12, 173, 466], [51, 174, 467], [97, 175, 468], [148, 444, 474], [198, 214, 470], [6, 419, 468], [332, 347, 472], [345, 347, 473], [174, 417, 467], [295, 300, 474], [66, 148, 475], [148, 429, 475], [175, 419, 468], [345, 424, 473], [404, 421, 469], [374, 414, 471], [58, 421, 469], [374, 428, 471], [295, 444, 474], [548, 612, 621], [547, 548, 612], [520, 591, 622], [558, 590, 627], [557, 558, 590], [520, 522, 591], [508, 591, 622], [521, 592, 605], [480, 526, 601], [496, 530, 600], [496, 530, 598], [480, 526, 599], [565, 586, 597], [479, 565, 596], [477, 572, 595], [477, 572, 594], [479, 565, 597], [479, 572, 594], [479, 572, 596], [525, 563, 593], [480, 514, 601], [497, 518, 602], [496, 518, 600], [493, 530, 598], [480, 514, 603], [496, 518, 602], [526, 577, 599], [497, 518, 604], [483, 514, 603], [497, 521, 604], [497, 521, 605], [534, 588, 606], [489, 534, 606], [487, 552, 614], [505, 561, 607], [487, 552, 611], [537, 568, 620], [485, 561, 615], [485, 545, 609], [490, 555, 618], [492, 540, 619], [490, 555, 616], [492, 540, 617], [485, 561, 608], [505, 561, 608], [501, 545, 609], [485, 545, 615], [506, 540, 617], [487, 555, 616], [544, 548, 621], [487, 555, 614], [491, 552, 611], [547, 568, 620], [547, 568, 612], [521, 592, 622], [509, 590, 627], [28, 29, 498], [28, 498, 510], [27, 28, 510], [512, 523, 524], [13, 14, 522], [510, 512, 523], [27, 510, 523], [14, 482, 522], [512, 524, 526], [16, 17, 481], [482, 519, 520], [478, 527, 528], [481, 515, 516], [17, 18, 527], [18, 478, 527], [510, 511, 512], [482, 515, 519], [16, 481, 515], [26, 27, 523], [26, 476, 523], [478, 528, 529], [481, 516, 517], [15, 16, 515], [17, 481, 527], [483, 531, 532], [498, 510, 511], [517, 527, 528], [476, 523, 524], [15, 482, 515], [117, 118, 483], [99, 100, 508], [516, 517, 518], [482, 520, 522], [543, 559, 561], [481, 517, 527], [543, 559, 560], [478, 529, 587], [476, 524, 525], [119, 531, 583], [14, 15, 482], [519, 520, 521], [103, 104, 497], [29, 498, 588], [19, 478, 587], [528, 529, 530], [48, 49, 560], [501, 546, 548], [556, 575, 584], [50, 484, 557], [484, 557, 558], [48, 541, 560], [129, 507, 535], [130, 131, 576], [50, 51, 557], [42, 492, 567], [115, 116, 480], [507, 535, 536], [42, 43, 567], [539, 575, 584], [132, 500, 546], [541, 543, 560], [536, 538, 540], [132, 133, 546], [125, 126, 556], [124, 502, 549], [128, 129, 535], [130, 507, 576], [499, 541, 542], [47, 499, 541], [122, 503, 585], [126, 556, 584], [507, 536, 537], [541, 542, 543], [502, 553, 554], [579, 580, 581], [131, 500, 576], [500, 546, 547], [546, 547, 548], [123, 124, 549], [125, 502, 556], [38, 39, 578], [535, 536, 538], [128, 488, 535], [133, 501, 546], [49, 50, 484], [502, 549, 553], [135, 136, 485], [507, 537, 576], [550, 551, 552], [502, 554, 556], [133, 134, 501], [46, 47, 499], [49, 484, 560], [531, 533, 583], [562, 564, 574], [39, 506, 578], [489, 579, 580], [532, 533, 534], [124, 125, 502], [495, 562, 563], [129, 130, 507], [549, 550, 553], [112, 495, 562], [131, 132, 500], [123, 503, 549], [32, 33, 579], [35, 36, 487], [127, 128, 488], [488, 538, 539], [32, 489, 579], [494, 569, 570], [498, 513, 588], [25, 26, 476], [45, 486, 582], [542, 544, 545], [503, 551, 585], [107, 108, 493], [109, 110, 494], [20, 21, 477], [112, 113, 495], [18, 19, 478], [22, 23, 479], [31, 32, 489], [37, 38, 490], [111, 112, 562], [120, 121, 504], [109, 494, 569], [564, 571, 574], [122, 123, 503], [491, 579, 581], [494, 570, 571], [563, 564, 565], [494, 571, 574], [562, 563, 564], [569, 570, 573], [110, 111, 574], [111, 562, 574], [570, 571, 572], [108, 493, 569], [493, 569, 573], [110, 494, 574], [33, 34, 491], [41, 42, 492], [121, 122, 585], [137, 138, 505], [108, 109, 569], [38, 490, 578], [44, 45, 486], [499, 542, 544], [553, 554, 555], [554, 556, 575], [47, 48, 541], [39, 40, 506], [33, 491, 579], [531, 532, 533], [503, 550, 551], [503, 549, 550], [488, 535, 538], [119, 120, 583], [499, 544, 582], [566, 567, 568], [43, 566, 567], [484, 558, 559], [120, 504, 583], [113, 495, 577], [45, 46, 582], [126, 127, 584], [46, 499, 582], [43, 44, 566], [488, 539, 584], [113, 114, 577], [484, 559, 560], [121, 504, 585], [44, 486, 566], [118, 119, 531], [127, 488, 584], [105, 106, 496], [476, 525, 586], [118, 483, 531], [25, 476, 586], [19, 20, 587], [515, 516, 519], [24, 25, 586], [20, 477, 587], [140, 141, 509], [511, 513, 514], [498, 511, 513], [29, 30, 588], [505, 589, 627], [565, 586, 628], [483, 514, 632], [526, 577, 631], [489, 534, 634], [537, 568, 640], [506, 540, 639], [544, 548, 637], [505, 607, 627], [525, 563, 628], [493, 530, 630], [534, 588, 633], [501, 545, 637], [491, 552, 636], [138, 139, 589], [98, 99, 591], [141, 142, 590], [138, 505, 589], [99, 508, 591], [141, 509, 590], [101, 102, 592], [512, 526, 601], [117, 483, 603], [517, 518, 600], [116, 480, 603], [104, 497, 602], [528, 530, 600], [511, 514, 601], [495, 563, 593], [564, 565, 596], [570, 572, 595], [21, 477, 594], [23, 479, 597], [22, 479, 594], [571, 572, 596], [105, 496, 602], [115, 480, 599], [107, 493, 598], [106, 496, 598], [519, 521, 604], [114, 577, 599], [24, 586, 597], [103, 497, 605], [559, 561, 607], [31, 489, 606], [550, 552, 614], [543, 561, 615], [40, 506, 617], [537, 576, 620], [135, 485, 609], [35, 487, 611], [41, 492, 617], [554, 555, 618], [137, 505, 608], [36, 487, 616], [516, 518, 604], [34, 491, 611], [136, 485, 608], [37, 490, 616], [536, 540, 619], [553, 555, 614], [500, 547, 620], [134, 501, 609], [542, 545, 615], [566, 568, 612], [544, 582, 621], [30, 588, 606], [2, 51, 623], [2, 142, 623], [1, 13, 624], [1, 98, 624], [5, 139, 625], [5, 140, 625], [504, 583, 635], [492, 567, 640], [538, 539, 639], [504, 585, 638], [524, 525, 631], [477, 587, 629], [4, 101, 626], [4, 100, 626], [539, 575, 641], [490, 578, 641], [102, 592, 605], [504, 610, 635], [492, 619, 640], [539, 613, 639], [504, 610, 638], [525, 593, 631], [477, 595, 629], [539, 613, 641], [520, 521, 622], [98, 591, 624], [139, 589, 625], [142, 590, 623], [490, 618, 641], [116, 117, 603], [495, 577, 593], [570, 573, 595], [23, 24, 597], [21, 22, 594], [564, 571, 596], [106, 107, 598], [104, 105, 602], [517, 528, 600], [114, 115, 599], [511, 512, 601], [102, 103, 605], [516, 519, 604], [30, 31, 606], [486, 612, 621], [558, 559, 607], [580, 581, 610], [550, 553, 614], [34, 35, 611], [506, 578, 613], [40, 41, 617], [486, 582, 621], [36, 37, 616], [136, 137, 608], [554, 575, 618], [486, 566, 612], [500, 576, 620], [134, 135, 609], [542, 543, 615], [536, 537, 619], [100, 508, 626], [13, 522, 624], [51, 557, 623], [140, 509, 625], [532, 534, 633], [483, 532, 632], [489, 580, 634], [544, 545, 637], [551, 552, 636], [580, 634, 635], [529, 530, 630], [525, 586, 628], [532, 632, 633], [524, 526, 631], [563, 565, 628], [493, 573, 630], [529, 587, 629], [501, 548, 637], [533, 583, 635], [513, 514, 632], [491, 581, 636], [538, 540, 639], [567, 568, 640], [551, 585, 638], [533, 534, 634], [513, 588, 633], [533, 634, 635], [513, 632, 633], [509, 589, 625], [522, 591, 624], [557, 590, 623], [508, 592, 622], [508, 592, 626], [101, 592, 626], [573, 629, 630], [529, 629, 630], [581, 636, 638], [551, 636, 638], [509, 589, 627], [558, 607, 627], [573, 595, 629], [577, 593, 631], [580, 610, 635], [537, 619, 640], [506, 613, 639], [581, 610, 638], [578, 613, 641], [575, 618, 641]], "boundaries": {"fluid-inlet": [0, 3, 22, 25, 28, 31, 34, 37], "fluid-outlet": [9, 13, 236, 239, 242, 245, 248, 251], "solid-inlet": [5, 16, 373, 376], "heated": [17, 19, 381, 384, 387, 390, 393, 396, 399, 402, 405, 408, 411, 414, 417, 420, 423, 426, 429, 432, 435, 438, 441, 444, 447, 450, 453, 456, 459, 462, 465, 468, 471, 474, 477, 480, 483, 486, 489, 492], "solid-outlet": [10, 20, 497, 500]}, "subdomains": {"fluid": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759], "solid": [760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177]}} \ No newline at end of file diff --git a/docs/examples/meshes/ex28.msh b/docs/examples/meshes/ex28.msh new file mode 100644 index 000000000..2881ef264 Binary files /dev/null and b/docs/examples/meshes/ex28.msh differ diff --git a/requirements.txt b/requirements.txt index f37a5dd22..7bd367c49 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,3 +13,4 @@ flake8 dmsh sphinx sphinx_rtd_theme +h5py diff --git a/setup.cfg b/setup.cfg index f189590e3..8f8ff336d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -10,7 +10,7 @@ project_urls = long_description = file: README.md long_description_content_type = text/markdown license = BSD-3-Clause -license_file = LICENSE.md +license_file = LICENSE classifiers = Intended Audience :: Science/Research Operating System :: OS Independent diff --git a/skfem/io/meshio.py b/skfem/io/meshio.py index 20ea22d97..6434667a6 100644 --- a/skfem/io/meshio.py +++ b/skfem/io/meshio.py @@ -1,10 +1,7 @@ -"""Import any formats supported by meshio.""" - -import warnings +"""Import/export any formats supported by meshio.""" import meshio import numpy as np - import skfem @@ -19,45 +16,53 @@ 'quad9': skfem.MeshQuad2, } +BOUNDARY_TYPE_MAPPING = { + 'line': 'vertex', + 'triangle': 'line', + 'quad': 'line', + 'tetra': 'triangle', + 'hexahedron': 'quad', + 'tetra10': 'triangle', # TODO support quadratic facets + 'triangle6': 'line', # TODO + 'quad9': 'line', # TODO +} + TYPE_MESH_MAPPING = {MESH_TYPE_MAPPING[k]: k for k in dict(reversed(list(MESH_TYPE_MAPPING.items())))} -def from_meshio(m, force_mesh_type=None): - """Convert meshio mesh into :class:`skfem.mesh.Mesh`. - - Parameters - ---------- - m - The mesh from meshio. - force_mesh_type - An optional string forcing the mesh type if automatic detection - fails. See :data:`skfem.io.meshio.MESH_TYPE_MAPPING` for possible - values. - - Returns - ------- - A :class:`~skfem.mesh.Mesh` object. - - """ +def from_meshio(m, + out=None, + int_data_to_sets=False): cells = m.cells_dict + meshio_type = None + + # detect 3D + for k in cells: + if k in {'tetra', 'hexahedron', 'tetra10'}: + meshio_type = k + break + + if meshio_type is None: + # detect 2D + for k in cells: + if k in {'triangle', 'quad', 'triangle6', 'quad9'}: + meshio_type = k + break - if force_mesh_type is None: - meshio_type = None - - for k, v in MESH_TYPE_MAPPING.items(): - # find first if match - if k in cells: - meshio_type, mesh_type = k, v + if meshio_type is None: + # detect 1D + for k in cells: + if k == 'line': + meshio_type = k break - if meshio_type is None: - raise NotImplementedError("Mesh type(s) not supported " - "in import: {}.".format(cells.keys())) - else: - meshio_type, mesh_type = (force_mesh_type, - MESH_TYPE_MAPPING[force_mesh_type]) + if meshio_type is None: + raise NotImplementedError("Mesh type(s) not supported " + "in import: {}.".format(cells.keys())) + + mesh_type = MESH_TYPE_MAPPING[meshio_type] # create p and t p = np.ascontiguousarray(mesh_type.strip_extra_coordinates(m.points).T) @@ -67,41 +72,46 @@ def from_meshio(m, force_mesh_type=None): if meshio_type == 'hexahedron': t = t[[0, 4, 3, 1, 7, 5, 2, 6]] - mtmp = mesh_type(p, t) + if int_data_to_sets: + m.int_data_to_sets() - try: - # element to boundary element type mapping - bnd_type = { - 'line': 'vertex', - 'triangle': 'line', - 'quad': 'line', - 'tetra': 'triangle', - 'hexahedron': 'quad', - }[meshio_type] - - def find_tagname(tag): - for key in m.field_data: - if m.field_data[key][0] == tag: - return key - return None - - if m.cell_sets: # MSH 4.1 - subdomains = {k: v[meshio_type] - for k, v in m.cell_sets_dict.items() - if meshio_type in v} - facets = {k: [tuple(f) for f in - np.sort(m.cells_dict[bnd_type][v[bnd_type]])] + subdomains = {} + boundaries = {} + + # parse any subdomains from cell_sets + if m.cell_sets: + subdomains = {k: v[meshio_type] for k, v in m.cell_sets_dict.items() - if bnd_type in v} - boundaries = {k: np.array([i for i, f in - enumerate(map(tuple, mtmp.facets.T)) - if f in v]) - for k, v in facets.items()} - else: # MSH 2.2? + if meshio_type in v} + + # create temporary mesh for matching boundary elements + mtmp = mesh_type(p, t) + bnd_type = BOUNDARY_TYPE_MAPPING[meshio_type] + + # parse boundaries from cell_sets + if m.cell_sets and bnd_type in m.cells_dict: + facets = {k: [tuple(f) for f in + np.sort(m.cells_dict[bnd_type][v[bnd_type]])] + for k, v in m.cell_sets_dict.items() + if bnd_type in v} + boundaries = {k: np.array([i for i, f in + enumerate(map(tuple, mtmp.facets.T)) + if f in v]) + for k, v in facets.items()} + + # MSH 2.2 tag parsing + if m.cell_data and m.field_data: + try: elements_tag = m.cell_data_dict['gmsh:physical'][meshio_type] subdomains = {} tags = np.unique(elements_tag) + def find_tagname(tag): + for key in m.field_data: + if m.field_data[key][0] == tag: + return key + return None + for tag in tags: t_set = np.nonzero(tag == elements_tag)[0] subdomains[find_tagname(tag)] = t_set @@ -128,28 +138,66 @@ def find_tagname(tag): tagindex = np.nonzero(tags == tag)[0] boundaries[find_tagname(tag)] = index[tagindex, 1] - mtmp = mesh_type(p, t, boundaries, subdomains) + except Exception: + pass + + # attempt parsing skfem tags + if m.cell_data: + _boundaries, _subdomains = mtmp._decode_cell_data(m.cell_data) + boundaries.update(_boundaries) + subdomains.update(_subdomains) - except Exception as e: - warnings.warn("Unable to load tagged boundaries/subdomains.") - print(e) + # export mesh data + if out is not None and isinstance(out, list): + for i, field in enumerate(out): + out[i] = getattr(m, field) - return mtmp + return mesh_type( + p, + t, + None if len(boundaries) == 0 else boundaries, + None if len(subdomains) == 0 else subdomains, + ) -def from_file(filename): - return from_meshio(meshio.read(filename)) +def from_file(filename, out, **kwargs): + return from_meshio(meshio.read(filename), out, **kwargs) -def to_meshio(mesh, point_data=None): +def to_meshio(mesh, + point_data=None, + cell_data=None): t = mesh.dofs.element_dofs.copy() if isinstance(mesh, skfem.MeshHex): t = t[[0, 3, 6, 2, 1, 5, 7, 4]] - cells = {TYPE_MESH_MAPPING[type(mesh)]: t.T} - return meshio.Mesh(mesh.p.T, cells, point_data) + mtype = TYPE_MESH_MAPPING[type(mesh)] + cells = {mtype: t.T} + + if cell_data is None: + cell_data = {} + + cell_data.update(mesh._encode_cell_data()) + + mio = meshio.Mesh( + mesh.p.T, + cells, + point_data=point_data, + cell_data=cell_data, + ) + + return mio + +def to_file(mesh, + filename, + point_data=None, + cell_data=None, + **kwargs): -def to_file(mesh, filename, point_data=None, **kwargs): - meshio.write(filename, to_meshio(mesh, point_data), **kwargs) + meshio.write(filename, + to_meshio(mesh, + point_data, + cell_data), + **kwargs) diff --git a/skfem/mesh/mesh.py b/skfem/mesh/mesh.py index 883a61536..5831db6cc 100644 --- a/skfem/mesh/mesh.py +++ b/skfem/mesh/mesh.py @@ -162,7 +162,8 @@ def define_boundary(self, name: str, self._boundaries[name] = self.facets_satisfying(test, boundaries_only) def with_boundaries(self, - boundaries: Dict[str, Callable[[ndarray], ndarray]]): + boundaries: Dict[str, Callable[[ndarray], ndarray]], + boundaries_only: bool = True): """Return a copy of the mesh with named boundaries. Parameters @@ -171,13 +172,15 @@ def with_boundaries(self, A dictionary of lambda functions with the names of the boundaries as keys. The midpoint of the facet should return ``True`` for the corresponding lambda function if the facet belongs to the boundary. + boundaries_only + If ``True``, consider only facets on the boundary of the domain. """ return replace( self, _boundaries={ **({} if self._boundaries is None else self._boundaries), - **{name: self.facets_satisfying(test, True) + **{name: self.facets_satisfying(test, boundaries_only) for name, test in boundaries.items()} }, ) @@ -204,6 +207,46 @@ def with_subdomains(self, } ) + def _encode_cell_data(self) -> Dict[str, List[ndarray]]: + + subdomains = {} if self._subdomains is None else self._subdomains + boundaries = {} if self._boundaries is None else self._boundaries + + return { + **{ + f"skfem:s:{name}": [ + np.isin(np.arange(self.t.shape[1]), subdomain).astype(int) + ] + for name, subdomain in subdomains.items() + }, + **{ + f"skfem:b:{name}": [ + ((1 << np.arange(self.t2f.shape[0])) + @ np.isin(self.t2f, boundary)).astype(int) + ] + for name, boundary in boundaries.items() + }, + } + + def _decode_cell_data(self, cell_data: Dict[str, List[ndarray]]): + + subdomains = {} + boundaries = {} + + for name, data in cell_data.items(): + subnames = name.split(":") + if subnames[0] != "skfem": + continue + if subnames[1] == "s": + subdomains[subnames[2]] = np.nonzero(data[0])[0] + elif subnames[1] == "b": + boundaries[subnames[2]] = self.t2f[ + (1 << np.arange(self.t2f.shape[0]))[:, None] + & data[0].astype(np.int64) > 0 + ] + + return boundaries, subdomains + def boundary_nodes(self) -> ndarray: """Return an array of boundary node indices.""" return np.unique(self.facets[:, self.boundary_facets()]) @@ -407,6 +450,7 @@ def __str__(self): def save(self, filename: str, point_data: Optional[Dict[str, ndarray]] = None, + cell_data: Optional[Dict[str, ndarray]] = None, **kwargs) -> None: """Export the mesh and fields using meshio. @@ -417,23 +461,37 @@ def save(self, e.g. .msh, .vtk, .xdmf point_data Data related to the vertices of the mesh. + cell_data + Data related to the elements of the mesh. """ from skfem.io.meshio import to_file - return to_file(self, filename, point_data, **kwargs) + return to_file(self, + filename, + point_data, + cell_data, + **kwargs) @classmethod - def load(cls, filename: str): + def load(cls, + filename: str, + out: Optional[List[str]] = None, + **kwargs): """Load a mesh using meshio. Parameters ---------- filename The filename of the mesh file. + out + Optional list of ``meshio.Mesh`` attribute names, overwrite with + the corresponding data. E.g., ``['point_data', 'cell_data']``. """ from skfem.io.meshio import from_file - return from_file(filename) + return from_file(filename, + out, + **kwargs) @classmethod def from_dict(cls, data): @@ -471,7 +529,7 @@ def to_dict(self) -> Dict[str, Optional[Dict[str, List[float]]]]: @classmethod def from_mesh(cls, mesh): - """Reuse an existing mesh by adding nodes. + """Reuse an existing mesh by adding the higher order nodes. Parameters ---------- diff --git a/tests/test_mesh.py b/tests/test_mesh.py index 12380427e..40a717e58 100644 --- a/tests/test_mesh.py +++ b/tests/test_mesh.py @@ -56,20 +56,22 @@ def _runTest(self): # disabled np.array([[0.0, 1.0, 2.0], [1.0, 2.0, 3.0]]).T) +MESH_PATH = Path(__file__).parents[1] / 'docs' / 'examples' / 'meshes' + + class Loading(TestCase): """Check that Mesh.load works properly.""" def runTest(self): # submeshes - path = Path(__file__).parents[1] / 'docs' / 'examples' / 'meshes' - m = MeshTet.load(str(path / 'box.msh')) + m = MeshTet.load(MESH_PATH / 'box.msh') self.assertTrue((m.boundaries['top'] == m.facets_satisfying(lambda x: x[1] == 1)).all()) self.assertTrue((m.boundaries['back'] == m.facets_satisfying(lambda x: x[2] == 0)).all()) self.assertTrue((m.boundaries['front'] == m.facets_satisfying(lambda x: x[2] == 1)).all()) - m = MeshTri.load(str(path / 'square.msh')) + m = MeshTri.load(MESH_PATH / 'square.msh') self.assertTrue((m.boundaries['top'] == m.facets_satisfying(lambda x: x[1] == 1)).all()) self.assertTrue((m.boundaries['left'] @@ -281,6 +283,7 @@ def test_finder_simplex(m, seed): MeshTri2(), MeshQuad2(), MeshTet2(), + MeshLine(), ] ) def test_meshio_cycle(m): @@ -288,6 +291,63 @@ def test_meshio_cycle(m): M = from_meshio(to_meshio(m)) assert_array_equal(M.p, m.p) assert_array_equal(M.t, m.t) + assert m.boundaries == M.boundaries + assert m.subdomains == M.subdomains + + +_test_lambda = { + 'left': lambda x: x[0] < 0.6, + 'right': lambda x: x[0] > 0.3, +} + + +@pytest.mark.parametrize( + "internal_facets", + [ + True, + False, + ] +) +@pytest.mark.parametrize( + "m", + [ + MeshTri(), + MeshQuad(), + MeshHex(), + MeshTet(), + MeshHex().refined(), + MeshTet.load(MESH_PATH / 'box.msh'), + MeshTri.load(MESH_PATH / 'square.msh'), + ] +) +def test_meshio_cycle_boundaries(internal_facets, m): + + m = m.with_boundaries(_test_lambda, internal_facets) + M = from_meshio(to_meshio(m)) + assert_array_equal(M.p, m.p) + assert_array_equal(M.t, m.t) + for key in m.boundaries: + assert_array_equal(M.boundaries[key].sort(), + m.boundaries[key].sort()) + + +@pytest.mark.parametrize( + "m", + [ + MeshTri(), + MeshQuad(), + MeshHex(), + MeshTet(), + ] +) +def test_meshio_cycle_subdomains(m): + + m = m.refined(2).with_subdomains(_test_lambda) + M = from_meshio(to_meshio(m)) + assert_array_equal(M.p, m.p) + assert_array_equal(M.t, m.t) + for key in m.subdomains: + assert_array_equal(M.subdomains[key], m.subdomains[key]) @pytest.mark.parametrize( @@ -299,18 +359,58 @@ def test_meshio_cycle(m): MeshHex(), ] ) -def test_saveload_cycle(m): +def test_saveload_cycle_vtk(m): from tempfile import NamedTemporaryFile m = m.refined(2) - f = NamedTemporaryFile(delete=False) - m.save(f.name + ".vtk") - with pytest.warns(UserWarning): - m2 = Mesh.load(f.name + ".vtk") + with NamedTemporaryFile() as f: + m.save(f.name + ".vtk") + m2 = Mesh.load(f.name + ".vtk") assert_array_equal(m.p, m2.p) assert_array_equal(m.t, m2.t) -if __name__ == '__main__': - main() +@pytest.mark.parametrize( + "fmt, kwargs", + [ + ('.msh', {}), + ('.msh', {'file_format': 'gmsh22'}), + ('.vtk', {}), + ('.xdmf', {}), + ('.vtu', {}), + ('.med', {}), + ] +) +@pytest.mark.parametrize( + "m", + [ + MeshTri(), + MeshQuad(), + MeshHex(), # TODO facet order changes? + MeshTet(), + ] +) +def test_saveload_cycle_tags(fmt, kwargs, m): + + m = (m + .refined(2) + .with_subdomains(_test_lambda) + .with_boundaries({'test': lambda x: (x[0] == 0) * (x[1] < 0.6), + 'set': lambda x: (x[0] == 0) * (x[1] > 0.3)})) + from tempfile import NamedTemporaryFile + with NamedTemporaryFile() as f: + m.save(f.name + fmt, point_data={'foo': m.p[0]}, **kwargs) + out = ['point_data', 'cells_dict'] + m2 = Mesh.load(f.name + fmt, out=out) + + + assert_array_equal(m.p, m2.p) + assert_array_equal(m.t, m2.t) + assert_array_equal(out[0]['foo'], m.p[0]) + for key in m.subdomains: + assert_array_equal(m2.subdomains[key].sort(), + m.subdomains[key].sort()) + for key in m.boundaries: + assert_array_equal(m2.boundaries[key].sort(), + m.boundaries[key].sort())