Skip to content

Commit 98b1c4e

Browse files
authored
Merge pull request #896 from Xiangyu-Hu/xiangyu/unifed_kernel
Xiangyu/unified kernel
2 parents b0fcf15 + a8f9313 commit 98b1c4e

32 files changed

+645
-744
lines changed

README.md

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,24 @@
11
# ![SPHinXsys Logo](assets/logo.png) SPHinXsys
22

3-
## Heterogeneous parallelism for mesh dynamics and particle relaxation
4-
5-
It is known that SPHinXsys relies on level-set technique to realize
6-
particle generation and relaxation for later SPH simulations.
7-
The level-set field is build on a multi-level Cartesian mesh
8-
with sparse storage and adaptive mesh refinement (AMR).
9-
After the level-set field is constructed,
10-
the body-fitted initial particle distribution,
11-
especially for solid bodies,
12-
is obtained by a physical-driving relaxation process
13-
using level-set field for body-fitting.
14-
15-
Now, the level-set based operations or more generally mesh dynamics,
16-
such as small-feature cleaning, re-initialization
17-
and normal direction computing,
18-
and the particle relaxation process now can be carried on either CPU or GPU
19-
with the same numerical algorithm and the help of SYCL kernels.
20-
21-
The test utilizes heterogeneous parallelism for mesh dynamics have been added to the cases
22-
`test_2d_particle_generator_single_resolution_sycl`,`test_3d_particle_relaxation_single_resolution_sycl`
23-
and `taylor_bar_sycl` in `test/test_sycl` folder,
24-
25-
showcasing the capabilities of our specially designed framework.
3+
## SPHinXsys new feature: turning “mesh nightmares” into smooth simulations
4+
5+
Ever had a perfect-looking CAD model that refused to mesh?
6+
7+
Hidden leaks (those tiny yellow marks in the figure) can completely derail numerical simulations — and repairing them can be tedious and frustrating.
8+
9+
![Leaking Geometry](https://media.licdn.com/dms/image/v2/D4D22AQF5CCANH4NQgQ/feedshare-shrink_2048_1536/B4DZiQ_oVfHYAw-/0/1754779257657?e=1758153600&v=beta&t=ugXbUmTgQQ4s7bjkO_f-zY7Y5yIOsUzlE1-sobnqLWc)
10+
11+
With SPHinXsys level set techniques, you can skip the repair work.
12+
We directly convert your original (even leaky) geometry into particles, then apply a physics-based relaxation to produce a clean, body-fitted, and uniformly distributed particle set — ready for simulation.
13+
14+
![Levelset and Particles](https://media.licdn.com/dms/image/v2/D4D22AQFmcHYYO-ji2Q/feedshare-shrink_2048_1536/B4DZiQ_oWQGsAo-/0/1754779257939?e=1758153600&v=beta&t=_IWXfhpGhLDzw4ukFiOrrOJlOx3jtS6J48xk5J9pPC4)
15+
16+
No more chasing tiny gaps. Just upload your model and let the algorithm do the work.
17+
18+
You can check the test cases
19+
`test_3d_particle_relaxation_single_resolution_sycl`
20+
for different geometries in the `data` folder,
21+
which showcase the capabilities of our specially designed framework.
2622

2723
Your tests, comments and modification of these test cases would be very welcomed!
2824

src/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
file(GLOB_RECURSE SPHINXSYS_SHARED_HEADERS CONFIGURE_DEPENDS shared/*.h shared/*.hpp)
1+
file(GLOB_RECURSE SPHINXSYS_SHARED_HEADERS CONFIGURE_DEPENDS shared/*.h shared/*.hpp shared/*.hxx)
22
file(GLOB_RECURSE SPHINXSYS_SHARED_SOURCES CONFIGURE_DEPENDS shared/*.cpp)
33

44
if(SPHINXSYS_USE_SYCL)

src/for_2D_build/mesh_dynamics/mesh_local_dynamics.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ inline Real UpdateKernelIntegrals::UpdateKernel::
134134
Vecd displacement = -Arrayi(i, j).cast<Real>().matrix() * data_spacing_;
135135
Real distance = displacement.norm();
136136
if (distance < cutoff_radius_)
137-
integral += kernel_->W(global_h_ratio_, distance, displacement) *
137+
integral += kernel_.W(displacement) *
138138
CutCellVolumeFraction(phi_neighbor, phi_gradient, data_spacing_);
139139
}
140140
});
@@ -163,7 +163,7 @@ inline Vecd UpdateKernelIntegrals::UpdateKernel::
163163
Vecd displacement = -Arrayi(i, j).cast<Real>().matrix() * data_spacing_;
164164
Real distance = displacement.norm();
165165
if (distance < cutoff_radius_)
166-
integral += kernel_->dW(global_h_ratio_, distance, displacement) *
166+
integral += kernel_.dW(displacement) *
167167
CutCellVolumeFraction(phi_neighbor, phi_gradient, data_spacing_) *
168168
displacement / (distance + TinyReal);
169169
}
@@ -194,7 +194,7 @@ inline Matd UpdateKernelIntegrals::UpdateKernel::
194194
Vecd displacement = -Arrayi(i, j).cast<Real>().matrix() * data_spacing_;
195195
Real distance = displacement.norm();
196196
if (distance < cutoff_radius_)
197-
integral += kernel_->d2W(global_h_ratio_, distance, displacement) *
197+
integral += kernel_.d2W(displacement) *
198198
CutCellVolumeFraction(phi_neighbor, phi_gradient, data_spacing_) *
199199
displacement * displacement.transpose() / (distance * distance + TinyReal);
200200
}

src/for_2D_build/meshes/sparse_storage_mesh/mesh_with_data_packages.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef MESH_WITH_DATA_PACKAGES_2D_HPP
22
#define MESH_WITH_DATA_PACKAGES_2D_HPP
33

4-
#include "mesh_with_data_packages.h"
4+
#include "mesh_with_data_packages.hxx"
55

66
namespace SPH
77
{

src/for_3D_build/mesh_dynamics/mesh_local_dynamics.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ inline Real UpdateKernelIntegrals::UpdateKernel::
146146
Vecd displacement = -Arrayi(i, j, k).cast<Real>().matrix() * data_spacing_;
147147
Real distance = displacement.norm();
148148
if (distance < cutoff_radius_)
149-
integral += kernel_->W(global_h_ratio_, distance, displacement) *
149+
integral += kernel_.W(displacement) *
150150
CutCellVolumeFraction(phi_neighbor, phi_gradient, data_spacing_);
151151
}
152152
});
@@ -181,7 +181,7 @@ inline Vecd UpdateKernelIntegrals::UpdateKernel::
181181
Vecd displacement = -Arrayi(i, j, k).cast<Real>().matrix() * data_spacing_;
182182
Real distance = displacement.norm();
183183
if (distance < cutoff_radius_)
184-
integral += kernel_->dW(global_h_ratio_, distance, displacement) *
184+
integral += kernel_.dW(displacement) *
185185
CutCellVolumeFraction(phi_neighbor, phi_gradient, data_spacing_) *
186186
displacement / (distance + TinyReal);
187187
}
@@ -218,7 +218,7 @@ inline Matd UpdateKernelIntegrals::UpdateKernel::
218218
Vecd displacement = -Arrayi(i, j, k).cast<Real>().matrix() * data_spacing_;
219219
Real distance = displacement.norm();
220220
if (distance < cutoff_radius_)
221-
integral += kernel_->d2W(global_h_ratio_, distance, displacement) *
221+
integral += kernel_.d2W(displacement) *
222222
CutCellVolumeFraction(phi_neighbor, phi_gradient, data_spacing_) *
223223
displacement * displacement.transpose() / (distance * distance + TinyReal);
224224
}

src/for_3D_build/meshes/sparse_storage_mesh/mesh_with_data_packages.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef MESH_WITH_DATA_PACKAGES_3D_HPP
22
#define MESH_WITH_DATA_PACKAGES_3D_HPP
33

4-
#include "mesh_with_data_packages.h"
4+
#include "mesh_with_data_packages.hxx"
55

66
#include "block_cluster_3d.h"
77

src/shared/common/base_dynamics.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/* ------------------------------------------------------------------------- *
2+
* SPHinXsys *
3+
* ------------------------------------------------------------------------- *
4+
* SPHinXsys (pronunciation: s'finksis) is an acronym from Smoothed Particle *
5+
* Hydrodynamics for industrial compleX systems. It provides C++ APIs for *
6+
* physical accurate simulation and aims to model coupled industrial dynamic *
7+
* systems including fluid, solid, multi-body dynamics and beyond with SPH *
8+
* (smoothed particle hydrodynamics), a meshless computational method using *
9+
* particle discretization. *
10+
* *
11+
* SPHinXsys is partially funded by German Research Foundation *
12+
* (Deutsche Forschungsgemeinschaft) DFG HU1527/6-1, HU1527/10-1, *
13+
* HU1527/12-1 and HU1527/12-4. *
14+
* *
15+
* Portions copyright (c) 2017-2025 Technical University of Munich and *
16+
* the authors' affiliations. *
17+
* *
18+
* Licensed under the Apache License, Version 2.0 (the "License"); you may *
19+
* not use this file except in compliance with the License. You may obtain a *
20+
* copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
21+
* *
22+
* ------------------------------------------------------------------------- */
23+
/**
24+
* @file base_dynamics.h
25+
* @brief This is for the base classes of all dynamics.
26+
* @author Xiangyu Hu
27+
*/
28+
#ifndef BASE_DYNAMICS_H
29+
#define BASE_DYNAMICS_H
30+
31+
namespace SPH
32+
{
33+
template <class ReturnType = void>
34+
class BaseDynamics
35+
{
36+
public:
37+
BaseDynamics() : is_newly_updated_(false) {};
38+
virtual ~BaseDynamics() {};
39+
bool checkNewlyUpdated() { return is_newly_updated_; };
40+
void setNotNewlyUpdated() { is_newly_updated_ = false; };
41+
42+
template <class IdentifierType>
43+
void setUpdated(IdentifierType &identifier)
44+
{
45+
identifier.setNewlyUpdated();
46+
is_newly_updated_ = true;
47+
};
48+
49+
/** There is the interface functions for computing. */
50+
virtual ReturnType exec(Real dt = 0.0) = 0;
51+
52+
private:
53+
bool is_newly_updated_;
54+
};
55+
} // namespace SPH
56+
#endif // BASE_DYNAMICS_H

src/shared/geometries/level_set.cpp

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,43 +11,51 @@ MultilevelLevelSet::MultilevelLevelSet(
1111
Shape &shape, SPHAdaptation &sph_adaptation, Real refinement_ratio)
1212
: BaseMeshField("LevelSet_" + shape.getName()), shape_(shape), total_levels_(1)
1313
{
14-
Real reference_data_spacing = coarse_data->DataSpacing() * 0.5;
15-
Real global_h_ratio = sph_adaptation.ReferenceSpacing() / reference_data_spacing / refinement_ratio;
16-
kernel_ = makeUnique<SingularVariable<KernelTabulatedCK>>(
17-
"levelset_kernel", KernelTabulatedCK(*sph_adaptation.getKernel()));
14+
Real data_spacing = coarse_data->DataSpacing() * 0.5;
15+
Real global_h_ratio = sph_adaptation.ReferenceSpacing() / data_spacing / refinement_ratio;
16+
Real smoothing_length = sph_adaptation.ReferenceSmoothingLength() / global_h_ratio;
1817
global_h_ratio_vec_.push_back(global_h_ratio);
18+
neighbor_method_set_.push_back(
19+
neighbor_method_keeper_.template createPtr<NeighborMethod<SingleValued>>(
20+
*sph_adaptation.getKernel(), smoothing_length, data_spacing));
1921

20-
initializeLevel(reference_data_spacing, tentative_bounds, coarse_data);
22+
initializeLevel(data_spacing, tentative_bounds, coarse_data);
2123
}
2224
//=================================================================================================//
2325
MultilevelLevelSet::MultilevelLevelSet(
24-
BoundingBox tentative_bounds, Real reference_data_spacing,
26+
BoundingBox tentative_bounds, Real data_spacing,
2527
size_t total_levels, Shape &shape, SPHAdaptation &sph_adaptation, Real refinement_ratio)
2628
: BaseMeshField("LevelSet_" + shape.getName()), shape_(shape), total_levels_(total_levels)
2729
{
28-
Real global_h_ratio = sph_adaptation.ReferenceSpacing() / reference_data_spacing / refinement_ratio;
30+
Real global_h_ratio = sph_adaptation.ReferenceSpacing() / data_spacing / refinement_ratio;
31+
Real smoothing_length = sph_adaptation.ReferenceSmoothingLength() / global_h_ratio;
2932
global_h_ratio_vec_.push_back(global_h_ratio);
30-
kernel_ = makeUnique<SingularVariable<KernelTabulatedCK>>(
31-
"levelset_kernel", KernelTabulatedCK(*sph_adaptation.getKernel()));
33+
neighbor_method_set_.push_back(
34+
neighbor_method_keeper_.template createPtr<NeighborMethod<SingleValued>>(
35+
*sph_adaptation.getKernel(), smoothing_length, data_spacing));
3236

33-
initializeLevel(reference_data_spacing, tentative_bounds);
37+
initializeLevel(data_spacing, tentative_bounds);
3438
for (size_t level = 1; level < total_levels_; ++level)
3539
{
36-
reference_data_spacing *= 0.5; // Halve the data spacing
37-
global_h_ratio *= 2; // Double the ratio
40+
data_spacing *= 0.5; // Halve the data spacing
41+
global_h_ratio *= 2; // Double the ratio
42+
smoothing_length *= 0.5; // Halve the smoothing length
3843
global_h_ratio_vec_.push_back(global_h_ratio);
44+
neighbor_method_set_.push_back(
45+
neighbor_method_keeper_.template createPtr<NeighborMethod<SingleValued>>(
46+
*sph_adaptation.getKernel(), smoothing_length, data_spacing));
3947

40-
initializeLevel(reference_data_spacing, tentative_bounds, mesh_data_set_[level - 1]);
48+
initializeLevel(data_spacing, tentative_bounds, mesh_data_set_[level - 1]);
4149
}
4250
}
4351
//=================================================================================================//
4452
void MultilevelLevelSet::initializeLevel(
45-
Real reference_data_spacing, BoundingBox tentative_bounds, MeshWithGridDataPackagesType *coarse_data)
53+
Real data_spacing, BoundingBox tentative_bounds, MeshWithGridDataPackagesType *coarse_data)
4654
{
4755
MeshWithGridDataPackagesType *mesh_data =
4856
mesh_data_ptr_vector_keeper_
4957
.template createPtr<MeshWithGridDataPackagesType>(
50-
tentative_bounds, reference_data_spacing, 4);
58+
tentative_bounds, data_spacing, 4);
5159
mesh_data_set_.push_back(mesh_data);
5260

5361
if (coarse_data == nullptr)

src/shared/geometries/level_set.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -121,17 +121,18 @@ class MultilevelLevelSet : public BaseMeshField
121121
void initializeLevel(Real reference_data_spacing, BoundingBox tentative_bounds,
122122
MeshWithGridDataPackagesType *coarse_data = nullptr);
123123
template <class ExecutionPolicy>
124-
void initializeMeshVariables(const ExecutionPolicy &ex_policy, KernelTabulatedCK *kernel);
124+
void initializeMeshVariables(const ExecutionPolicy &ex_policy);
125125
template <class ExecutionPolicy>
126-
void initializeKernelIntegralVariables(const ExecutionPolicy &ex_policy, KernelTabulatedCK *kernel);
126+
void initializeKernelIntegralVariables(const ExecutionPolicy &ex_policy);
127127
template <class ExecutionPolicy>
128128
void registerProbes(const ExecutionPolicy &ex_policy, size_t level);
129129

130130
Shape &shape_; /**< the geometry is described by the level set. */
131131
size_t total_levels_; /**< level 0 is the coarsest */
132132
StdVec<UnsignedInt *> cell_pkg_index_set_;
133133
StdVec<std::pair<Arrayi, int> *> pkg_cell_info_set_;
134-
StdVec<Real> global_h_ratio_vec_;
134+
StdVec<Real> global_h_ratio_vec_; /**< the ratio of the reference spacing to the data spacing */
135+
StdVec<NeighborMethod<SingleValued> *> neighbor_method_set_;
135136
StdVec<MeshWithGridDataPackagesType *> mesh_data_set_;
136137
StdVec<ProbeSignedDistance *> probe_signed_distance_set_;
137138
StdVec<ProbeNormalDirection *> probe_normal_direction_set_;
@@ -147,13 +148,13 @@ class MultilevelLevelSet : public BaseMeshField
147148
UniquePtrsKeeper<ProbeKernelGradientIntegral> probe_kernel_gradient_integral_vector_keeper_;
148149
UniquePtrsKeeper<ProbeKernelSecondGradientIntegral> probe_kernel_second_gradient_integral_vector_keeper_;
149150

150-
UniquePtr<BaseExecDynamics> correct_topology_keeper_;
151-
UniquePtr<BaseExecDynamics> clean_interface_keeper_;
152-
UniquePtr<SingularVariable<KernelTabulatedCK>> kernel_;
151+
UniquePtr<BaseDynamics<void>> correct_topology_keeper_;
152+
UniquePtr<BaseDynamics<void>> clean_interface_keeper_;
153+
UniquePtrsKeeper<NeighborMethod<SingleValued>> neighbor_method_keeper_;
153154
std::function<void()> sync_mesh_variable_data_;
154155

155156
template <class ExecutionPolicy>
156-
void configLevelSetPostProcesses(const ExecutionPolicy &ex_policy, KernelTabulatedCK *kernel);
157+
void configLevelSetPostProcesses(const ExecutionPolicy &ex_policy);
157158
};
158159
} // namespace SPH
159160
#endif // LEVEL_SET_H

