In this tutorial, we will show the use of NodeFinder with a simple example. We will find the nodal line given by the following function:
In : import numpy as np In : def gap_function(pos): ...: x, y, z = pos ...: return np.sqrt((y - np.sin(np.pi * x))**2 + z**2) ...:
The NodeFinder module consists of two parts: In the first part, a Nelder-Mead optimization is performed from many starting points. If nodes are found, a local refinement is done to check if there are more nodal points nearby, such as when there is a nodal line. The goal of this first step is to find nodal positions which lie densely in the object which should be identified.
This first step is performed using the
In : import nodefinder as nf In : search_result = nf.search.run( ...: gap_function, ...: limits=[(-1, 1)] * 3, ...: initial_mesh_size=3, ...: gap_threshold=1e-4, ...: feature_size=0.1, ...: use_fake_potential=True, ...: ) ...: In : print(search_result) SearchResultContainer(coordinate_system=CoordinateSystem(limits=array([[-1, 1], [-1, 1], [-1, 1]]), periodic=True), minimization_results=<1548 values>, gap_threshold=0.0001, dist_cutoff=0.03333333333333333) In : nf.search.plot.points(search_result);
Of note here is the
use_fake_potential flag. When this flag is set, each minimization step first adds a “fake” potential to the function to be minimized, which repels the minimization from nodes which have already been found. This is especially useful for nodal lines, because it helps covering the whole line.
The second step in the process is to identify the nodal features from the point clouds calculated in the search step. For this purpose, the
identify submodule is used.
This process works by first clustering the points into connected components. Next, the dimension of each cluster is determined. Finally, the shape of the object is determined.
In : identify_result = nf.identify.run(search_result) In : print(identify_result) IdentificationResultContainer(coordinate_system=CoordinateSystem(limits=array([[-1, 1], [-1, 1], [-1, 1]]), periodic=True), feature_size=0.1, results=[IdentificationResult(dimension=1, shape=NodalLine(graph=<1468 nodes, 1468 edges>, degree_count=Counter(), shape_name='CLOSED LOOP'), positions=<1533 values>)]) In : nf.identify.plot.result(identify_result);