def test_simple(nx, ny, potFunc, xyz): # create the grid and the edge data gr = Grid() points = numpy.zeros((nx * ny, 4, 3), numpy.float64) data = numpy.zeros((nx * ny, 4)) dx = 1.0 / float(nx) dy = 1.0 / float(ny) k = 0 for i in range(nx): x0 = i * dx x1 = x0 + dx for j in range(ny): y0 = j * dy y1 = y0 + dy # node indexing # 3-->--2 # | | # ^ ^ # | | # 0-->--1 points[k, 0, :] = x0, y0, 0. points[k, 1, :] = x1, y0, 0. points[k, 2, :] = x1, y1, 0. points[k, 3, :] = x0, y1, 0. # edge indexing # 2 # +-->--+ # | | # 3^ ^1 # | | # +-->--+ # 0 data[k, 0] = potFunc(points[k, 1, :]) - potFunc(points[k, 0, :]) data[k, 1] = potFunc(points[k, 2, :]) - potFunc(points[k, 1, :]) data[k, 2] = potFunc(points[k, 2, :]) - potFunc(points[k, 3, :]) data[k, 3] = potFunc(points[k, 3, :]) - potFunc(points[k, 0, :]) # increment the cell counter k += 1 gr.setPoints(points) gr.dump('test_polyline_integral.vtk') pli = PolylineIntegral() pli.setGrid(gr) # no periodicity in x pli.buildLocator(numCellsPerBucket=128, periodX=0.0, enableFolding=False) pli.computeWeights(xyz, counterclock=False) flux = pli.getIntegral(data=data, placement=CELL_BY_CELL_DATA) exactFlux = potFunc(xyz[-1, :]) - potFunc(xyz[0, :]) print(f'total flux: {flux:.3f} exact flux: {exactFlux:.3f}') assert abs(flux - exactFlux) < 1.e-10
def test_create_grid(): # create the grid gr = Grid() # 2 cells points = numpy.array([(0., 0., 0.), (1., 0., 0.), (1., 1., 0.), (0., 1., 0.), (1., 0., 0.), (2., 0., 0.), (2., 1., 0.), (1., 1., 0.)]).reshape(2, 4, 3) gr.setPoints(points) gr.dump('test_create_grid.vtk')
def test_degenerate(): nx, ny, nxTarget, nyTarget = 1, 1, 12, 11 v0 = (0., 0., 0.) v1 = (1., 1., 0.) v2 = (1., 1., 0.) # degenerate point v3 = (0., 1., 0.) # create the grid gr = Grid() cellPoints = getCellByCellPoints( generateStructuredGridPoints(nx, ny, v0, v1, v2, v3)) gr.setPoints(cellPoints) numCells = cellPoints.shape[0] # create the interpolator vi = VectorInterp() vi.setGrid(gr) vi.buildLocator(numCellsPerBucket=1, periodX=0., enableFolding=False) # generate targets point for the above grid targetPoints = generateStructuredGridPoints(nxTarget, nyTarget, v0, v1, v2, v3).reshape((-1, 3)) numBad = vi.findPoints(targetPoints, tol2=1.e-10) # all points fall within the source grid so numBad == 0 assert (numBad == 0) with TemporaryDirectory() as d: # generate edge data data = numpy.zeros((numCells, 4), numpy.float64) for cellId in range(numCells): # iterate over the edges of the source grid cells for edgeIndex in range(4): # set one edge to 1, all other edges to zero data[cellId, edgeIndex] = 1.0 # get the edge interpolated vectors vectorData = vi.getEdgeVectors(data, placement=CELL_BY_CELL_DATA) fileName = f"{d}{sep}degenerate_cellId{cellId}edgeIndex{edgeIndex}Edge.vtk" saveVectorsVTKFile(targetPoints, vectorData, fileName) # get the face interpolated vectors vectorData = vi.getFaceVectors(data, placement=CELL_BY_CELL_DATA) fileName = f"{d}{sep}degenerate_cellId{cellId}edgeIndex{edgeIndex}Face.vtk" saveVectorsVTKFile(targetPoints, vectorData, fileName) # reset this edge's value back to its original data[cellId, edgeIndex] = 0.0
def test_rectilinear(): nx, ny, nxTarget, nyTarget = 1, 1, 2, 3 v0 = (0., 0., 0.) v1 = (1., 0., 0.) v2 = (1., 1., 0.) v3 = (0., 1., 0.) # create the grid gr = Grid() cellPoints = getCellByCellPoints( generateStructuredGridPoints(nx, ny, v0, v1, v2, v3)) gr.setPoints(cellPoints) numCells = cellPoints.shape[0] # create the interpolator vi = VectorInterp() vi.setGrid(gr) vi.buildLocator(numCellsPerBucket=1, periodX=0., enableFolding=False) # generate targets point for the above grid targetPoints = generateStructuredGridPoints(nxTarget, nyTarget, v0, v1, v2, v3).reshape((-1, 3)) numBad = vi.findPoints(targetPoints, tol2=1.e-10) # all points fall within the source grid so numBad == 0 assert (numBad == 0) # generate edge data data = numpy.zeros((numCells, 4), numpy.float64) for cellId in range(numCells): # iterate over the edges of the source grid cells for edgeIndex in range(4): # set one edge to 1, all other edges to zero data[cellId, edgeIndex] = 1.0 # get the edge interpolated vectors vectorData = vi.getEdgeVectors(data, placement=CELL_BY_CELL_DATA) assert (abs(vectorData.max() - 1.) < 1.e-12) assert (abs(vectorData.min() - 0.) < 1.e-12) # get the lateral flux interpolated vectors vectorData = vi.getFaceVectors(data, placement=CELL_BY_CELL_DATA) # face vectors take the sign of the area vector, # negative if pointing down assert (abs(numpy.fabs(vectorData).max() - 1.) < 1.e-12) assert (abs(numpy.fabs(vectorData).min() - 0.) < 1.e-12) # reset this edge's value back to its original data[cellId, edgeIndex] = 0.0
def test_rectilinear2(): nx, ny, nxTarget, nyTarget = 1, 2, 1, 2 v0 = numpy.array((0., 0., 0.)) v1 = numpy.array((nx, 0., 0.)) v2 = numpy.array((nx, ny, 0.)) v3 = numpy.array((0., ny, 0.)) # create the grid gr = Grid() cellPoints = getCellByCellPoints( generateStructuredGridPoints(nx, ny, v0, v1, v2, v3)) gr.setPoints(cellPoints) numCells = cellPoints.shape[0] # create the interpolator vi = VectorInterp() vi.setGrid(gr) vi.buildLocator(numCellsPerBucket=10, periodX=0., enableFolding=False) # generate targets point for the above grid dx = numpy.array((0.1, 0., 0.)) dy = numpy.array((0., 0.1, 0.)) targetPoints = generateStructuredGridPoints(nxTarget, nyTarget, v0 + dx + dy, v1 - dx + dy, v2 - dx - dy, v3 + dx - dy).reshape((-1, 3)) numBad = vi.findPoints(targetPoints, tol2=1.e-10) # all points fall within the source grid so numBad == 0 assert (numBad == 0) # generate edge data data = numpy.zeros((numCells, 4), numpy.float64) for cellId in range(numCells): # iterate over the edges of the source grid cells for edgeIndex in range(4): # set one edge to 1, all other edges to zero data[cellId, edgeIndex] = 1.0 # get the edge interpolated vectors vectorData = vi.getEdgeVectors(data, placement=CELL_BY_CELL_DATA) # get the lateral flux interpolated vectors vectorData = vi.getFaceVectors(data, placement=CELL_BY_CELL_DATA) # reset this edge's value back to its original data[cellId, edgeIndex] = 0.0
def test_create_grid(): # create the grid gr = Grid() # 2 cells points = numpy.array([(0., 0., 0.), (1., 0., 0.), (1., 1., 0.), (0., 1., 0.), (1., 0., 0.), (2., 0., 0.), (2., 1., 0.), (1., 1., 0.)]).reshape((2, 4, 3)) gr.setPoints(points) # get a pointer to the points of the cell-by-cell mesh pts = gr.getPoints() print(pts) with TemporaryDirectory() as d: fname = str(Path(d) / Path('grid.vtk')) gr.dump(fname)
def test_attach_data(): # create the grid gr = Grid() # 2 cells points = numpy.array([(0., 0., 0.), (1., 0., 0.), (1., 1., 0.), (0., 1., 0.), (1., 0., 0.), (2., 0., 0.), (2., 1., 0.), (1., 1., 0.)]).reshape((2, 4, 3)) gr.setPoints(points) # create cell data, 3 per cell nDataPerCell = 3 data = numpy.arange(0, 2 * nDataPerCell, dtype=numpy.float64).reshape( (2, nDataPerCell)) gr.attach('mydata', data) with TemporaryDirectory() as d: fname = str(Path(d) / Path('grid.vtk')) gr.dump(fname) # read the data back to check the layout of the data reader = vtk.vtkUnstructuredGridReader() reader.SetFileName(fname) reader.Update() ugrid = reader.GetOutput() arr = ugrid.GetCellData().GetArray('mydata') assert (arr.GetNumberOfTuples() == gr.getNumberOfCells()) assert (arr.GetNumberOfComponents() == nDataPerCell)
def test_simple(): # create the grid and the edge data gr = Grid() nx, ny = 3, 2 points = numpy.zeros((nx * ny, 4, 3), numpy.float64) data = numpy.zeros((nx * ny, 4)) dx = 1.0 / float(nx) dy = 1.0 / float(ny) k = 0 for i in range(nx): x0 = i * dx x1 = x0 + dx for j in range(ny): y0 = j * dy y1 = y0 + dy # node indexing # 3-->--2 # | | # ^ ^ # | | # 0-->--1 points[k, 0, :] = x0, y0, 0. points[k, 1, :] = x1, y0, 0. points[k, 2, :] = x1, y1, 0. points[k, 3, :] = x0, y1, 0. # edge indexing # 2 # +-->--+ # | | # 3^ ^1 # | | # +-->--+ # 0 data[k, 0] = potentialFunc(points[k, 1, :]) - potentialFunc( points[k, 0, :]) data[k, 1] = potentialFunc(points[k, 2, :]) - potentialFunc( points[k, 1, :]) data[k, 2] = potentialFunc(points[k, 2, :]) - potentialFunc( points[k, 3, :]) data[k, 3] = potentialFunc(points[k, 3, :]) - potentialFunc( points[k, 0, :]) # increment the cell counter k += 1 gr.setPoints(points) gr.dump('test_polyline_integral.vtk') pli = PolylineIntegral() # create the polyline through which the flux will be integrated xyz = numpy.array([(0., 0., 0.), (1., 0., 0.), (1., 1., 0.), (0., 1., 0.)]) # no periodicity in x pli.build(gr, xyz, counterclock=False, periodX=0.0) flux = pli.getIntegral(data) exactFlux = potentialFunc(xyz[-1, :]) - potentialFunc(xyz[0, :]) print(f'total flux: {flux:.3f} exact flux: {exactFlux:.3f}') assert abs(flux - exactFlux) < 1.e-10
def test_partially_outside(nx, ny, potFunc): print('target line is partially outside the domain, expect a warning!') # create the grid and the edge data gr = Grid() points = numpy.zeros((nx * ny, 4, 3), numpy.float64) data = numpy.zeros((nx * ny, 4)) dx = 1.0 / float(nx) dy = 1.0 / float(ny) k = 0 for i in range(nx): x0 = i * dx x1 = x0 + dx for j in range(ny): y0 = j * dy y1 = y0 + dy # node indexing # 3-->--2 # | | # ^ ^ # | | # 0-->--1 points[k, 0, :] = x0, y0, 0. points[k, 1, :] = x1, y0, 0. points[k, 2, :] = x1, y1, 0. points[k, 3, :] = x0, y1, 0. # edge indexing # 2 # +-->--+ # | | # 3^ ^1 # | | # +-->--+ # 0 data[k, 0] = potFunc(points[k, 1, :]) - potFunc(points[k, 0, :]) data[k, 1] = potFunc(points[k, 2, :]) - potFunc(points[k, 1, :]) data[k, 2] = potFunc(points[k, 2, :]) - potFunc(points[k, 3, :]) data[k, 3] = potFunc(points[k, 3, :]) - potFunc(points[k, 0, :]) # increment the cell counter k += 1 gr.setPoints(points) pli = PolylineIntegral() # create the polyline through which the flux will be integrated xyz = numpy.array([(-0.5, 0., 0.), (1., 0., 0.), (1., 1., 0.), (0., 1., 0.)]) pli.setGrid(gr) # no periodicity in x pli.buildLocator(numCellsPerBucket=128, periodX=0.0, enableFolding=False) pli.computeWeights(xyz, counterclock=False) flux = pli.getIntegral(data=data, placement=CELL_BY_CELL_DATA) # because the first point is outside the domain, only the contribution # stemming from the path inside the domain will be computed. Let's # correct for this by moving the first point inwards xyz[0, 0] = 0. exactFlux = potentialFunc(xyz[-1, :]) - potentialFunc(xyz[0, :]) print(f'total flux: {flux:.3f} exact flux: {exactFlux:.3f}') assert abs(flux - exactFlux) < 1.e-10 # print all the log messages printLogMessages() # write the logs to file writeLogMessages("test_partially_outside_log.txt")
def test_completely_outside(nx, ny, potFunc): print('target line is outside the domain, expect warnings!') # create the grid and the edge data gr = Grid() points = numpy.zeros((nx * ny, 4, 3), numpy.float64) data = numpy.zeros((nx * ny, 4)) dx = 1.0 / float(nx) dy = 1.0 / float(ny) k = 0 for i in range(nx): x0 = i * dx x1 = x0 + dx for j in range(ny): y0 = j * dy y1 = y0 + dy # node indexing # 3-->--2 # | | # ^ ^ # | | # 0-->--1 points[k, 0, :] = x0, y0, 0. points[k, 1, :] = x1, y0, 0. points[k, 2, :] = x1, y1, 0. points[k, 3, :] = x0, y1, 0. # edge indexing # 2 # +-->--+ # | | # 3^ ^1 # | | # +-->--+ # 0 data[k, 0] = potFunc(points[k, 1, :]) - potFunc(points[k, 0, :]) data[k, 1] = potFunc(points[k, 2, :]) - potFunc(points[k, 1, :]) data[k, 2] = potFunc(points[k, 2, :]) - potFunc(points[k, 3, :]) data[k, 3] = potFunc(points[k, 3, :]) - potFunc(points[k, 0, :]) # increment the cell counter k += 1 gr.setPoints(points) pli = PolylineIntegral() pli.setGrid(gr) # create the polyline through which the flux will be integrated xyz = numpy.array([(0., 0., 0.), (-1., 0., 0.), (-1., 1., 0.), (0., 1., 0.)]) # no periodicity in x pli.buildLocator(numCellsPerBucket=128, periodX=0.0, enableFolding=False) pli.computeWeights(xyz, counterclock=False) flux = pli.getIntegral(data=data, placement=CELL_BY_CELL_DATA) exactFlux = 0.0 print(f'total flux: {flux:.3f} exact flux: {exactFlux:.3f}') assert abs(flux - exactFlux) < 1.e-10