Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
4bf033a
add mc conservative projection file
abhiyan123 Mar 17, 2026
d2eb0af
add mc helper functions declaration
abhiyan123 Mar 17, 2026
8f5148a
change function name from buildLoadVector to buildLoadVectorMI
abhiyan123 Mar 17, 2026
9094916
fix the load vector integrator name
abhiyan123 Mar 17, 2026
a95460b
add mc load vector build declaration
abhiyan123 Mar 17, 2026
e0b9fcd
add header
abhiyan123 Mar 17, 2026
26f1a4f
delete pcms_mc_proj_utils.hpp
abhiyan123 Mar 17, 2026
12c50c7
rename pcms_mc_proj_utils.cpp -> load_vector_integrator_mc.cpp
abhiyan123 Mar 17, 2026
21fdaba
rename load_vector_integrator.cpp -> load_vector_integrator_mi.cpp
abhiyan123 Mar 17, 2026
ab31a90
add mc load vector build
abhiyan123 Mar 17, 2026
54213bb
add build load vector with mc approach
abhiyan123 Mar 17, 2026
ecd8234
change the parameter sequence
abhiyan123 Mar 17, 2026
56c0160
add mc solver function
abhiyan123 Mar 17, 2026
e489bea
change parameter sequence
abhiyan123 Mar 17, 2026
17644e3
update variants of galerkin projection solve
abhiyan123 Mar 18, 2026
d542524
add namespace
abhiyan123 Mar 18, 2026
aea8cb6
update filenames in CMakeLists.txt
abhiyan123 Mar 18, 2026
15897c1
update solveGalerkinProjection to solveGalerkinProjectionMI
abhiyan123 Mar 18, 2026
5643ec2
update buildLoadVector to buildLoadVectorMI
abhiyan123 Mar 18, 2026
6356c81
add mc test functions
abhiyan123 Mar 18, 2026
bb20610
update mc test file in CMakeLists.txt
abhiyan123 Mar 18, 2026
6d6e7e1
add semicolon
abhiyan123 Mar 19, 2026
65a09c9
correct the class name
abhiyan123 Mar 19, 2026
4f664bc
update variable
abhiyan123 Mar 19, 2026
af6e728
correct class name
abhiyan123 Mar 19, 2026
a6207e7
change tri_id to element_id
abhiyan123 Mar 19, 2026
d51b3cd
change tri_id to element_id
abhiyan123 Mar 19, 2026
73d2143
minor changes
abhiyan123 Mar 19, 2026
4e626c9
fix the function name
abhiyan123 Mar 19, 2026
5dca135
update header
abhiyan123 Mar 19, 2026
e0915d1
update header
abhiyan123 Mar 19, 2026
0310306
update function
abhiyan123 Mar 19, 2026
4556bdc
minor changes
abhiyan123 Mar 19, 2026
24eccd5
add test case for monte carlo field transfer
abhiyan123 Mar 19, 2026
083144c
add filename in CMakeLists.txt
abhiyan123 Mar 19, 2026
30785f1
update header
abhiyan123 Mar 19, 2026
82f2fa8
update solveGalerkinProjectionMC parameters
abhiyan123 Mar 19, 2026
7a9785d
update args in a solveGalerkinProjectionMC function
abhiyan123 Mar 19, 2026
5a3d44a
create a host view instead of device
abhiyan123 Mar 19, 2026
80f8aba
update the API docs for MC projection
abhiyan123 Mar 19, 2026
e0c310d
add sobol samples
abhiyan123 Mar 19, 2026
86285ff
added more sobol barycentric points
abhiyan123 Mar 20, 2026
a92a3d1
change triangular element to just element
abhiyan123 Mar 20, 2026
228d58a
minor changes
abhiyan123 Mar 20, 2026
7cefadf
remove the condition number evaluate part
abhiyan123 Mar 25, 2026
6a9ed9e
add test for mass matrix
abhiyan123 Mar 31, 2026
08f1756
rename test_mass_matrix_mi.cpp to test_mass_matrix.cpp
abhiyan123 Mar 31, 2026
3695751
add abs_tol and rel_tol values
abhiyan123 Mar 31, 2026
3efbed6
move abs_tol and rel_tol to load_vector_integrator_mi.cpp
abhiyan123 Mar 31, 2026
6a53f51
move abs_tol and rel_tol to mesh_intersection.hpp
abhiyan123 Mar 31, 2026
b16ceb8
add test case for error evaluator using supermesh approach
abhiyan123 Mar 31, 2026
3441917
add files for mass matrix and error evaluator tests
abhiyan123 Mar 31, 2026
4ba58a8
correct the host view array
abhiyan123 Apr 1, 2026
f80abcb
defined accum with the specific variables
abhiyan123 Apr 1, 2026
a95d22b
define accum with the specific variables
abhiyan123 Apr 1, 2026
376bb82
correct host view
abhiyan123 Apr 1, 2026
38b0714
add view
abhiyan123 Apr 2, 2026
cd92c47
add some attributes for test
abhiyan123 Apr 2, 2026
61179ef
update Errors output
abhiyan123 Apr 2, 2026
662de10
change the threshold
abhiyan123 Apr 2, 2026
0b7e5a5
change the intersection threshold to the previous
abhiyan123 Apr 2, 2026
ad5b512
fix conversion from flat array to rank 2 array
abhiyan123 Apr 7, 2026
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
3 changes: 2 additions & 1 deletion src/pcms/transfer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ set(PCMS_FIELD_TRANSFER_HEADERS

set(PCMS_FIELD_TRANSFER_SOURCES
adj_search.cpp
load_vector_integrator.cpp
load_vector_integrator_mi.cpp
load_vector_integrator_mc.cpp
mesh_intersection.cpp
mls_interpolation.cpp
interpolation_base.cpp)
Expand Down
49 changes: 47 additions & 2 deletions src/pcms/transfer/calculate_load_vector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace pcms
{
PetscErrorCode calculateLoadVector(Omega_h::Mesh& target_mesh,
PetscErrorCode calculateLoadVectorMI(Omega_h::Mesh& target_mesh,
Omega_h::Mesh& source_mesh,
const IntersectionResults& intersection,
const Omega_h::Reals& source_values,
Expand All @@ -21,7 +21,52 @@ PetscErrorCode calculateLoadVector(Omega_h::Mesh& target_mesh,

// Fill COO values
auto elmLoadVector =
buildLoadVector(target_mesh, source_mesh, intersection, source_values);
buildLoadVectorMI(target_mesh, source_mesh, intersection, source_values);

auto hostElmLoadVector = Kokkos::create_mirror_view(elmLoadVector);
Kokkos::deep_copy(hostElmLoadVector, elmLoadVector);
PetscCheck(static_cast<PetscInt>(hostElmLoadVector.extent(0)) == nnz,
PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ,
"Element load vector size (%d) does not match COO nnz (%d)",
static_cast<PetscInt>(hostElmLoadVector.extent(0)), nnz);

for (PetscInt e = 0; e < nnz; ++e) {
coo_vals[e] = hostElmLoadVector(e);
}

// create vector with preallocated COO structure
Vec vec;
PetscCall(createSeqVec(PETSC_COMM_WORLD, target_mesh.nverts(), &vec));
PetscCall(VecSetPreallocationCOO(vec, nnz, coo_i));
PetscCall(VecSetValuesCOO(vec, coo_vals, ADD_VALUES));
PetscCall(PetscFree(coo_i));
PetscCall(PetscFree(coo_vals));

if (target_mesh.nelems() < 10) {
PetscCall(VecView(vec, PETSC_VIEWER_STDOUT_WORLD));
}

*loadVec_out = vec;
PetscFunctionReturn(PETSC_SUCCESS);
}

PetscErrorCode calculateLoadVectorMC(
Omega_h::Mesh& target_mesh, const Omega_h::Reals& field_values_at_points,
const int npoints_each_tri, SamplingMethod method, Vec* loadVec_out,
const std::string sobol_filename)
{

PetscFunctionBeginUser;
PetscInt nnz = 0;
PetscInt* coo_i = nullptr;
PetscCall(build_linear_triangle_coo_rows(target_mesh, &coo_i, &nnz));
PetscScalar* coo_vals = nullptr;
PetscCall(PetscMalloc1(nnz, &coo_vals));

// Fill COO values
auto elmLoadVector =
buildLoadVectorMC(target_mesh, field_values_at_points, npoints_each_tri,
method, sobol_filename);

auto hostElmLoadVector = Kokkos::create_mirror_view(elmLoadVector);
Kokkos::deep_copy(hostElmLoadVector, elmLoadVector);
Expand Down
76 changes: 63 additions & 13 deletions src/pcms/transfer/calculate_load_vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,18 @@
#define PCMS_TRANSFER_CALCULATE_LOAD_VECTOR_HPP
#include <Omega_h_mesh.hpp>
#include <pcms/transfer/mesh_intersection.hpp>
#include <pcms/transfer/load_vector_integrator.hpp>
#include <petscvec.h>

namespace pcms
{

/**
* @brief Assembles the global load vector.
* @brief Assembles the global load vector using mesh intersection method.
*
* This function computes the unassembled local load vector contributions for
* each triangular element in the target mesh using `buildLoadVector()` and then
* assembles them into a global PETSc vector in COO format.
* each triangular element in the target mesh using `buildLoadVectorMI()` and
* then assembles them into a global PETSc vector in COO format.
*
*
* @param target_mesh The target Omega_h mesh to which the scalar field is being
Expand All @@ -40,20 +44,66 @@
* @note
* - Works for 2D linear triangular elements.
* - Uses COO-style preallocation and insertion into the PETSc vector.
* - Internally calls `buildLoadVector()` to compute per-element contributions.
* - Internally calls `buildLoadVectorMI()` to compute per-element
* contributions.
* - The resulting vector is used as the right-hand side (RHS) in a projection
* solve.
*
* @see buildLoadVector,IntersectionResults
* @see buildLoadVectorMI,IntersectionResults
*/

namespace pcms
{
// FIXME use PCMS error handling rather than returning a PETSC error code
PetscErrorCode calculateLoadVector(Omega_h::Mesh& target_mesh,
Omega_h::Mesh& source_mesh,
const IntersectionResults& intersection,
const Omega_h::Reals& source_values,
Vec* loadVec_out);
PetscErrorCode calculateLoadVectorMI(Omega_h::Mesh& target_mesh,
Omega_h::Mesh& source_mesh,
const IntersectionResults& intersection,
const Omega_h::Reals& source_values,
Vec* loadVec_out);

/**
* @brief Assembles the global load vector using Monte Carlo integration.
*
* This function computes the unassembled local load vector contributions for
* each element in the target mesh using Monte Carlo integration and
* then assembles them into a global PETSc vector in COO format.
*
* The element-local contributions are computed from source-field values already
* evaluated at the sampled physical points in each target element. The sampling
* pattern is defined on the reference triangle and may be generated either by
* uniform random sampling or by precomputed Sobol barycentric samples.
*
* @param target_mesh The target Omega_h mesh to which the scalar field is being
* projected.
* @param field_values_at_points Source-field values evaluated at the sampled
* physical points in the target mesh. The data is expected to be stored
* element-by-element, with total size
* `target_mesh.nelems() * npoints_each_tri`.
* @param npoints_each_tri Number of sample points used in each target triangle
* for the Monte Carlo integration.
* @param method Sampling method used to define the reference barycentric sample
* coordinates. Supported options include uniform random sampling and Sobol
* sampling.
* @param sobol_filename Path to the file containing precomputed Sobol
* barycentric samples when `method` is `SamplingMethod::SOBOL`.
* @param[out] loadVec_out Pointer to a PETSc Vec where the assembled load
* vector will be stored.
*
* @return PetscErrorCode Returns PETSC_SUCCESS if successful, or an appropriate
* PETSc error code otherwise.
*
* @note
* - Works for 2D linear triangular elements.
* - Uses COO-style preallocation and insertion into the PETSc vector.
* - Internally computes per-element Monte Carlo load vector contributions
* before assembling the global vector.
* - For linear triangular elements, the barycentric coordinates are equal to
* the local shape-function values used in the Monte Carlo estimator.
* - The resulting vector is used as the right-hand side (RHS) in a projection
* solve.
*
* @see buildLoadVectorMC, SamplingMethod
*/
PetscErrorCode calculateLoadVectorMC(
Omega_h::Mesh& target_mesh, const Omega_h::Reals& field_values_at_points,
const int npoints_each_tri, SamplingMethod method, Vec* loadVec_out,
const std::string sobol_filename = "");
} // namespace pcms
#endif // PCMS_TRANSFER_CALCULATE_LOAD_VECTOR_HPP
2 changes: 1 addition & 1 deletion src/pcms/transfer/calculate_mass_matrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ PetscErrorCode calculateMassMatrix(Omega_h::Mesh& mesh, Mat* mass_out)
{
PetscFunctionBeginUser;

MeshField::OmegahMeshField<DefaultExecutionSpace, 2,
MeshField::OmegahMeshField<Kokkos::DefaultExecutionSpace, 2,
MeshField::KokkosController>
omf(mesh);

Expand Down
102 changes: 80 additions & 22 deletions src/pcms/transfer/conservative_projection_solver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,22 @@ static Vec solveLinearSystem(Mat A, Vec b)
ierr = KSPSolve(ksp, b, x);
CHKERRABORT(PETSC_COMM_WORLD, ierr);

/// compute and print condition number estimate
PetscReal smax = 0.0, smin = 0.0;
ierr = KSPComputeExtremeSingularValues(ksp, &smax, &smin);
if (!ierr && smin > 0.0) {
PetscPrintf(PETSC_COMM_WORLD,
"Estimated condition number of matrix A: %.6e\n", smax / smin);
} else {
PetscPrintf(PETSC_COMM_WORLD,
"Condition number estimate unavailable (smin <= 0 or error)\n");
}
KSPConvergedReason reason;
PetscInt its = 0;
PetscReal rnorm = 0.0;

ierr = KSPGetConvergedReason(ksp, &reason);
CHKERRABORT(PETSC_COMM_WORLD, ierr);

ierr = KSPGetIterationNumber(ksp, &its);
CHKERRABORT(PETSC_COMM_WORLD, ierr);

ierr = KSPGetResidualNorm(ksp, &rnorm);
CHKERRABORT(PETSC_COMM_WORLD, ierr);

PetscPrintf(PETSC_COMM_WORLD,
"KSP reason=%d iterations=%d residual=%e\n",
(int)reason, (int)its, (double)rnorm);

ierr = KSPDestroy(&ksp);
CHKERRABORT(PETSC_COMM_WORLD, ierr);
Expand Down Expand Up @@ -86,10 +92,9 @@ static Omega_h::Reals vecToOmegaHReals(Vec vec)
return Omega_h::Reals(values_host);
}

Omega_h::Reals solveGalerkinProjection(Omega_h::Mesh& target_mesh,
Omega_h::Mesh& source_mesh,
const IntersectionResults& intersection,
const Omega_h::Reals& source_values)
Omega_h::Reals solveGalerkinProjectionMI(
Omega_h::Mesh& target_mesh, Omega_h::Mesh& source_mesh,
const IntersectionResults& intersection, const Omega_h::Reals& source_values)
{
if ((PetscInt)source_values.size() !=
source_mesh.coords().size() / source_mesh.dim()) {
Expand All @@ -105,8 +110,8 @@ Omega_h::Reals solveGalerkinProjection(Omega_h::Mesh& target_mesh,
CHKERRABORT(PETSC_COMM_WORLD, ierr);

Vec vec;
ierr = calculateLoadVector(target_mesh, source_mesh, intersection,
source_values, &vec);
ierr = calculateLoadVectorMI(target_mesh, source_mesh, intersection,
source_values, &vec);
CHKERRABORT(PETSC_COMM_WORLD, ierr);

Vec x = solveLinearSystem(mass, vec);
Expand All @@ -123,15 +128,46 @@ Omega_h::Reals solveGalerkinProjection(Omega_h::Mesh& target_mesh,

return solution_vector;
}
Omega_h::Reals rhsVectorMI(Omega_h::Mesh& target_mesh,
Omega_h::Mesh& source_mesh,
const IntersectionResults& intersection,
const Omega_h::Reals& source_values)

Omega_h::Reals solveGalerkinProjectionMC(
Omega_h::Mesh& target_mesh, const Omega_h::Reals& field_values_at_points,
const int npoints_each_tri, SamplingMethod method,
const std::string sobol_filename)
{

Mat mass;
PetscErrorCode ierr = calculateMassMatrix(target_mesh, &mass);
CHKERRABORT(PETSC_COMM_WORLD, ierr);

Vec vec;
ierr = calculateLoadVectorMC(target_mesh, field_values_at_points,
npoints_each_tri, method, &vec, sobol_filename);
CHKERRABORT(PETSC_COMM_WORLD, ierr);

Vec x = solveLinearSystem(mass, vec);
auto solution_vector = vecToOmegaHReals(x);

ierr = VecDestroy(&x);
CHKERRABORT(PETSC_COMM_WORLD, ierr);

ierr = MatDestroy(&mass);
CHKERRABORT(PETSC_COMM_WORLD, ierr);

ierr = VecDestroy(&vec);
CHKERRABORT(PETSC_COMM_WORLD, ierr);

return solution_vector;
}

Omega_h::Reals computeRhsVectorMI(Omega_h::Mesh& target_mesh,
Omega_h::Mesh& source_mesh,
const IntersectionResults& intersection,
const Omega_h::Reals& source_values)
{
Vec vec;
PetscErrorCode ierr;
ierr = calculateLoadVector(target_mesh, source_mesh, intersection,
source_values, &vec);
ierr = calculateLoadVectorMI(target_mesh, source_mesh, intersection,
source_values, &vec);
CHKERRABORT(PETSC_COMM_WORLD, ierr);

auto rhsvector = vecToOmegaHReals(vec);
Expand All @@ -141,4 +177,26 @@ Omega_h::Reals rhsVectorMI(Omega_h::Mesh& target_mesh,

return rhsvector;
}

Omega_h::Reals computeRhsVectorMC(Omega_h::Mesh& target_mesh,
const Omega_h::Reals& field_values_at_points,
const int npoints_each_tri,
SamplingMethod method,
const std::string& sobol_filename)
{

Vec vec;
PetscErrorCode ierr;
ierr =
calculateLoadVectorMC(target_mesh, field_values_at_points,
npoints_each_tri, method, &vec, sobol_filename);
CHKERRABORT(PETSC_COMM_WORLD, ierr);

auto rhsvector = vecToOmegaHReals(vec);
ierr = VecDestroy(&vec);
CHKERRABORT(PETSC_COMM_WORLD, ierr);

return rhsvector;
}

} // namespace pcms
Loading