Skip to content

Commit

Permalink
Merge pull request #12461 from KratosMultiphysics/doc/initial-search-doc
Browse files Browse the repository at this point in the history
[Doc] Initial search documentation
  • Loading branch information
loumalouomega authored Jun 20, 2024
2 parents 1fcc8b5 + 6f63abf commit c6cfb31
Show file tree
Hide file tree
Showing 10 changed files with 599 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
---
title: SpatialSearchResult
keywords: search spatial_container core
tags: [search spatial_container]
sidebar: kratos_core_search
summary: Class result of the spatial searches.
---

# Spatial Search Result

## Description

This class is the result of the spatial searches. It provides:
- A global pointer to the object found.
- Distance to the object if `IsDistanceCalculated()` is true
- IsObjectFound if for example search nearest fails or not

This class is essential for applications involving spatial queries where it is crucial to not only find an object but also to know the distance to the object and handle cases where the search may fail. The use of `GlobalPointer` allows the system to work efficiently in a distributed environment, making it highly suitable for large-scale simulations handled by *Kratos*.

By abstracting the result of spatial searches into a dedicated class, *Kratos* provides a clean and reusable interface that enhances code maintainability and readability. This approach is beneficial in multi-physics simulations where different types of data and interactions need to be managed coherently.

See [Spatial Search Result Container](spatial_search_result_container) and [Spatial Search Result Container Vector](spatial_search_result_container_vector).

## Implementation

