diff --git a/discretize/TreeMesh.py b/discretize/TreeMesh.py index ccde92ae3..1c77f8b88 100644 --- a/discretize/TreeMesh.py +++ b/discretize/TreeMesh.py @@ -349,9 +349,10 @@ def permuteE(self): def plotSlice( self, v, vType='CC', - normal='Z', ind=None, grid=True, view='real', + normal='Z', ind=None, grid=False, view='real', ax=None, clim=None, showIt=False, - pcolorOpts=None, streamOpts=None, gridOpts=None + pcolorOpts=None, streamOpts=None, gridOpts=None, + range_x=None, range_y=None, ): if pcolorOpts is None: @@ -360,10 +361,33 @@ def plotSlice( streamOpts = {'color': 'k'} if gridOpts is None: gridOpts = {'color': 'k', 'alpha': 0.5} - if vType not in ['CC', 'F', 'E']: - raise ValueError('vType must be one of CC, F, or E') + vTypeOpts = ['CC', 'N', 'F', 'E', 'Fx', 'Fy', 'Fz', 'E', 'Ex', 'Ey', 'Ez'] + viewOpts = ['real', 'imag', 'abs'] + normalOpts = ['X', 'Y', 'Z'] + if vType not in vTypeOpts: + raise ValueError( + "vType must be in ['{0!s}']".format("', '".join(vTypeOpts)) + ) if self.dim == 2: - raise Exception('plotSlice not support for 2D, use plotImage') + raise NotImplementedError( + 'Must be a 3D mesh. Use plotImage.' + ) + if view == 'vec': + raise NotImplementedError( + 'Vector view plotting is not implemented for TreeMesh (yet)' + ) + if view not in viewOpts: + raise ValueError( + "view must be in ['{0!s}']".format("', '".join(viewOpts)) + ) + normal = normal.upper() + if normal not in normalOpts: + raise ValueError( + "normal must be in ['{0!s}']".format("', '".join(normalOpts)) + ) + + if not isinstance(grid, bool): + raise TypeError('grid must be a boolean') import matplotlib.pyplot as plt import matplotlib @@ -388,7 +412,7 @@ def plotSlice( if type(ind) not in integer_types: raise ValueError('ind must be an integer') - #create a temporary TreeMesh with the slice through + # create a temporary TreeMesh with the slice through temp_mesh = TreeMesh(h2d, x2d) level_diff = self.max_level - temp_mesh.max_level @@ -406,24 +430,41 @@ def plotSlice( tm_gridboost[:, antiNormalInd] = temp_mesh.gridCC tm_gridboost[:, normalInd] = slice_loc - #interpolate values to self.gridCC if not 'CC' - if vType in ['F', 'E']: + # interpolate values to self.gridCC if not 'CC' + if vType is not 'CC': aveOp = 'ave' + vType + '2CC' Av = getattr(self, aveOp) - v = Av*v - - #interpolate values from self.gridCC to grid2d + if v.size == Av.shape[1]: + v = Av*v + elif len(vType) == 2: + # was one of Fx, Fy, Fz, Ex, Ey, Ez + # assuming v has all three components in these cases + vec_ind = {'x': 0, 'y': 1, 'z': 2}[vType[1]] + if vType[0] == 'E': + i_s = np.cumsum([0, self.nEx, self.nEy, self.nEz]) + elif vType[0] == 'F': + i_s = np.cumsum([0, self.nFx, self.nFy, self.nFz]) + v = v[i_s[vec_ind]:i_s[vec_ind+1]] + v = Av*v + + # interpolate values from self.gridCC to grid2d ind_3d_to_2d = self._get_containing_cell_indexes(tm_gridboost) v2d = v[ind_3d_to_2d] if ax is None: - fig = plt.figure() + plt.figure() ax = plt.subplot(111) - else: - assert isinstance(ax, matplotlib.axes.Axes), "ax must be an matplotlib.axes.Axes" - fig = ax.figure - - out = temp_mesh.plotImage(v2d, ax=ax, grid=grid, showIt=showIt, clim=clim) + elif not isinstance(ax, matplotlib.axes.Axes): + raise Exception("ax must be an matplotlib.axes.Axes") + + out = temp_mesh.plotImage( + v2d, vType='CC', + grid=grid, view=view, + ax=ax, clim=clim, showIt=False, + pcolorOpts=pcolorOpts, + gridOpts=gridOpts, + range_x=range_x, + range_y=range_y) ax.set_xlabel('y' if normal == 'X' else 'x') ax.set_ylabel('y' if normal == 'Z' else 'z') diff --git a/discretize/tree.cpp b/discretize/tree.cpp index 775c23479..93b7d16d0 100644 --- a/discretize/tree.cpp +++ b/discretize/tree.cpp @@ -395,148 +395,160 @@ void Cell::divide(node_map_t& nodes, double* xs, double* ys, double* zs, bool fo }else if(force){ do_splitting = true; }else{ - int_t test_level = (*test_func)(this); - if(test_level > level){ - do_splitting = true; + if(is_leaf()){ + // Only need to call the function if I am a leaf... + int_t test_level = (*test_func)(this); + do_splitting = test_level > level; } } - if(!do_splitting){ - return; - } - //If i haven't already been split... - if(children[0] == NULL){ - spawn(nodes, children, xs, ys, zs); - - //If I need to be split, and my neighbor is below my level - //Then it needs to be split - //-x,+x,-y,+y,-z,+z - if(balance){ - for(int_t i = 0; i < 2*n_dim; ++i){ - if(neighbors[i] != NULL && neighbors[i]->level < level){ - neighbors[i]->divide(nodes, xs, ys, zs, true); + if(do_splitting){ + //If i haven't already been split... + if(is_leaf()){ + spawn(nodes, children, xs, ys, zs); + + //If I need to be split, and my neighbor is below my level + //Then it needs to be split + //-x,+x,-y,+y,-z,+z + if(balance){ + for(int_t i = 0; i < 2*n_dim; ++i){ + if(neighbors[i] != NULL && neighbors[i]->level < level){ + neighbors[i]->divide(nodes, xs, ys, zs, true); + } } } - } - //Set children's neighbors (first do the easy ones) - // all of the children live next to each other - children[0]->set_neighbor(children[1], 1); - children[0]->set_neighbor(children[2], 3); - children[1]->set_neighbor(children[3], 3); - children[2]->set_neighbor(children[3], 1); - - if(n_dim == 3){ - children[4]->set_neighbor(children[5], 1); - children[4]->set_neighbor(children[6], 3); - children[5]->set_neighbor(children[7], 3); - children[6]->set_neighbor(children[7], 1); - - children[0]->set_neighbor(children[4], 5); - children[1]->set_neighbor(children[5], 5); - children[2]->set_neighbor(children[6], 5); - children[3]->set_neighbor(children[7], 5); - } + //Set children's neighbors (first do the easy ones) + // all of the children live next to each other + children[0]->set_neighbor(children[1], 1); + children[0]->set_neighbor(children[2], 3); + children[1]->set_neighbor(children[3], 3); + children[2]->set_neighbor(children[3], 1); + + if(n_dim == 3){ + children[4]->set_neighbor(children[5], 1); + children[4]->set_neighbor(children[6], 3); + children[5]->set_neighbor(children[7], 3); + children[6]->set_neighbor(children[7], 1); + + children[0]->set_neighbor(children[4], 5); + children[1]->set_neighbor(children[5], 5); + children[2]->set_neighbor(children[6], 5); + children[3]->set_neighbor(children[7], 5); + } - // -x direction - if(neighbors[0]!=NULL && !(neighbors[0]->is_leaf())){ - children[0]->set_neighbor(neighbors[0]->children[1], 0); - children[2]->set_neighbor(neighbors[0]->children[3], 0); - } - else{ - children[0]->set_neighbor(neighbors[0], 0); - children[2]->set_neighbor(neighbors[0], 0); - } - // +x direction - if(neighbors[1]!=NULL && !neighbors[1]->is_leaf()){ - children[1]->set_neighbor(neighbors[1]->children[0], 1); - children[3]->set_neighbor(neighbors[1]->children[2], 1); - }else{ - children[1]->set_neighbor(neighbors[1], 1); - children[3]->set_neighbor(neighbors[1], 1); - } - // -y direction - if(neighbors[2]!=NULL && !neighbors[2]->is_leaf()){ - children[0]->set_neighbor(neighbors[2]->children[2], 2); - children[1]->set_neighbor(neighbors[2]->children[3], 2); - }else{ - children[0]->set_neighbor(neighbors[2], 2); - children[1]->set_neighbor(neighbors[2], 2); - } - // +y direction - if(neighbors[3]!=NULL && !neighbors[3]->is_leaf()){ - children[2]->set_neighbor(neighbors[3]->children[0], 3); - children[3]->set_neighbor(neighbors[3]->children[1], 3); - }else{ - children[2]->set_neighbor(neighbors[3], 3); - children[3]->set_neighbor(neighbors[3], 3); - } - if(n_dim==3){ // -x direction if(neighbors[0]!=NULL && !(neighbors[0]->is_leaf())){ - children[4]->set_neighbor(neighbors[0]->children[5], 0); - children[6]->set_neighbor(neighbors[0]->children[7], 0); + children[0]->set_neighbor(neighbors[0]->children[1], 0); + children[2]->set_neighbor(neighbors[0]->children[3], 0); } else{ - children[4]->set_neighbor(neighbors[0], 0); - children[6]->set_neighbor(neighbors[0], 0); + children[0]->set_neighbor(neighbors[0], 0); + children[2]->set_neighbor(neighbors[0], 0); } // +x direction if(neighbors[1]!=NULL && !neighbors[1]->is_leaf()){ - children[5]->set_neighbor(neighbors[1]->children[4], 1); - children[7]->set_neighbor(neighbors[1]->children[6], 1); + children[1]->set_neighbor(neighbors[1]->children[0], 1); + children[3]->set_neighbor(neighbors[1]->children[2], 1); }else{ - children[5]->set_neighbor(neighbors[1], 1); - children[7]->set_neighbor(neighbors[1], 1); + children[1]->set_neighbor(neighbors[1], 1); + children[3]->set_neighbor(neighbors[1], 1); } // -y direction if(neighbors[2]!=NULL && !neighbors[2]->is_leaf()){ - children[4]->set_neighbor(neighbors[2]->children[6], 2); - children[5]->set_neighbor(neighbors[2]->children[7], 2); + children[0]->set_neighbor(neighbors[2]->children[2], 2); + children[1]->set_neighbor(neighbors[2]->children[3], 2); }else{ - children[4]->set_neighbor(neighbors[2], 2); - children[5]->set_neighbor(neighbors[2], 2); + children[0]->set_neighbor(neighbors[2], 2); + children[1]->set_neighbor(neighbors[2], 2); } // +y direction if(neighbors[3]!=NULL && !neighbors[3]->is_leaf()){ - children[6]->set_neighbor(neighbors[3]->children[4], 3); - children[7]->set_neighbor(neighbors[3]->children[5], 3); + children[2]->set_neighbor(neighbors[3]->children[0], 3); + children[3]->set_neighbor(neighbors[3]->children[1], 3); }else{ - children[6]->set_neighbor(neighbors[3], 3); - children[7]->set_neighbor(neighbors[3], 3); + children[2]->set_neighbor(neighbors[3], 3); + children[3]->set_neighbor(neighbors[3], 3); } - // -z direction - if(neighbors[4]!=NULL && !neighbors[4]->is_leaf()){ - children[0]->set_neighbor(neighbors[4]->children[4], 4); - children[1]->set_neighbor(neighbors[4]->children[5], 4); - children[2]->set_neighbor(neighbors[4]->children[6], 4); - children[3]->set_neighbor(neighbors[4]->children[7], 4); - }else{ - children[0]->set_neighbor(neighbors[4], 4); - children[1]->set_neighbor(neighbors[4], 4); - children[2]->set_neighbor(neighbors[4], 4); - children[3]->set_neighbor(neighbors[4], 4); - } - // +z direction - if(neighbors[5]!=NULL && !neighbors[5]->is_leaf()){ - children[4]->set_neighbor(neighbors[5]->children[0], 5); - children[5]->set_neighbor(neighbors[5]->children[1], 5); - children[6]->set_neighbor(neighbors[5]->children[2], 5); - children[7]->set_neighbor(neighbors[5]->children[3], 5); - }else{ - children[4]->set_neighbor(neighbors[5], 5); - children[5]->set_neighbor(neighbors[5], 5); - children[6]->set_neighbor(neighbors[5], 5); - children[7]->set_neighbor(neighbors[5], 5); + if(n_dim==3){ + // -x direction + if(neighbors[0]!=NULL && !(neighbors[0]->is_leaf())){ + children[4]->set_neighbor(neighbors[0]->children[5], 0); + children[6]->set_neighbor(neighbors[0]->children[7], 0); + } + else{ + children[4]->set_neighbor(neighbors[0], 0); + children[6]->set_neighbor(neighbors[0], 0); + } + // +x direction + if(neighbors[1]!=NULL && !neighbors[1]->is_leaf()){ + children[5]->set_neighbor(neighbors[1]->children[4], 1); + children[7]->set_neighbor(neighbors[1]->children[6], 1); + }else{ + children[5]->set_neighbor(neighbors[1], 1); + children[7]->set_neighbor(neighbors[1], 1); + } + // -y direction + if(neighbors[2]!=NULL && !neighbors[2]->is_leaf()){ + children[4]->set_neighbor(neighbors[2]->children[6], 2); + children[5]->set_neighbor(neighbors[2]->children[7], 2); + }else{ + children[4]->set_neighbor(neighbors[2], 2); + children[5]->set_neighbor(neighbors[2], 2); + } + // +y direction + if(neighbors[3]!=NULL && !neighbors[3]->is_leaf()){ + children[6]->set_neighbor(neighbors[3]->children[4], 3); + children[7]->set_neighbor(neighbors[3]->children[5], 3); + }else{ + children[6]->set_neighbor(neighbors[3], 3); + children[7]->set_neighbor(neighbors[3], 3); + } + // -z direction + if(neighbors[4]!=NULL && !neighbors[4]->is_leaf()){ + children[0]->set_neighbor(neighbors[4]->children[4], 4); + children[1]->set_neighbor(neighbors[4]->children[5], 4); + children[2]->set_neighbor(neighbors[4]->children[6], 4); + children[3]->set_neighbor(neighbors[4]->children[7], 4); + }else{ + children[0]->set_neighbor(neighbors[4], 4); + children[1]->set_neighbor(neighbors[4], 4); + children[2]->set_neighbor(neighbors[4], 4); + children[3]->set_neighbor(neighbors[4], 4); + } + // +z direction + if(neighbors[5]!=NULL && !neighbors[5]->is_leaf()){ + children[4]->set_neighbor(neighbors[5]->children[0], 5); + children[5]->set_neighbor(neighbors[5]->children[1], 5); + children[6]->set_neighbor(neighbors[5]->children[2], 5); + children[7]->set_neighbor(neighbors[5]->children[3], 5); + }else{ + children[4]->set_neighbor(neighbors[5], 5); + children[5]->set_neighbor(neighbors[5], 5); + children[6]->set_neighbor(neighbors[5], 5); + children[7]->set_neighbor(neighbors[5], 5); + } } } } if(!force){ - for(int_t i = 0; i < (1<divide(nodes, xs, ys, zs); + if(!is_leaf()){ + for(int_t i = 0; i < (1<divide(nodes, xs, ys, zs); + } } } }; + +void Cell::set_test_function(function func){ + test_func = func; + if(!is_leaf()){ + for(int_t i = 0; i < (1<set_test_function(func); + } + } +} + void Cell::build_cell_vector(cell_vec_t& cells){ if(this->is_leaf()){ cells.push_back(this); @@ -723,7 +735,7 @@ void Tree::build_tree_from_function(function test_func){ for(int_t iz=0; iztest_func = test_func; + roots[iz][iy][ix]->set_test_function(test_func); //Now we can divide for(int_t iz=0; iz 0: + mesh.insert_cells( + np.c_[ + newLoc[indIn, :2], + newLoc[indIn, 2]-zOffset], + np.ones(nnz)*mesh.max_level-ii, + finalize=False + ) + + zOffset += dz + + depth -= dz * octree_levels[ii] + + if finalize: + mesh.finalize() + + elif method.lower() == 'box': + + # Define the data extend [bottom SW, top NE] + bsw = np.min(xyz, axis=0) + tne = np.max(xyz, axis=0) + + hx = mesh.hx.min() + + if mesh.dim == 2: + hz = mesh.hy.min() + else: + hz = mesh.hz.min() + + # Pre-calculate max depth of each level + zmax = np.cumsum( + hz * np.asarray(octree_levels) * + 2**np.arange(len(octree_levels)) + ) + + if mesh.dim == 2: + # Pre-calculate outer extent of each level + padWidth = np.cumsum( + mesh.hx.min() * + np.asarray(octree_levels_padding) * + 2**np.arange(len(octree_levels_padding)) + ) + + # Make a list of outer limits + BSW = [ + bsw - np.r_[padWidth[ii], zmax[ii]] + for ii, (octZ, octXY) in enumerate( + zip(octree_levels, octree_levels_padding) + ) + ] + + TNE = [ + tne + np.r_[padWidth[ii], zmax[ii]] + for ii, (octZ, octXY) in enumerate( + zip(octree_levels, octree_levels_padding) + ) + ] + + else: + hy = mesh.hy.min() + + # Pre-calculate outer X extent of each level + padWidth_x = np.cumsum( + hx * np.asarray(octree_levels_padding) * + 2**np.arange(len(octree_levels_padding)) + ) + + # Pre-calculate outer Y extent of each level + padWidth_y = np.cumsum( + hy * np.asarray(octree_levels_padding) * + 2**np.arange(len(octree_levels_padding)) + ) + + # Make a list of outer limits + BSW = [ + bsw - np.r_[padWidth_x[ii], padWidth_y[ii], zmax[ii]] + for ii, (octZ, octXY) in enumerate( + zip(octree_levels, octree_levels_padding) + ) + ] + + TNE = [ + tne + np.r_[padWidth_x[ii], padWidth_y[ii], zmax[ii]] + for ii, (octZ, octXY) in enumerate( + zip(octree_levels, octree_levels_padding) + ) + ] + + def inBox(cell): + + xyz = cell.center + + for ii, (nC, bsw, tne) in enumerate(zip(octree_levels, BSW, TNE)): + + if np.all([xyz > bsw, xyz < tne]): + return mesh.max_level-ii + + return cell._level + + mesh.refine(inBox, finalize=finalize) + + else: + raise NotImplementedError( + "Only method= 'radial', 'surface'" + " or 'box' have been implemented" + ) + + return mesh diff --git a/docs/api/index.rst b/docs/api/index.rst index c2927ea53..aaf6717d4 100644 --- a/docs/api/index.rst +++ b/docs/api/index.rst @@ -101,6 +101,8 @@ Mesh Utilities utils.closestPoints utils.ExtractCoreMesh utils.random_model + utils.mesh_builder_xyz + utils.refine_tree_xyz Matrix Utilities diff --git a/docs/conf.py b/docs/conf.py index a9aba242c..b06b51de5 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -39,7 +39,7 @@ 'sphinx.ext.extlinks', 'sphinx.ext.intersphinx', 'sphinx.ext.mathjax', - # 'sphinx.ext.napoleon', + 'sphinx.ext.napoleon', 'sphinx.ext.todo', 'sphinx.ext.viewcode', 'matplotlib.sphinxext.plot_directive', @@ -53,16 +53,16 @@ numpydoc_class_members_toctree = False -# napoleon_numpy_docstring = True -# napoleon_include_init_with_doc = False -# napoleon_include_private_with_doc = False -# napoleon_include_special_with_doc = True -# napoleon_use_admonition_for_examples = False -# napoleon_use_admonition_for_notes = False -# napoleon_use_admonition_for_references = False -# napoleon_use_ivar = False -# napoleon_use_param = True -# napoleon_use_rtype = True +napoleon_numpy_docstring = True +napoleon_include_init_with_doc = False +napoleon_include_private_with_doc = False +napoleon_include_special_with_doc = True +napoleon_use_admonition_for_examples = False +napoleon_use_admonition_for_notes = False +napoleon_use_admonition_for_references = False +napoleon_use_ivar = False +napoleon_use_param = True +napoleon_use_rtype = True # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -155,7 +155,7 @@ html_theme = 'sphinx_rtd_theme' html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] pass -except Exception, e: +except Exception: html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme diff --git a/docs/examples/vtki_demo.py b/docs/examples/vtki_demo.py index 95d1acbf4..f3402493e 100644 --- a/docs/examples/vtki_demo.py +++ b/docs/examples/vtki_demo.py @@ -8,7 +8,7 @@ To run this example, you will need to `install vtki`_. .. _vtki: http://www.vtki.org -.. _install vtki: http://www.vtki.org/en/latest/getting-started/installation.html +.. _install vtki: http://docs.vtki.org/getting-started/installation.html - contributed by `@banesullivan `_ diff --git a/tests/tree/test_tree_utils.py b/tests/tree/test_tree_utils.py new file mode 100644 index 000000000..af28f9e44 --- /dev/null +++ b/tests/tree/test_tree_utils.py @@ -0,0 +1,136 @@ +from __future__ import print_function +import numpy as np +import unittest +import discretize +from discretize.utils import meshutils + +TOL = 1e-8 +np.random.seed(12) + + +class TestRefineOcTree(unittest.TestCase): + + def test_radial(self): + dx = 0.25 + rad = 10 + mesh = meshutils.mesh_builder_xyz( + np.c_[0.01, 0.01, 0.01], [dx, dx, dx], + depth_core=0, + padding_distance=[[0, 20], [0, 20], [0, 20]], + mesh_type='TREE', + ) + + radCell = int(np.ceil(rad/dx)) + mesh = meshutils.refine_tree_xyz( + mesh, np.c_[0, 0, 0], + octree_levels=[radCell], method='radial', + finalize=True + ) + + # Volume of sphere + vol = 4.*np.pi/3.*rad**3. + + residual = np.abs( + vol - + mesh.vol[ + mesh._cell_levels_by_indexes(range(mesh.nC)) == mesh.max_level + ].sum() + )/vol * 100 + + self.assertTrue(residual < 3) + + def test_box(self): + dx = 0.25 + dl = 10 + + # Create a box 2*dl in width + X, Y, Z = np.meshgrid(np.c_[-dl, dl], np.c_[-dl, dl], np.c_[-dl, dl]) + xyz = np.c_[np.ravel(X), np.ravel(Y), np.ravel(Z)] + mesh = meshutils.mesh_builder_xyz( + np.c_[0.01, 0.01, 0.01], [dx, dx, dx], + depth_core=0, + padding_distance=[[0, 20], [0, 20], [0, 20]], + mesh_type='TREE', + ) + + mesh = meshutils.refine_tree_xyz( + mesh, xyz, octree_levels=[1], method='box', finalize=True + ) + + # Volume of box + vol = (2*dl)**3 + + residual = np.abs( + vol - + mesh.vol[ + mesh._cell_levels_by_indexes(range(mesh.nC)) == mesh.max_level + ].sum() + )/vol * 100 + + self.assertTrue(residual < 0.5) + + def test_surface(self): + dx = 0.1 + dl = 20 + + # Define triangle + xyz = np.r_[ + np.c_[-dl/2, -dl/2, 0], + np.c_[dl/2, -dl/2, 0], + np.c_[dl/2, dl/2, 0] + ] + mesh = meshutils.mesh_builder_xyz( + np.c_[0.01, 0.01, 0.01], [dx, dx, dx], + depth_core=0, + padding_distance=[[0, 20], [0, 20], [0, 20]], + mesh_type='TREE', + ) + + mesh = meshutils.refine_tree_xyz( + mesh, xyz, octree_levels=[1], method='surface', finalize=True + ) + + # Volume of triangle + vol = dl*dl*dx/2 + + residual = np.abs( + vol - + mesh.vol[ + mesh._cell_levels_by_indexes(range(mesh.nC)) == mesh.max_level + ].sum()/2 + )/vol * 100 + + self.assertTrue(residual < 5) + + def test_errors(self): + dx = 0.25 + rad = 10 + self.assertRaises(ValueError, meshutils.mesh_builder_xyz, + np.c_[0.01, 0.01, 0.01], [dx, dx, dx], + depth_core=0, + padding_distance=[[0, 20], [0, 20], [0, 20]], + mesh_type='cyl', + ) + + mesh = meshutils.mesh_builder_xyz( + np.c_[0.01, 0.01, 0.01], [dx, dx, dx], + depth_core=0, + padding_distance=[[0, 20], [0, 20], [0, 20]], + mesh_type='tree', + ) + + radCell = int(np.ceil(rad/dx)) + self.assertRaises(NotImplementedError, meshutils.refine_tree_xyz, + mesh, np.c_[0, 0, 0], octree_levels=[radCell], method='other', + finalize=True + ) + + self.assertRaises(ValueError, meshutils.refine_tree_xyz, + mesh, np.c_[0, 0, 0], octree_levels=[radCell], + octree_levels_padding=[], method='surface', + finalize=True + ) + + +if __name__ == '__main__': + unittest.main()