### Configure and Setup Laplace FMM Source: https://github.com/exafmm/exafmm-t/blob/master/examples/python/laplace.ipynb Shows how to instantiate the LaplaceFmm solver and set up the octree structure. The setup function builds the tree, interaction lists, and handles pre-computation matrices. ```python fmm = laplace.LaplaceFmm(p=10, ncrit=200, filename="test_file.dat") tree = laplace.setup(sources, targets, fmm) ``` -------------------------------- ### Install ExaFMM-t Library Source: https://context7.com/exafmm/exafmm-t/llms.txt Instructions for installing the library dependencies and building the project on Ubuntu, or installing via pip for Python. ```bash apt-get update apt-get -y install libopenblas-dev libfftw3-dev gfortran ./configure make check make install ``` ```bash pip install git+https://github.com/exafmm/exafmm-t.git ``` -------------------------------- ### Install Documentation Dependencies Source: https://github.com/exafmm/exafmm-t/blob/master/docs/documentation.rst Command to install the necessary Python packages required for the documentation build process using pip. ```bash pip install -r docs/requirements.txt ``` -------------------------------- ### Initialization and Setup Source: https://github.com/exafmm/exafmm-t/blob/master/examples/python/laplace.ipynb Methods to initialize source and target bodies and configure the LaplaceFmm instance. ```APIDOC ## POST /init_sources ### Description Initializes source bodies for the FMM calculation. ### Parameters #### Request Body - **src_coords** (numpy.ndarray) - Required - Coordinates of source bodies. - **src_charges** (numpy.ndarray) - Required - Weights/charges of source bodies. ## POST /init_targets ### Description Initializes target bodies for the FMM calculation. ### Parameters #### Request Body - **trg_coords** (numpy.ndarray) - Required - Coordinates of target bodies. ## POST /setup ### Description Builds the octree, interaction lists, and pre-computes invariant matrices. ### Parameters #### Request Body - **sources** (list) - Required - List of source instances. - **targets** (list) - Required - List of target instances. - **fmm** (LaplaceFmm) - Required - The FMM configuration instance. ``` -------------------------------- ### Build Documentation Locally Source: https://github.com/exafmm/exafmm-t/blob/master/docs/documentation.rst Commands to navigate to the documentation directory and trigger the HTML build process. This assumes all dependencies like Doxygen and Python requirements are already installed. ```bash cd docs make html ``` -------------------------------- ### HelmholtzFmm - Helmholtz Kernel Source: https://context7.com/exafmm/exafmm-t/llms.txt Illustrates the setup and execution of an FMM solver for the Helmholtz kernel (exp(ikr)/r potential) with a complex wave number. This example includes creating sources with complex charges and performing the standard FMM passes. ```APIDOC ## HelmholtzFmm - Helmholtz Kernel ### Description Creates an FMM solver for the Helmholtz kernel (exp(ikr)/r potential) with complex wave number. ### Method N/A (C++ Example) ### Endpoint N/A (C++ Example) ### Parameters N/A ### Request Example ```cpp #include "helmholtz.h" #include "build_tree.h" #include "build_list.h" int main() { using exafmm_t::complex_t; // Create FMM instance with complex wave number int P = 8; int ncrit = 400; complex_t wavek(2.0, 4.0); // Wave number k = 2 + 4i exafmm_t::HelmholtzFmm fmm(P, ncrit, wavek); // Create sources with complex charges int nsources = 100000; exafmm_t::Bodies sources(nsources); std::random_device rd; std::mt19937 gen(rd()); std::uniform_real_distribution<> dist(-1.0, 1.0); for (int i = 0; i < nsources; i++) { sources[i].ibody = i; sources[i].q = complex_t(dist(gen), dist(gen)); // Complex charge for (int d = 0; d < 3; d++) sources[i].X[d] = dist(gen); } // Create targets int ntargets = 100000; exafmm_t::Bodies targets(ntargets); for (int i = 0; i < ntargets; i++) { targets[i].ibody = i; for (int d = 0; d < 3; d++) targets[i].X[d] = dist(gen); } // Build tree and evaluate (same pattern as Laplace) exafmm_t::get_bounds(sources, targets, fmm.x0, fmm.r0); exafmm_t::NodePtrs leafs, nonleafs; exafmm_t::Nodes nodes = exafmm_t::build_tree(sources, targets, leafs, nonleafs, fmm); exafmm_t::init_rel_coord(); exafmm_t::build_list(nodes, fmm); fmm.M2L_setup(nonleafs); fmm.precompute(); fmm.upward_pass(nodes, leafs); fmm.downward_pass(nodes, leafs); auto error = fmm.verify(leafs); std::cout << "Potential error: " << error[0] << std::endl; std::cout << "Gradient error: " << error[1] << std::endl; return 0; } ``` ### Response N/A (C++ Example) #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Install ExaFMM-t Dependencies on Ubuntu (Bash) Source: https://github.com/exafmm/exafmm-t/blob/master/docs/compile.rst Installs essential libraries for ExaFMM-t on Ubuntu systems, including OpenBLAS, FFTW3, and GFortran. These are required for compiling and running ExaFMM-t. ```bash $ apt-get update $ apt-get -y install libopenblas-dev libfftw3-dev gfortran ``` -------------------------------- ### Configure and Setup Modified Helmholtz FMM Source: https://github.com/exafmm/exafmm-t/blob/master/examples/python/modified_helmholtz.ipynb Instantiates the FMM solver with specific parameters and builds the tree structure and interaction lists. ```python fmm = mod_helm.ModifiedHelmholtzFmm(p=10, ncrit=400, wavek=7.5, filename='modhelm_example.dat') tree = mod_helm.setup(sources, targets, fmm) ``` -------------------------------- ### Configure and Setup Helmholtz FMM Source: https://github.com/exafmm/exafmm-t/blob/master/examples/python/helmholtz.ipynb Creates a HelmholtzFmm instance with specific parameters and builds the tree structure and interaction lists required for computation. ```python fmm = helmholtz.HelmholtzFmm(p=10, ncrit=300, wavek=10, filename='helmholtz_example_k10.dat') tree = helmholtz.setup(sources, targets, fmm) ``` -------------------------------- ### C++ FMM List Construction and Setup Source: https://github.com/exafmm/exafmm-t/blob/master/docs/examples.rst Prepares the FMM operators by initializing relative coordinates, setting up colleague nodes, and building interaction lists in C++. It also performs an extra setup for the M2L (Multipole-to-Local) operator. ```cpp exafmm_t::init_rel_coord(); // compute all possible relative positions of nodes for each FMM operator exafmm_t::set_colleagues(nodes); // find colleague nodes exafmm_t::build_list(nodes, fmm); // create list for each FMM operator fmm.M2L_setup(nonleafs); // an extra setup for M2L operator ``` -------------------------------- ### Initialize and Execute Laplace Kernel FMM Source: https://context7.com/exafmm/exafmm-t/llms.txt Demonstrates the setup and execution of an FMM solver for the 1/r Laplace potential. It covers tree construction, interaction list generation, and the evaluation of potential and gradient errors. ```cpp #include "laplace.h" #include "build_tree.h" #include "build_list.h" int main() { int P = 8; int ncrit = 400; exafmm_t::LaplaceFmm fmm(P, ncrit); exafmm_t::Bodies sources(100000); exafmm_t::Bodies targets(100000); exafmm_t::get_bounds(sources, targets, fmm.x0, fmm.r0); exafmm_t::NodePtrs leafs, nonleafs; exafmm_t::Nodes nodes = exafmm_t::build_tree(sources, targets, leafs, nonleafs, fmm); exafmm_t::init_rel_coord(); exafmm_t::build_list(nodes, fmm); fmm.M2L_setup(nonleafs); fmm.precompute(); fmm.upward_pass(nodes, leafs); fmm.downward_pass(nodes, leafs); std::vector error = fmm.verify(leafs); std::cout << "Potential error: " << error[0] << std::endl; std::cout << "Gradient error: " << error[1] << std::endl; return 0; } ``` -------------------------------- ### Initialize and Execute Yukawa Kernel FMM Source: https://context7.com/exafmm/exafmm-t/llms.txt Provides an example of setting up an FMM solver for the modified Helmholtz (Yukawa) kernel (exp(-kr)/r) with a real wave number. ```cpp #include "modified_helmholtz.h" #include "build_tree.h" #include "build_list.h" int main() { int P = 8; int ncrit = 400; exafmm_t::real_t wavek = 5.0; exafmm_t::ModifiedHelmholtzFmm fmm(P, ncrit, wavek); exafmm_t::Bodies sources(100000); exafmm_t::Bodies targets(100000); exafmm_t::get_bounds(sources, targets, fmm.x0, fmm.r0); exafmm_t::NodePtrs leafs, nonleafs; exafmm_t::Nodes nodes = exafmm_t::build_tree(sources, targets, leafs, nonleafs, fmm); exafmm_t::init_rel_coord(); exafmm_t::build_list(nodes, fmm); fmm.M2L_setup(nonleafs); fmm.precompute(); fmm.upward_pass(nodes, leafs); fmm.downward_pass(nodes, leafs); return 0; } ``` -------------------------------- ### Laplace Kernel FMM in Python Source: https://context7.com/exafmm/exafmm-t/llms.txt Demonstrates the simplified Python API for the Laplace kernel, including initialization, setup, evaluation, and verification. ```python import numpy as np import exafmm.laplace as laplace # 1. Create sources and targets nsrcs = 100000 ntrgs = 200000 src_coords = np.random.random((nsrcs, 3)) trg_coords = np.random.random((ntrgs, 3)) src_charges = np.random.random(nsrcs) sources = laplace.init_sources(src_coords, src_charges) targets = laplace.init_targets(trg_coords) # 2. Create FMM instance fmm = laplace.LaplaceFmm(p=10, ncrit=200, filename="laplace_p10.dat") # 3. Setup FMM (builds tree, lists, precomputes matrices) tree = laplace.setup(sources, targets, fmm) # 4. Evaluate potentials and gradients trg_values = laplace.evaluate(tree, fmm, verbose=True) # trg_values is (ntrgs, 4) array: [potential, grad_x, grad_y, grad_z] print(f"Potential at target 0: {trg_values[0, 0]}") print(f"Gradient at target 0: {trg_values[0, 1:4]}") # 5. Verify accuracy error = fmm.verify(tree.leafs) print(f"Potential error (L2): {error[0]}") print(f"Gradient error (L2): {error[1]}") ``` -------------------------------- ### Install ExaFMM-t Python Package (Bash) Source: https://github.com/exafmm/exafmm-t/blob/master/docs/compile.rst Installs the ExaFMM-t Python package using pip. This requires pre-installed dependencies, including OpenBLAS, and utilizes pybind11 for Python bindings. ```bash $ pip install git+https://github.com/exafmm/exafmm-t.git ``` -------------------------------- ### Configure and Build ExaFMM-t (Bash) Source: https://github.com/exafmm/exafmm-t/blob/master/docs/compile.rst Configures the ExaFMM-t build system using autotools, compiles the library, and optionally installs headers. This process is for users integrating ExaFMM-t into C++ applications. ```bash $ cd exafmm-t $ ./configure $ make check $ make install ``` -------------------------------- ### C++ Example: Laplace N-body Problem Source: https://github.com/exafmm/exafmm-t/blob/master/docs/examples.rst Demonstrates how to solve a Laplace N-body problem using the ExaFMM-t C++ API. This includes setting up sources and targets, initializing the FMM class, building and balancing the octree, and performing upward and downward passes for potential and gradient evaluation. ```APIDOC ## C++ Example: Laplace N-body Problem ### Description This example demonstrates the core workflow of using ExaFMM-t in C++ to solve an N-body problem for the Laplace kernel. It covers the initialization of sources and targets, FMM setup, octree construction and balancing, and the final potential and gradient evaluation. ### Method N/A (Illustrative C++ Code) ### Endpoint N/A (Local C++ Execution) ### Parameters N/A (Code-based configuration) ### Request Example ```cpp // Initialization of sources and targets using exafmm_t::real_t; std::random_device rd; std::mt19937 gen(rd()); // random number generator std::uniform_real_distribution<> dist(-1.0, 1.0); int ntargets = 100000; int nsources = 100000; exafmm_t::Bodies sources(nsources); for (int i=0; i targets(ntargets); for (int i=0; i leafs, nonleafs; exafmm_t::Nodes nodes = exafmm_t::build_tree(sources, targets, leafs, nonleafs, fmm); exafmm_t::balance_tree(nodes, sources, targets, leafs, nonleafs, fmm); // List construction and pre-computation exafmm_t::init_rel_coord(); // compute all possible relative positions of nodes for each FMM operator exafmm_t::set_colleagues(nodes); // find colleague nodes exafmm_t::build_list(nodes, fmm); // create list for each FMM operator fmm.M2L_setup(nonleafs); // an extra setup for M2L operator // FMM evaluation fmm.upward_pass(nodes, leafs); fmm.downward_pass(nodes, leafs); // Verification std::vector error = fmm.verify(leafs); std::cout << "potential error: " << error[0] << "\n" << "gradient error: " << error[1] << "\n"; ``` ### Response N/A (Console Output) ### Response Example ``` potential error: [some_value] gradient error: [some_value] ``` ``` -------------------------------- ### ModifiedHelmholtzFmm - Yukawa Kernel Source: https://context7.com/exafmm/exafmm-t/llms.txt Shows how to set up and use an FMM solver for the modified Helmholtz/Yukawa kernel (exp(-kr)/r potential) with a real wave number. The example follows a similar structure to the Laplace kernel example. ```APIDOC ## ModifiedHelmholtzFmm - Yukawa Kernel ### Description Creates an FMM solver for the modified Helmholtz/Yukawa kernel (exp(-kr)/r potential). ### Method N/A (C++ Example) ### Endpoint N/A (C++ Example) ### Parameters N/A ### Request Example ```cpp #include "modified_helmholtz.h" #include "build_tree.h" #include "build_list.h" int main() { // Create FMM instance with real wave number int P = 8; int ncrit = 400; exafmm_t::real_t wavek = 5.0; // Wave number k (real) exafmm_t::ModifiedHelmholtzFmm fmm(P, ncrit, wavek); // Create sources and targets (real-valued, same as Laplace) exafmm_t::Bodies sources(100000); exafmm_t::Bodies targets(100000); // ... populate sources and targets ... // Build tree and evaluate (same pattern as Laplace) exafmm_t::get_bounds(sources, targets, fmm.x0, fmm.r0); exafmm_t::NodePtrs leafs, nonleafs; exafmm_t::Nodes nodes = exafmm_t::build_tree(sources, targets, leafs, nonleafs, fmm); exafmm_t::init_rel_coord(); exafmm_t::build_list(nodes, fmm); fmm.M2L_setup(nonleafs); fmm.precompute(); fmm.upward_pass(nodes, leafs); fmm.downward_pass(nodes, leafs); return 0; } ``` ### Response N/A (C++ Example) #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### LaplaceFmm - Laplace Kernel Source: https://context7.com/exafmm/exafmm-t/llms.txt Demonstrates the creation and usage of an FMM solver for the Laplace kernel (1/r potential). Includes steps for FMM instance creation, body population, tree building, interaction list generation, M2L setup, precomputation, upward and downward passes, and accuracy verification. ```APIDOC ## LaplaceFmm - Laplace Kernel ### Description Creates an FMM solver for the Laplace kernel (1/r potential). ### Method N/A (C++ Example) ### Endpoint N/A (C++ Example) ### Parameters N/A ### Request Example ```cpp #include "laplace.h" #include "build_tree.h" #include "build_list.h" int main() { // Create FMM instance int P = 8; // Expansion order (controls accuracy) int ncrit = 400; // Max bodies per leaf (controls tree depth) exafmm_t::LaplaceFmm fmm(P, ncrit); // Optional: specify precomputation file // exafmm_t::LaplaceFmm fmm(P, ncrit, "laplace_d_p8.dat"); // Create sources and targets (see Body example above) exafmm_t::Bodies sources(100000); exafmm_t::Bodies targets(100000); // ... populate sources and targets ... // Get bounding box and build tree exafmm_t::get_bounds(sources, targets, fmm.x0, fmm.r0); exafmm_t::NodePtrs leafs, nonleafs; exafmm_t::Nodes nodes = exafmm_t::build_tree(sources, targets, leafs, nonleafs, fmm); // Build interaction lists and precompute matrices exafmm_t::init_rel_coord(); exafmm_t::build_list(nodes, fmm); fmm.M2L_setup(nonleafs); fmm.precompute(); // Evaluate FMM fmm.upward_pass(nodes, leafs); fmm.downward_pass(nodes, leafs); // Verify accuracy (returns [potential_error, gradient_error] in L2 norm) std::vector error = fmm.verify(leafs); std::cout << "Potential error: " << error[0] << std::endl; std::cout << "Gradient error: " << error[1] << std::endl; return 0; } ``` ### Response N/A (C++ Example) #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Python ExaFMM High-Level API Usage Source: https://github.com/exafmm/exafmm-t/blob/master/docs/examples.rst Demonstrates the high-level Python interface for ExaFMM. It shows how tree construction, list construction, and pre-computation are merged into a single `setup()` function, and evaluation is done via `evaluate()`. ```python # Example usage (conceptual, actual code in notebooks): # import exafmm # # # Initialize FMM for a specific kernel (e.g., Laplace) # fmm = exafmm.laplace.LaplaceFmm() # # # Setup the FMM (tree construction, list building, etc.) # fmm.setup(sources, targets) # # # Evaluate potentials and gradients # fmm.evaluate() # # # Access results (e.g., from targets) # potentials = [t.p for t in targets] # gradients = [t.F for t in targets] ``` -------------------------------- ### C++ Laplace N-body Problem Setup Source: https://github.com/exafmm/exafmm-t/blob/master/docs/examples.rst Sets up sources and targets for a Laplace N-body problem in C++. It initializes random bodies with charges and locations within a specified cube. Dependencies include standard C++ libraries for random number generation and STL containers. ```cpp using exafmm_t::real_t; std::random_device rd; std::mt19937 gen(rd()); // random number generator std::uniform_real_distribution<> dist(-1.0, 1.0); int ntargets = 100000; int nsources = 100000; exafmm_t::Bodies sources(nsources); for (int i=0; i targets(ntargets); for (int i=0; i sources(nsources); std::random_device rd; std::mt19937 gen(rd()); std::uniform_real_distribution<> dist(-1.0, 1.0); for (int i = 0; i < nsources; i++) { sources[i].ibody = i; sources[i].q = dist(gen); for (int d = 0; d < 3; d++) sources[i].X[d] = dist(gen); } int ntargets = 100000; exafmm_t::Bodies targets(ntargets); for (int i = 0; i < ntargets; i++) { targets[i].ibody = i; for (int d = 0; d < 3; d++) targets[i].X[d] = dist(gen); } ``` -------------------------------- ### Initialize Sources and Targets Source: https://github.com/exafmm/exafmm-t/blob/master/examples/python/laplace.ipynb Demonstrates how to initialize source and target bodies using numpy arrays for coordinates and charges. The init_sources and init_targets functions convert raw data into exafmm.laplace.Body objects. ```python import numpy as np import exafmm.laplace as laplace nsrcs = 100000 ntrgs = 200000 src_coords = np.random.random((nsrcs, 3)) trg_coords = np.random.random((ntrgs, 3)) src_charges = np.random.random(nsrcs) sources = laplace.init_sources(src_coords, src_charges) targets = laplace.init_targets(trg_coords) ``` -------------------------------- ### Initialize and Execute Helmholtz Kernel FMM Source: https://context7.com/exafmm/exafmm-t/llms.txt Shows how to configure an FMM solver for the Helmholtz kernel (exp(ikr)/r) using complex wave numbers and complex-valued source charges. ```cpp #include "helmholtz.h" #include "build_tree.h" #include "build_list.h" int main() { using exafmm_t::complex_t; int P = 8; int ncrit = 400; complex_t wavek(2.0, 4.0); exafmm_t::HelmholtzFmm fmm(P, ncrit, wavek); int nsources = 100000; exafmm_t::Bodies sources(nsources); // ... population logic ... exafmm_t::Bodies targets(100000); exafmm_t::get_bounds(sources, targets, fmm.x0, fmm.r0); exafmm_t::NodePtrs leafs, nonleafs; exafmm_t::Nodes nodes = exafmm_t::build_tree(sources, targets, leafs, nonleafs, fmm); exafmm_t::init_rel_coord(); exafmm_t::build_list(nodes, fmm); fmm.M2L_setup(nonleafs); fmm.precompute(); fmm.upward_pass(nodes, leafs); fmm.downward_pass(nodes, leafs); auto error = fmm.verify(leafs); return 0; } ``` -------------------------------- ### Initialize Sources and Targets for FMM Source: https://github.com/exafmm/exafmm-t/blob/master/examples/python/modified_helmholtz.ipynb Generates random particle coordinates and charges, then initializes them into the format required by the exafmm-t Modified Helmholtz module. ```python import numpy as np import exafmm.modified_helmholtz as mod_helm nsrcs = 100000 ntrgs = 100000 src_coords = np.random.random((nsrcs, 3)) trg_coords = np.random.random((nsrcs, 3)) src_charges = np.random.random(nsrcs) sources = mod_helm.init_sources(src_coords, src_charges) targets = mod_helm.init_targets(trg_coords) ``` -------------------------------- ### Create Interaction Lists in C++ Source: https://context7.com/exafmm/exafmm-t/llms.txt Constructs P2P, M2L, P2L, and M2P interaction lists for all nodes. Requires initialization of relative coordinates. ```cpp #include "build_list.h" // Initialize relative coordinates (must be called once before build_list) exafmm_t::init_rel_coord(); // Build interaction lists for all operators exafmm_t::build_list(nodes, fmm); // Setup M2L operator (required after build_list) fmm.M2L_setup(nonleafs); ``` -------------------------------- ### Initialize Sources and Targets Source: https://github.com/exafmm/exafmm-t/blob/master/examples/python/helmholtz.ipynb Generates random coordinates and complex charges for source particles and random coordinates for target particles, then initializes them using the Helmholtz module. ```python import numpy as np import exafmm.helmholtz as helmholtz nsrcs = 100000 ntrgs = 200000 src_coords = np.random.random((nsrcs, 3)) trg_coords = np.random.random((nsrcs, 3)) src_charges = np.zeros(nsrcs, dtype=np.complex_) src_charges.real = np.random.random(nsrcs) src_charges.imag = np.random.random(nsrcs) sources = helmholtz.init_sources(src_coords, src_charges) targets = helmholtz.init_targets(trg_coords) ``` -------------------------------- ### Verify Accuracy and Iterative Execution Source: https://github.com/exafmm/exafmm-t/blob/master/examples/python/laplace.ipynb Demonstrates how to verify FMM results against direct methods and perform iterative updates to source charges within the existing tree structure. ```python fmm.verify(tree.leafs) # Iterative update example niters = 5 for i in range(niters): src_charges = np.random.random(nsrcs) laplace.update_charges(tree, src_charges) laplace.clear_values(tree) trg_values = laplace.evaluate(tree, fmm) print("Error: ", fmm.verify(tree.leafs)) ``` -------------------------------- ### Iterative FMM Execution Source: https://github.com/exafmm/exafmm-t/blob/master/examples/python/helmholtz.ipynb Demonstrates how to update source charges, clear previous values, and re-evaluate the FMM iteratively for dynamic simulations. ```python for i in range(4): src_charges.real = np.random.random(nsrcs) src_charges.imag = np.random.random(nsrcs) helmholtz.update_charges(tree, src_charges) helmholtz.clear_values(tree) trg_values = helmholtz.evaluate(tree, fmm) print("Error: ", fmm.verify(tree.leafs)) ``` -------------------------------- ### Construct Adaptive Octree in C++ Source: https://context7.com/exafmm/exafmm-t/llms.txt Builds an adaptive octree based on particle distribution. Particles are sorted by Hilbert index, and the function returns node pointers. ```cpp #include "build_tree.h" // After calling get_bounds and creating fmm instance exafmm_t::NodePtrs leafs; // Output: pointers to leaf nodes exafmm_t::NodePtrs nonleafs; // Output: pointers to non-leaf nodes // Build tree - particles are sorted by Hilbert index exafmm_t::Nodes nodes = exafmm_t::build_tree(sources, targets, leafs, nonleafs, fmm); // Tree depth is stored in fmm.depth after build_tree completes std::cout << "Tree depth: " << fmm.depth << std::endl; std::cout << "Number of leaf nodes: " << leafs.size() << std::endl; std::cout << "Number of non-leaf nodes: " << nonleafs.size() << std::endl; ``` -------------------------------- ### Iterative FMM Evaluation with Charge Updates Source: https://context7.com/exafmm/exafmm-t/llms.txt Demonstrates how to perform multiple iterations of FMM evaluation by updating charges on an existing tree structure. This avoids the overhead of rebuilding the tree for every time step or iteration. ```python for iteration in range(5): new_charges = np.random.random(nsrcs) laplace.update_charges(tree, new_charges) laplace.clear_values(tree) trg_values = laplace.evaluate(tree, fmm) print(f"Iteration {iteration}: error = {fmm.verify(tree.leafs)}") ``` -------------------------------- ### Tree Construction Functions Source: https://context7.com/exafmm/exafmm-t/llms.txt Provides an overview of the tree construction functions used within ExaFMM, which are essential for organizing sources and targets for FMM computations. ```APIDOC ## Tree Construction Functions ### Description Functions for building the octree structure required for FMM computations. ### Method N/A (C++ Example) ### Endpoint N/A (C++ Example) ### Parameters N/A ### Request Example ```cpp // Example usage within FMM solvers (see kernel examples above) // exafmm_t::build_tree(sources, targets, leafs, nonleafs, fmm); ``` ### Response N/A (C++ Example) #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Iterative FMM Charge Updates Source: https://github.com/exafmm/exafmm-t/blob/master/examples/python/modified_helmholtz.ipynb Demonstrates how to update source charges within an existing tree structure and re-evaluate the FMM without rebuilding the entire tree. ```python niters = 4 for i in range(niters): src_charges = np.random.random(nsrcs) mod_helm.update_charges(tree, src_charges) mod_helm.clear_values(tree) trg_values = mod_helm.evaluate(tree, fmm) print("Error: ", fmm.verify(tree.leafs)) ``` -------------------------------- ### C++ Octree Construction and Balancing Source: https://github.com/exafmm/exafmm-t/blob/master/docs/examples.rst Builds and balances the octree for FMM calculations in C++. It first determines the spatial bounds, then constructs the tree, and finally balances it by distributing bodies among leaf nodes. Dependencies include `get_bounds`, `build_tree`, and `balance_tree` functions from the exafmm_t library. ```cpp exafmm_t::get_bounds(sources, targets, fmm.x0, fmm.r0); exafmm_t::NodePtrs leafs, nonleafs; exafmm_t::Nodes nodes = exafmm_t::build_tree(sources, targets, leafs, nonleafs, fmm); exafmm_t::balance_tree(nodes, sources, targets, leafs, nonleafs, fmm); ``` -------------------------------- ### C++ Laplace FMM Instance Creation Source: https://github.com/exafmm/exafmm-t/blob/master/docs/examples.rst Creates an FMM instance for the Laplace kernel in C++. It configures the expansion order (P) and the maximum number of bodies per leaf node (ncrit) to control accuracy and workload balance. ```cpp int P = 8; // expansion order int ncrit = 400; // max number of bodies per leaf exafmm_t::LaplaceFmm fmm(P, ncrit); ``` -------------------------------- ### Access Node Properties in C++ Source: https://context7.com/exafmm/exafmm-t/llms.txt Shows how to access spatial properties, particle counts, and expansion data from an octree node after the tree has been constructed. ```cpp #include "exafmm_t.h" exafmm_t::Node* node; exafmm_t::vec3 center = node->x; exafmm_t::real_t radius = node->r; int level = node->level; bool is_leaf = node->is_leaf; int num_sources = node->nsrcs; int num_targets = node->ntrgs; std::vector& up_equiv = node->up_equiv; std::vector& dn_equiv = node->dn_equiv; std::vector& trg_value = node->trg_value; ``` -------------------------------- ### Evaluate Potentials and Verify Accuracy Source: https://github.com/exafmm/exafmm-t/blob/master/examples/python/helmholtz.ipynb Computes the potential and gradient values for targets and verifies the accuracy of the FMM results against direct calculation methods. ```python trg_values = helmholtz.evaluate(tree, fmm) accuracy = fmm.verify(tree.leafs) ``` -------------------------------- ### Evaluation and Verification Source: https://github.com/exafmm/exafmm-t/blob/master/examples/python/laplace.ipynb Methods for executing the FMM evaluation and verifying the accuracy of the results. ```APIDOC ## POST /evaluate ### Description Triggers the FMM evaluation and returns potential and gradient values. ### Parameters #### Request Body - **tree** (Tree) - Required - The octree structure. - **fmm** (LaplaceFmm) - Required - The FMM configuration instance. - **verbose** (bool) - Optional - If true, displays timing information. ### Response #### Success Response (200) - **trg_values** (numpy.ndarray) - Array of shape (ntrgs, 4) containing potential and gradient values. ## POST /verify ### Description Calculates the L2-norm relative error of potential and gradient compared to direct methods. ### Parameters #### Request Body - **leafs** (list) - Required - The leaf nodes of the tree. ``` -------------------------------- ### Evaluate FMM Potentials and Gradients Source: https://github.com/exafmm/exafmm-t/blob/master/examples/python/modified_helmholtz.ipynb Triggers the FMM evaluation process to compute potentials and gradients at target positions, returning a numpy array. ```python trg_values = mod_helm.evaluate(tree, fmm) ``` -------------------------------- ### Modified Helmholtz Kernel Evaluation (Yukawa Potential) Source: https://context7.com/exafmm/exafmm-t/llms.txt Demonstrates the usage of the Modified Helmholtz kernel for real wave numbers, commonly used for screened Coulomb interactions in computational chemistry. ```python import numpy as np import exafmm.modified_helmholtz as mod_helmholtz nsrcs = 100000 src_coords = np.random.random((nsrcs, 3)) trg_coords = np.random.random((nsrcs, 3)) src_charges = np.random.random(nsrcs) sources = mod_helmholtz.init_sources(src_coords, src_charges) targets = mod_helmholtz.init_targets(trg_coords) fmm = mod_helmholtz.ModifiedHelmholtzFmm(p=10, ncrit=300, wavek=5.0) tree = mod_helmholtz.setup(sources, targets, fmm) trg_values = mod_helmholtz.evaluate(tree, fmm) print(f"Error: {fmm.verify(tree.leafs)}") ``` -------------------------------- ### Verify FMM Accuracy in C++ Source: https://context7.com/exafmm/exafmm-t/llms.txt Computes relative L2 error by comparing FMM results with direct summation. Samples leaf nodes to estimate potential and gradient accuracy. ```cpp // Verify accuracy (samples 10 leaf nodes by default) std::vector error = fmm.verify(leafs, true); std::cout << "Potential error (L2): " << error[0] << std::endl; std::cout << "Gradient error (L2): " << error[1] << std::endl; ``` -------------------------------- ### Perform Upward and Downward FMM Passes in C++ Source: https://context7.com/exafmm/exafmm-t/llms.txt Executes the upward pass for multipole expansions and the downward pass for local expansions and target potentials. ```cpp // Compute upward equivalent charges for all nodes // verbose=true prints timing information fmm.upward_pass(nodes, leafs, true); // Compute potentials and gradients for all targets fmm.downward_pass(nodes, leafs, true); ``` -------------------------------- ### Compute Bounding Box in C++ Source: https://context7.com/exafmm/exafmm-t/llms.txt Computes the bounding box that encloses all sources and targets. It outputs the center and half-side length of the box. ```cpp #include "build_tree.h" exafmm_t::Bodies sources, targets; // ... populate sources and targets ... exafmm_t::vec3 x0; // Center of bounding box (output) exafmm_t::real_t r0; // Half-side length of bounding box (output) exafmm_t::get_bounds(sources, targets, x0, r0); std::cout << "Bounding box center: [" << x0[0] << ", " << x0[1] << ", " << x0[2] << "]" << std::endl; std::cout << "Bounding box radius: " << r0 << std::endl; ``` -------------------------------- ### Extract Results from Leaf Nodes in C++ Source: https://context7.com/exafmm/exafmm-t/llms.txt Extracts potentials and gradients from leaf nodes back into the original particle order using stored target indices. ```cpp // Extract potentials and gradients in original target order int ntargets = targets.size(); std::vector potential(ntargets); std::vector gradient_x(ntargets); std::vector gradient_y(ntargets); std::vector gradient_z(ntargets); for (size_t i = 0; i < leafs.size(); ++i) { exafmm_t::Node* leaf = leafs[i]; std::vector& itrgs = leaf->itrgs; // Original target indices for (size_t j = 0; j < itrgs.size(); ++j) { potential[itrgs[j]] = leaf->trg_value[4*j + 0]; gradient_x[itrgs[j]] = leaf->trg_value[4*j + 1]; gradient_y[itrgs[j]] = leaf->trg_value[4*j + 2]; gradient_z[itrgs[j]] = leaf->trg_value[4*j + 3]; } } ``` -------------------------------- ### Verify FMM Accuracy Source: https://github.com/exafmm/exafmm-t/blob/master/examples/python/modified_helmholtz.ipynb Calculates the L2-norm relative error for potentials and gradients compared to direct summation, provided skip_P2P is False. ```python error = fmm.verify(tree.leafs) ```