Skip to content

Commit

Permalink
Merge pull request #267 from jcapriot/tree_mesh_negative_levels
Browse files Browse the repository at this point in the history
Tree mesh negative levels
  • Loading branch information
jcapriot authored Oct 25, 2021
2 parents 5ebeb22 + 4be8412 commit c6ea5eb
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 18 deletions.
10 changes: 5 additions & 5 deletions .azure-pipelines/azure-pipelines-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
eval "$(conda shell.bash hook)"
conda activate test
.ci/setup_headless_display.sh
pytest tests -v -s -W ignore::DeprecationWarning
pytest -v -s --ignore=tests/docs -W ignore::DeprecationWarning
displayName: 'Testing'
condition: ne(variables['python.version'], '3.8')
Expand All @@ -56,13 +56,13 @@ jobs:
eval "$(conda shell.bash hook)"
conda activate test
.ci/setup_headless_display.sh
pytest tests -v -s --cov-config=.coveragerc --cov=discretize --cov-report=xml --cov-report=html -W ignore::DeprecationWarning
pytest -v -s --cov-config=.coveragerc --cov=discretize --cov-report=xml --cov-report=html -W ignore::DeprecationWarning
displayName: 'Testing with coverage'
condition: eq(variables['python.version'], '3.8')
- script: |
bash <(curl -s https://codecov.io/bash)
curl -Os https://uploader.codecov.io/latest/linux/codecov
chmod +x codecov
./codecov
displayName: 'Upload coverage to codecov.io'
env:
CODECOV_TOKEN: $(codecov.token)
condition: eq(variables['python.version'], '3.8')
2 changes: 1 addition & 1 deletion .azure-pipelines/azure-pipelines-osx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,5 @@ jobs:
- script: |
eval "$(conda shell.bash hook)"
conda activate test
pytest tests -v -s -W ignore::DeprecationWarning
pytest -v -s --ignore=tests/docs -W ignore::DeprecationWarning
displayName: 'Running Tests'
2 changes: 1 addition & 1 deletion .azure-pipelines/azure-pipelines-win.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@ jobs:
- script: |
call activate test
pytest tests/base tests/cyl tests/tree -v -s -W ignore::DeprecationWarning
pytest -v -s --ignore=tests/docs -W ignore::DeprecationWarning
displayName: 'Running tests'
5 changes: 4 additions & 1 deletion discretize/_extensions/tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,10 @@ void Cell::divide(node_map_t& nodes, double* xs, double* ys, double* zs, bool fo
}else{
if(is_leaf()){
// Only need to call the function if I am a leaf...
int_t test_level = (*test_func)(this);
int test_level = (*test_func)(this);
if(test_level < 0){
test_level = (max_level + 1) - (abs(test_level) % (max_level + 1));
}
do_splitting = test_level > level;
}
}
Expand Down
4 changes: 2 additions & 2 deletions discretize/_extensions/tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ typedef std::vector<int_t> int_vec_t;
class PyWrapper{
public:
void *py_func;
int_t (*eval)(void *, Cell*);
int (*eval)(void *, Cell*);

PyWrapper(){
py_func = NULL;
};

void set(void* func, int_t (*wrapper)(void*, Cell*)){
void set(void* func, int (*wrapper)(void*, Cell*)){
py_func = func;
eval = wrapper;
};
Expand Down
2 changes: 1 addition & 1 deletion discretize/_extensions/tree.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ cdef extern from "tree.h":

cdef cppclass PyWrapper:
PyWrapper()
void set(void*, int_t(*)(void*, Cell*))
void set(void*, int(*)(void*, Cell*))

cdef cppclass Tree:
int_t n_dim
Expand Down
29 changes: 22 additions & 7 deletions discretize/_extensions/tree_ext.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -299,12 +299,13 @@ cdef class TreeCell:
def _level(self):
return self._cell.level

cdef int_t _evaluate_func(void* function, c_Cell* cell) with gil:
cdef int _evaluate_func(void* function, c_Cell* cell) with gil:
# Wraps a function to be called in C++
func = <object> function
pycell = TreeCell()
pycell._set(cell)
return <int_t> func(pycell)
val = func(pycell)
return <int> func(pycell)

cdef class _TreeMesh:
cdef c_Tree *tree
Expand Down Expand Up @@ -497,6 +498,7 @@ cdef class _TreeMesh:
if finalize:
self.finalize()

@cython.cdivision(True)
def refine_ball(self, points, radii, levels, finalize=True):
"""Refine :class:`~discretize.TreeMesh` using radial distance (ball) and refinement level for a cluster of points.
Expand Down Expand Up @@ -561,8 +563,13 @@ cdef class _TreeMesh:
raise ValueError("level length must match the points array's first dimension")

cdef int_t i
cdef int l
cdef int max_level = self.max_level
for i in range(ls.shape[0]):
self.tree.refine_ball(&cs[i, 0], rs[i], ls[i])
l = ls[i]
if l < 0:
l = (max_level + 1) - (abs(l) % (max_level + 1))
self.tree.refine_ball(&cs[i, 0], rs[i], l)
if finalize:
self.finalize()

Expand Down Expand Up @@ -631,9 +638,13 @@ cdef class _TreeMesh:
if x0.shape[0] != ls.shape[0]:
raise ValueError("level length must match the points array's first dimension")

cdef int_t i
cdef int l
cdef int max_level = self.max_level
for i in range(ls.shape[0]):
self.tree.refine_box(&x0[i, 0], &x1[i, 0], ls[i])
l = ls[i]
if l < 0:
l = (max_level + 1) - (abs(l) % (max_level + 1))
self.tree.refine_box(&x0[i, 0], &x1[i, 0], l)
if finalize:
self.finalize()

Expand Down Expand Up @@ -671,9 +682,13 @@ cdef class _TreeMesh:
cdef double[:, :] cs = points
cdef int[:] ls = np.require(np.atleast_1d(levels), dtype=np.int32,
requirements='C')
cdef int_t i
cdef int l
cdef int max_level = self.max_level
for i in range(ls.shape[0]):
self.tree.insert_cell(&cs[i, 0], ls[i])
l = ls[i]
if l < 0:
l = (max_level + 1) - (abs(l) % (max_level + 1))
self.tree.insert_cell(&cs[i, 0], l)
if finalize:
self.finalize()

Expand Down
43 changes: 43 additions & 0 deletions tests/tree/test_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,5 +399,48 @@ def test_Ez(self):
self.assertLess(np.abs(P[:, (self.M.nEx + self.M.nEy) :] * r - r).max(), TOL)


class TestWrapAroundLevels(unittest.TestCase):

def test_refine_func(self):
mesh1 = discretize.TreeMesh((16, 16, 16))
mesh2 = discretize.TreeMesh((16, 16, 16))

mesh1.refine(-1)
mesh2.refine(mesh2.max_level)

self.assertEqual(mesh1.nC, mesh2.nC)

def test_refine_box(self):
mesh1 = discretize.TreeMesh((16, 16, 16))
mesh2 = discretize.TreeMesh((16, 16, 16))

x0s = [[4, 4, 4]]
x1s = [[8, 8, 8]]
mesh1.refine_box(x0s, x1s, [-1])
mesh2.refine_box(x0s, x1s, [mesh2.max_level])

self.assertEqual(mesh1.nC, mesh2.nC)

def test_refine_ball(self):
mesh1 = discretize.TreeMesh((16, 16, 16))
mesh2 = discretize.TreeMesh((16, 16, 16))

centers = [[8, 8, 8]]
r_s = [3]
mesh1.refine_ball(centers, r_s, [-1])
mesh2.refine_ball(centers, r_s, [mesh2.max_level])

self.assertEqual(mesh1.nC, mesh2.nC)

def test_insert_point(self):
mesh1 = discretize.TreeMesh((16, 16, 16))
mesh2 = discretize.TreeMesh((16, 16, 16))

mesh1.insert_cells([[8, 8, 8]], [-1])
mesh2.insert_cells([[8, 8, 8]], [mesh2.max_level])

self.assertEqual(mesh1.nC, mesh2.nC)


if __name__ == "__main__":
unittest.main()

0 comments on commit c6ea5eb

Please sign in to comment.