src/shared/geometries/level_set.hpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@ namespace SPH
77
{
88
//=================================================================================================//
99
template <class ExecutionPolicy>
10-
void MultilevelLevelSet::configLevelSetPostProcesses(const ExecutionPolicy &ex_policy, KernelTabulatedCK *kernel)
10+
void MultilevelLevelSet::configLevelSetPostProcesses(const ExecutionPolicy &ex_policy)
1111
{
1212
clean_interface_keeper_ = makeUnique<CleanInterface<ExecutionPolicy>>(
13-
*mesh_data_set_.back(), kernel, global_h_ratio_vec_.back());
13+
*mesh_data_set_.back(), *neighbor_method_set_.back());
1414
correct_topology_keeper_ = makeUnique<CorrectTopology<ExecutionPolicy>>(
15-
*mesh_data_set_.back(), kernel, global_h_ratio_vec_.back());
15+
*mesh_data_set_.back(), *neighbor_method_set_.back());
1616
}
1717
//=================================================================================================//
1818
template <class ExecutionPolicy>
19-
void MultilevelLevelSet::initializeMeshVariables(const ExecutionPolicy &ex_policy, KernelTabulatedCK *kernel)
19+
void MultilevelLevelSet::initializeMeshVariables(const ExecutionPolicy &ex_policy)
2020
{
2121
for (size_t level = 0; level < total_levels_; level++)
2222
{
@@ -35,23 +35,23 @@ void MultilevelLevelSet::initializeMeshVariables(const ExecutionPolicy &ex_polic
3535
template <class ExecutionPolicy>
3636
void MultilevelLevelSet::finishInitialization(const ExecutionPolicy &ex_policy, UsageType usage_type)
3737
{
38-
initializeMeshVariables(ex_policy, kernel_->Data());
38+
initializeMeshVariables(ex_policy);
3939
if (usage_type == UsageType::Volumetric)
4040
{
41-
initializeKernelIntegralVariables(ex_policy, kernel_->Data());
42-
configLevelSetPostProcesses(ex_policy, kernel_->Data());
41+
initializeKernelIntegralVariables(ex_policy);
42+
configLevelSetPostProcesses(ex_policy);
4343
}
4444
sync_mesh_variable_data_ = [&]()
4545
{ this->syncMeshVariableData(ex_policy); };
4646
}
4747
//=================================================================================================//
4848
template <class ExecutionPolicy>
49-
void MultilevelLevelSet::initializeKernelIntegralVariables(const ExecutionPolicy &ex_policy, KernelTabulatedCK *kernel)
49+
void MultilevelLevelSet::initializeKernelIntegralVariables(const ExecutionPolicy &ex_policy)
5050
{
5151
for (size_t level = 0; level < total_levels_; level++)
5252
{
5353
MeshInnerDynamics<ExecutionPolicy, UpdateKernelIntegrals>
54-
update_kernel_integrals{*mesh_data_set_[level], kernel, global_h_ratio_vec_[level]};
54+
update_kernel_integrals{*mesh_data_set_[level], *neighbor_method_set_[level]};
5555
update_kernel_integrals.exec();
5656

5757
probe_kernel_integral_set_.push_back(

0 commit comments

Comments
 (0)