Skip to content
Draft
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// SPDX-FileCopyrightText: 2023 - 2026 NeoN authors
//
// SPDX-License-Identifier: MIT

#pragma once

#include <variant>

#include "NeoN/core/parallelAlgorithms.hpp"
#include "NeoN/core/primitives/scalar.hpp"
#include "NeoN/core/primitives/label.hpp"
#include "NeoN/core/view.hpp"

namespace NeoN::finiteVolume::cellCentred
{

/* @brief Device-callable weight kernel for linear interpolation.
** Captures the pre-computed geometry weights views (internal + boundary); no virtual dispatch.
** The boundary view covers both physical and proc boundary faces in a single contiguous array.
*/
struct LinearInlineKernel
{
View<const scalar> weights;
View<const scalar> bWeights;

NEON_INLINE_FUNCTION scalar weight(localIdx facei, scalar /*flux*/) const
{
return weights[facei];
}

NEON_INLINE_FUNCTION scalar boundaryWeight(localIdx bfacei, scalar /*flux*/) const
{
return bWeights[bfacei];
}

NEON_INLINE_FUNCTION scalar procBoundaryWeight(localIdx bcfacei, scalar /*flux*/) const
{
return bWeights[bcfacei];
}
};

/* @brief Device-callable weight kernel for upwind interpolation.
** Internal weight: 1 if flux >= 0 (owner upwind), 0 otherwise.
** Physical boundary weight: always 1 (value comes from the BC, not interpolated).
** Proc boundary weight: flux-sign, matching the coupled internal-face convention.
*/
struct UpwindInlineKernel
{
NEON_INLINE_FUNCTION scalar weight([[maybe_unused]] localIdx facei, scalar flux) const
{
return flux >= scalar(0) ? scalar(1) : scalar(0);
}

NEON_INLINE_FUNCTION scalar
boundaryWeight([[maybe_unused]] localIdx bfacei, [[maybe_unused]] scalar flux) const
{
return scalar(1);
}

NEON_INLINE_FUNCTION scalar
procBoundaryWeight([[maybe_unused]] localIdx bcfacei, scalar flux) const
{
return flux >= scalar(0) ? scalar(1) : scalar(0);
}
};

using InlineWeightKernel = std::variant<LinearInlineKernel, UpwindInlineKernel>;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this makes it incompatible with a plugin architecture, so adding new schemes would require adding to InlineWeightKernel


} // namespace NeoN::finiteVolume::cellCentred
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ void computeLinearInterpolation(
SurfaceField<ValueType>& dst
);


template<typename ValueType>
class Linear : public SurfaceInterpolationFactory<ValueType>::template Register<Linear<ValueType>>
{
Expand Down Expand Up @@ -84,6 +85,12 @@ class Linear : public SurfaceInterpolationFactory<ValueType>::template Register<
}


InlineWeightKernel inlineWeightKernel() const override
{
const SurfaceField<scalar>& w = geometryScheme_->weights();
return LinearInlineKernel {w.internalVector().view(), w.boundaryData().value().view()};
}

std::unique_ptr<SurfaceInterpolationFactory<ValueType>> clone() const override
{
return std::make_unique<Linear>(*this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ class LinearUpwind :
);
}

InlineWeightKernel inlineWeightKernel() const override { return UpwindInlineKernel {}; }

std::unique_ptr<SurfaceInterpolationFactory<ValueType>> clone() const override
{
return std::make_unique<LinearUpwind>(*this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "NeoN/finiteVolume/cellCentred/fields/surfaceField.hpp"
#include "NeoN/finiteVolume/cellCentred/fields/volumeField.hpp"
#include "NeoN/finiteVolume/cellCentred/boundary.hpp"
#include "NeoN/finiteVolume/cellCentred/interpolation/inlineInterpolationKernels.hpp"

namespace NeoN::finiteVolume::cellCentred
{
Expand Down Expand Up @@ -91,6 +92,11 @@ class SurfaceInterpolationFactory :
fill(corr.boundaryData().value(), zero<ValueType>());
}

/* @brief Returns a device-callable weight kernel for use inside Kokkos kernels.
* The kernel computes the face interpolation weight inline per face without virtual dispatch.
*/
virtual InlineWeightKernel inlineWeightKernel() const = 0;

Comment on lines +95 to +99
// Pure virtual function for cloning
virtual std::unique_ptr<SurfaceInterpolationFactory<ValueType>> clone() const = 0;

Expand Down Expand Up @@ -159,6 +165,11 @@ class SurfaceInterpolation

bool corrected() const { return interpolationKernel_->corrected(); }

InlineWeightKernel inlineWeightKernel() const
{
return interpolationKernel_->inlineWeightKernel();
}

void correction(
const SurfaceField<scalar>& flux,
const VolumeField<ValueType>& src,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ class Upwind : public SurfaceInterpolationFactory<ValueType>::template Register<
computeUpwindInterpolationWeights(faceFlux, src, weights);
}

InlineWeightKernel inlineWeightKernel() const override { return UpwindInlineKernel {}; }

std::unique_ptr<SurfaceInterpolationFactory<ValueType>> clone() const override
{
return std::make_unique<Upwind>(*this);
Expand Down
Loading
Loading