Can be found in [`spatial_search_result.h`](https://github.com/KratosMultiphysics/Kratos/blob/master/kratos/spatial_containers/spatial_search_result.h).

### Class: `SpatialSearchResult`
A template class designed to handle the results of spatial searches. The class is templated so it can handle to hold any kind of object.

#### Constructors
- **Default Constructor**: Initializes member variables to represent an unsuccessful search.
- **Parameterized Constructor**: Accepts a pointer to `TObjectType` and initializes based on whether the object exists. Default rank is zero, assuming a serial set up.

#### Operations
- **`Reset`**: Resets the search result to its initial state, indicating no object found and no distance calculated.

#### Accessors
- **Getters and Setters**: For accessing and modifying the object, its distance, and status flags (object found, distance calculated).

#### Inquiry
- **Status Checks**: Methods to check if the object was found and if the distance was calculated.

### Python exposition

Here’s a detailed explanation of how the C++ class `SpatialSearchResult` is exposed to Python:

#### Class specialization

Here's a breakdown of the objects that are specialized and their names as exposed in Python:

1. **Node** - This is specialized for spatial search and is exposed in Python as `"SpatialSearchResultNode"`.
2. **GeometricalObject** - This is another specialization for spatial search results and is exposed in Python as `"SpatialSearchResultGeometricalObject"`.
3. **Element** - Specialized for spatial search results concerning elements, and it is exposed in Python as `"SpatialSearchResultElement"`.
4. **Condition** - This type is also specialized for spatial search results, specifically for conditions, and is exposed in Python as `"SpatialSearchResultCondition"`.

#### Member functions
- `Reset`: Binds the `Reset` method that resets the internal state of the search result.
- `Get`: Binds the `Get` method, which returns the object stored in the result.
- `Set`: Binds the `Set` method to set the object in the result.
- `GetDistance`: Binds the `GetDistance` method to retrieve the distance at which the object was found.
- `SetDistance`: Binds the `SetDistance` method to set the distance.
- `IsObjectFound`: Binds a method to check if an object was found in the search.
- `IsDistanceCalculated`: Binds a method to check if the distance has been calculated.

## Example usage

### Python

~~~python
import KratosMultiphysics as KM

# Create a new SpatialSearchResult for a specific type, say Node
result = KM.SpatialSearchResultNode()

# Use the methods bound to the SpatialSearchResultNode class
result.Set(node_pointer) # Set a node
print(result.Get()) # Get the node
print(result.GetDistance()) # Get the distance
result.SetDistance(10.0) # Set the distance
print(result.IsObjectFound()) # Check if the object was found
print(result.IsDistanceCalculated()) # Check if the distance was calculated
~~~
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
title: BinsDynamic
keywords: search spatial_container core
tags: [search spatial_container]
sidebar: kratos_core_search
summary: A dynamic binning data structure template for organizing and querying points in multi-dimensional space.
---

# Bins Dynamic

## Description

The `BinsDynamic` class template provides a dynamic binning data structure for organizing and querying points in a multi-dimensional space. It is parameterized by the dimension of the space, the point type, the container type for storing points, and other optional template parameters for specifying point iterators, distance iterators, and distance functions.

This class inherits from `TreeNode` to leverage common functionalities for tree-based data structures.

Also see [Bins (static)](bins_static) and [Geometrical Object Bins](geometrical_object_bins).

## Implementation

Can be found in [`bins_dynamic.h`](https://github.com/KratosMultiphysics/Kratos/blob/master/kratos/spatial_containers/bins_dynamic.h).

Derives from [`Tree`](tree.md) and [`TreeNode`](tree.md) class.

### Template arguments

- `TDimension`: The dimensionality of the space.
- `TPointType`: The type representing points in the space.
- `TContainerType`: The container type for storing points.
- `TPointerType`: The type of pointers or iterators to points in the container (default is inferred from `TContainerType`).
- `TIteratorType`: The type of iterators for traversing the container (default is inferred from `TContainerType`).
- `TDistanceIteratorType`: The type of iterators for storing distance values (default is `std::vector<double>::iterator`).
- `TDistanceFunction`: The type of the distance function used for querying (default is `Kratos::SearchUtils::SquaredDistanceFunction`).

### Search methods

- `SearchInRadius`: Iterates through potential cells based on the query point and radius, checking each object within these cells to gather those within the specified radius.
- `SearchInBox`: Iterates through potential cells based on the query point and bounding box points, checking each object within these cells to gather those within the specified bounding box.
- `SearchNearestPoint`: Focuses on finding the nearest object independently of the distance.

## Example usage

### C++

The following example of use for a simple case:

~~~c++
// Defining the point type for the search
using NodesContainerType = ModelPart::NodesContainerType;
using ResultNodesContainerType = NodesContainerType::ContainerType;
using VectorResultNodesContainerType = std::vector<ResultNodesContainerType>;
using PointType = PointObject<Node>;
using PointVector = std::vector<PointType::Pointer>;
using DistanceType = std::vector<double>;
using VectorDistanceType = std::vector<DistanceType>;

// Defining the PointVector
VectorResultNodesContainerType nodes_results;
VectorDistanceType result_distance;
PointVector points = SearchUtilities::PrepareSearch(rStructureNodes, rInputNodes, nodes_results, result_distance);

// Definitions
const int allocation_size = 1000;

/// BinsDynamic definitions
using DynamicBins = BinsDynamic<3ul, PointType, PointVector>;

// Creating the bins
DynamicBins dynamic_bins(points.begin(), points.end());

// Performing search
double radius = 1.0;
SearchUtilities::ParallelSearch(rInputNodes, radius, dynamic_bins, nodes_results, result_distance, allocation_size);
~~~
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
---
title: Bins
keywords: search spatial_container core
tags: [search spatial_container]
sidebar: kratos_core_search
summary: Class for searching and organizing spatial data using a binning technique.
---

# Bins (static)

## Description

The bins is deigned for searching and organizing spatial data using a binning technique. This technique refers to an approach where data is first grouped into bins or categories before the search is conducted. This method can be particularly useful for improving the efficiency of search processes in large datasets. The method is based on:

1. **Data segregation**: The data set is divided into multiple bins based on certain criteria, often the range of data values. Each bin contains data that falls within a specific interval.

2. **Efficient searching**: When a search query is issued, instead of searching the entire dataset, the algorithm first identifies the appropriate bin or bins where the search keys are likely to be found.

Also see [Bins Dynamic](bins_dynamic) and [Geometrical Object Bins](geometrical_object_bins).

## Implementation

Can be found in [`bins_static.h`](https://github.com/KratosMultiphysics/Kratos/blob/master/kratos/spatial_containers/bins_static.h).

Derives from [`Tree`](tree.md) and [`TreeNode`](tree.md) class.

### Template arguments

- `TDimension`: The dimensionality of the space.
- `TPointType`: The type representing points in the space.
- `TContainerType`: The container type for storing points.
- `TPointerType`: The type of pointers or iterators to points in the container (default is inferred from `TContainerType`).
- `TIteratorType`: The type of iterators for traversing the container (default is inferred from `TContainerType`).
- `TDistanceIteratorType`: The type of iterators for storing distance values (default is `std::vector<double>::iterator`).
- `TDistanceFunction`: The type of the distance function used for querying (default is `Kratos::SearchUtils::SquaredDistanceFunction`).

### Search methods

- `SearchInRadius`: Iterates through potential cells based on the query point and radius, checking each object within these cells to gather those within the specified radius.
- `SearchInBox`: Iterates through potential cells based on the query point and bounding box points, checking each object within these cells to gather those within the specified bounding box.
- `SearchNearestPoint`: Focuses on finding the nearest object independently of the distance.

## Example usage

### C++

The following example of use for a simple case:

~~~c++
// Defining the point type for the search
using NodesContainerType = ModelPart::NodesContainerType;
using ResultNodesContainerType = NodesContainerType::ContainerType;
using VectorResultNodesContainerType = std::vector<ResultNodesContainerType>;
using PointType = PointObject<Node>;
using PointVector = std::vector<PointType::Pointer>;
using DistanceType = std::vector<double>;
using VectorDistanceType = std::vector<DistanceType>;

// Defining the PointVector
VectorResultNodesContainerType nodes_results;
VectorDistanceType result_distance;
PointVector points = SearchUtilities::PrepareSearch(rStructureNodes, rInputNodes, nodes_results, result_distance);

// Definitions
const int allocation_size = 1000;
const int bucket_size = 1000;

/// StaticBins definitions
using StaticBinsTree = Tree<Bins<3ul, PointType, PointVector>>;

// Creating the tree
StaticBinsTree static_bins_tree(points.begin(), points.end(), bucket_size);

// Performing search
double radius = 1.0;
SearchUtilities::ParallelSearch(rInputNodes, radius, static_bins_tree, nodes_results, result_distance, allocation_size);
~~~
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
---
title: GeometricalObjectsBins
keywords: search spatial_container core
tags: [search spatial_container]
sidebar: kratos_core_search
summary: A bins container for 3 dimensional GeometricalObject entities.
---

# Geometrical Object Bins

## Description

It provides efficient search in radius and search nearest methods. All of the geometries should be given at construction time. After constructing the bins the geometries cannot be modified. In case of any modification, the bins should be reconstructed.

Also see [Bins Dynamic](bins_dynamic) and [Bins (static)](bins_static).

## Implementation

Can be found in [`geometrical_object_bins.h`](https://github.com/KratosMultiphysics/Kratos/blob/master/kratos/spatial_containers/geometrical_object_bins.h).

### Constructors

Initialize the bins with a range of geometrical objects, automatically calculating the bounding box and appropriate cell sizes based on the objects' spatial distribution.

### Search methods

- `SearchInRadius`: Iterates through potential cells based on the query point and radius, checking each object within these cells to gather those within the specified radius.
- `SearchNearestInRadius`: Similar to `SearchInRadius` but focuses on finding the nearest object within the given radius, optimizing the search by incrementally increasing the search radius until the nearest object is found or all cells are covered.
- `SearchNearest`: Focuses on finding the nearest object independently of the distance.
- `SearchIsInside`: Determines if a point is directly inside any geometrical object, which can be useful for point-inclusion tests.

### Python exposition

1. **Constructors**: The class provides several overloaded constructors to initialize the `GeometricalObjectsBins` with either an `ElementsContainerType` or a `ConditionsContainerType`. Optionally also taking a `double` which represent a tolerance.

2. **Member functions**:

- `GetBoundingBox`: Exposed to retrieve the bounding box of the geometrical objects.
- `GetCellSizes`: Exposed to get the sizes of cells in the bins.
- `GetNumberOfCells`: Returns the number of cells.
- `GetTotalNumberOfCells`: Returns the total number of cells in all dimensions.

3. **Search functions**:

- `SearchInRadius`: Two overloaded versions are exposed. One takes a single point and a radius, performing a search within that radius and returning the results in a Python list. The other version accepts a container of nodes and a radius, returning a nested list where each sublist corresponds to the results for a particular node.
- `SearchNearestInRadius`: Similar to `SearchInRadius`, but presumably returns only the nearest object within the specified radius. It is also overloaded for single points and node containers.
- `SearchNearest`: Exposed for searching the nearest geometrical object to a point or each point in a container of nodes.
- `SearchIsInside`: Determines whether a point or nodes in a container are inside the geometric area defined by the geometrical objects.

Each search function captures lambda functions which interact with the `GeometricalObjectsBins` instance methods to perform searches, process results, and return them in a Python-friendly format using `py::list`.

## Example usage

### C++

The following is an example how to use it in C++ for example search all the results available in a given radius.

~~~c++
// Generate the cube skin
// Here, we create a skin model part of a cube using the utility function `CreateCubeSkinModelPart`.
// This function takes a reference to the current model and returns a reference to the newly created 'ModelPart'.
ModelPart& r_skin_part = CppTestsUtilities::CreateCubeSkinModelPart(current_model);

// Create bins for spatial search
// This line initializes an object `bins` of type `GeometricalObjectsBins`. It is constructed using iterators
// that define a range over the elements in 'r_skin_part'. This allows performing spatial searches on these elements.
GeometricalObjectsBins bins(r_skin_part.ElementsBegin(), r_skin_part.ElementsEnd());

// Define a vector to store search results
// A vector `results` is defined to store the results from the spatial search.
// The type stored in the vector is `GeometricalObjectsBins::ResultType`.
std::vector<GeometricalObjectsBins::ResultType> results;

// Define the center point for the search
// A `Point` object `center_point` is defined with coordinates (0.0, 0.0, 0.0).
Point center_point{0.0, 0.0, 0.0};

// Perform a radius search
// This function call performs a search within a radius of 0.29 units around `center_point`.
// The results of the search are stored in the `results` vector.
bins.SearchInRadius(center_point, 0.3, results);
~~~
### Python
Here an example how to use it in python:
```py
# Importing the Kratos Library
import KratosMultiphysics as KM
# Create a model
model = KM.Model()
# Create a model part
model_part = model.CreateModelPart("SampleModelPart")
model_part.ProcessInfo[KM.DOMAIN_SIZE] = 3 # Define the spatial dimension
# Add variables that might be needed for the conditions
model_part.AddNodalSolutionStepVariable(KM.DISPLACEMENT)
# Create nodes
model_part.CreateNewNode(1, 0.0, 0.0, 0.0)
model_part.CreateNewNode(2, 1.0, 0.0, 0.0)
model_part.CreateNewNode(3, 0.0, 1.0, 0.0)
# Create a triangular condition (assuming 2D domain for simplicity)
prop = model_part.GetProperties()[1] # Default properties
model_part.CreateNewCondition("SurfaceCondition3D3N", 1, [1, 2, 3], prop)
# Example of using GeometricalObjectBins for searching conditions
# Initialize the search structure
search = KM.GeometricalObjectsBins(model_part.Conditions)
# Create a search node
search_node = KM.Node(4, 0.5, 0.1, 0.0)
# Search in radius
radius = 1.0
found_conditions = search.SearchInRadius(search_node, radius)
# Print found conditions
print("Conditions found in radius:", radius)
for cond in found_conditions:
print("Condition ID:", cond.Id)
```
Loading

0 comments on commit c6cfb31

Please sign in to comment.