Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/shammodels/gsph/include/shammodels/gsph/Solver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ namespace shammodels::gsph {
using GhostHandleCache = typename GhostHandle::CacheMap;

void gen_ghost_handler(Tscal time_val);
inline void reset_ghost_handler() { storage.ghost_handler.reset(); }
inline void reset_ghost_handler() {
shambase::get_check_ref(storage.ghost_handler).free_alloc();
}

void build_ghost_cache();
void clear_ghost_cache();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,15 @@
#include "shambase/stacktrace.hpp"
#include "shambackends/vec.hpp"
#include "shammodels/gsph/modules/GSPHGhostHandler.hpp"
#include "shammodels/gsph/solvergraph/GhostHandlerEdge.hpp"
#include "shammodels/sph/solvergraph/NeighCache.hpp"
#include "shamrock/scheduler/SerialPatchTree.hpp"
#include "shamrock/scheduler/ShamrockCtx.hpp"
#include "shamrock/solvergraph/Field.hpp"
#include "shamrock/solvergraph/FieldRefs.hpp"
#include "shamrock/solvergraph/Indexes.hpp"
#include "shamrock/solvergraph/ScalarsEdge.hpp"
#include "shamrock/solvergraph/SolverGraph.hpp"
#include "shamsys/legacy/log.hpp"
#include "shamtree/CompressedLeafBVH.hpp"
#include "shamtree/KarrasRadixTreeField.hpp"
Expand Down Expand Up @@ -70,6 +72,8 @@ namespace shammodels::gsph {

using RTree = shamtree::CompressedLeafBVH<Tmorton, Tvec, 3>;

shamrock::solvergraph::SolverGraph solver_graph;

/// Particle counts per patch
std::shared_ptr<shamrock::solvergraph::Indexes<u32>> part_counts;
std::shared_ptr<shamrock::solvergraph::Indexes<u32>> part_counts_with_ghost;
Expand All @@ -84,11 +88,11 @@ namespace shammodels::gsph {
/// Patch rank ownership
std::shared_ptr<shamrock::solvergraph::ScalarsEdge<u32>> patch_rank_owner;

std::shared_ptr<solvergraph::GhostHandlerEdge<Tvec>> ghost_handler;
/// Serial patch tree for load balancing
Component<SerialPatchTree<Tvec>> serial_patch_tree;

/// Ghost handler for boundary particles
Component<GhostHandle> ghost_handler;
/// Ghost interface cache
Component<GhostHandleCache> ghost_patch_cache;

/// Merged position-h data for neighbor search
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// -------------------------------------------------------//
//
// SHAMROCK code for hydrodynamics
// Copyright (c) 2021-2026 Timothée David--Cléris <tim.shamrock@proton.me>
// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1
// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information
//
// -------------------------------------------------------//

#pragma once

/**
* @file GhostHandlerEdge.hpp
* @author Guo Yansong (guo.yansong.ngy@gmail.com)
* @brief SolverGraph edge for GSPH ghost handler
*/

#include "shambase/memory.hpp"
#include "shammodels/gsph/modules/GSPHGhostHandler.hpp"
#include "shamrock/solvergraph/IEdgeNamed.hpp"
#include <optional>

namespace shammodels::gsph::solvergraph {

/// SolverGraph edge for GSPH ghost handler
template<class Tvec>
class GhostHandlerEdge : public shamrock::solvergraph::IEdgeNamed {
public:
using IEdgeNamed::IEdgeNamed;
using GhostHandle = GSPHGhostHandler<Tvec>;

std::optional<GhostHandle> handler;

GhostHandle &get() {
if (!handler.has_value()) {
shambase::throw_with_loc<std::runtime_error>("GhostHandler not set");
}
return handler.value();
}

const GhostHandle &get() const {
if (!handler.has_value()) {
shambase::throw_with_loc<std::runtime_error>("GhostHandler not set");
}
return handler.value();
}

bool has_value() const { return handler.has_value(); }

void set(GhostHandle &&h) {
handler.reset();
handler.emplace(std::move(h));
}

/// Free the allocated handler
inline virtual void free_alloc() override { handler.reset(); }
};

} // namespace shammodels::gsph::solvergraph
45 changes: 29 additions & 16 deletions src/shammodels/gsph/src/Solver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ void shammodels::gsph::Solver<Tvec, Kern>::init_solver_graph() {
storage.neigh_cache
= std::make_shared<shammodels::sph::solvergraph::NeighCache>(edges::neigh_cache, "neigh");

// Register ghost handler in solvergraph for explicit data dependency tracking
storage.ghost_handler = storage.solver_graph.register_edge(
"ghost_handler", solvergraph::GhostHandlerEdge<Tvec>("ghost_handler", "\\mathcal{G}"));

storage.omega = std::make_shared<shamrock::solvergraph::Field<Tscal>>(1, "omega", "\\Omega");
storage.density = std::make_shared<shamrock::solvergraph::Field<Tscal>>(1, "density", "\\rho");
storage.pressure = std::make_shared<shamrock::solvergraph::Field<Tscal>>(1, "pressure", "P");
Expand Down Expand Up @@ -142,26 +146,32 @@ void shammodels::gsph::Solver<Tvec, Kern>::gen_ghost_handler(Tscal time_val) {
// Boundary condition selection - similar to SPH solver
// Note: Wall boundaries use Periodic with dynamic wall particles
if (SolverBCFree *c = std::get_if<SolverBCFree>(&solver_config.boundary_config.config)) {
storage.ghost_handler.set(
GhostHandle{
scheduler(), BCFree{}, storage.patch_rank_owner, storage.xyzh_ghost_layout});
shambase::get_check_ref(storage.ghost_handler)
.set(
GhostHandle{
scheduler(), BCFree{}, storage.patch_rank_owner, storage.xyzh_ghost_layout});
} else if (
SolverBCPeriodic *c
= std::get_if<SolverBCPeriodic>(&solver_config.boundary_config.config)) {
storage.ghost_handler.set(
GhostHandle{
scheduler(), BCPeriodic{}, storage.patch_rank_owner, storage.xyzh_ghost_layout});
shambase::get_check_ref(storage.ghost_handler)
.set(
GhostHandle{
scheduler(),
BCPeriodic{},
storage.patch_rank_owner,
storage.xyzh_ghost_layout});
} else if (
SolverBCShearingPeriodic *c
= std::get_if<SolverBCShearingPeriodic>(&solver_config.boundary_config.config)) {
// Shearing periodic boundaries (Stone 2010) - reuse SPH implementation
storage.ghost_handler.set(
GhostHandle{
scheduler(),
BCShearingPeriodic{
c->shear_base, c->shear_dir, c->shear_speed * time_val, c->shear_speed},
storage.patch_rank_owner,
storage.xyzh_ghost_layout});
shambase::get_check_ref(storage.ghost_handler)
.set(
GhostHandle{
scheduler(),
BCShearingPeriodic{
c->shear_base, c->shear_dir, c->shear_speed * time_val, c->shear_speed},
storage.patch_rank_owner,
storage.xyzh_ghost_layout});
} else {
shambase::throw_with_loc<std::runtime_error>("GSPH: Unsupported boundary condition type.");
}
Expand All @@ -175,7 +185,7 @@ void shammodels::gsph::Solver<Tvec, Kern>::build_ghost_cache() {
GSPHUtils gsph_utils(scheduler());

storage.ghost_patch_cache.set(gsph_utils.build_interf_cache(
storage.ghost_handler.get(),
shambase::get_check_ref(storage.ghost_handler).get(),
storage.serial_patch_tree.get(),
solver_config.htol_up_coarse_cycle));
}
Expand All @@ -191,7 +201,9 @@ void shammodels::gsph::Solver<Tvec, Kern>::merge_position_ghost() {
StackEntry stack_loc{};

storage.merged_xyzh.set(
storage.ghost_handler.get().build_comm_merge_positions(storage.ghost_patch_cache.get()));
shambase::get_check_ref(storage.ghost_handler)
.get()
.build_comm_merge_positions(storage.ghost_patch_cache.get()));

// Get field indices from xyzh_ghost_layout
const u32 ixyz_ghost
Expand Down Expand Up @@ -665,7 +677,8 @@ void shammodels::gsph::Solver<Tvec, Kern>::communicate_merge_ghosts_fields() {

using InterfaceBuildInfos = typename gsph::GSPHGhostHandler<Tvec>::InterfaceBuildInfos;

gsph::GSPHGhostHandler<Tvec> &ghost_handle = storage.ghost_handler.get();
gsph::GSPHGhostHandler<Tvec> &ghost_handle
= shambase::get_check_ref(storage.ghost_handler).get();
shamrock::solvergraph::Field<Tscal> &omega = shambase::get_check_ref(storage.omega);
shamrock::solvergraph::Field<Tscal> &density = shambase::get_check_ref(storage.density);

Expand Down