-
Notifications
You must be signed in to change notification settings - Fork 6
Jk/linear tet #65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Jk/linear tet #65
Changes from 3 commits
53fb9ec
b6773a4
70d1771
9ccc52b
919e366
af6026b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -89,6 +89,37 @@ | |||||||||||||||||||||||||||||||
| return {0, triCompIdx, vtx, MeshField::Vertex}; // node, comp, ent, topo | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||
| struct LinearTetrahedronToVertexField { | ||||||||||||||||||||||||||||||||
| Omega_h::LOs tetVerts; | ||||||||||||||||||||||||||||||||
| LinearTetrahedronToVertexField(Omega_h::Mesh &mesh) | ||||||||||||||||||||||||||||||||
| : tetVerts(mesh.ask_elem_verts()) { | ||||||||||||||||||||||||||||||||
| if (mesh.dim() != 3 && mesh.family() != OMEGA_H_SIMPLEX) { | ||||||||||||||||||||||||||||||||
| MeshField::fail( | ||||||||||||||||||||||||||||||||
| "The mesh passed to %s must be 3D and simplex (tetrahedron)\n", | ||||||||||||||||||||||||||||||||
| __func__); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| KOKKOS_FUNCTION Kokkos::Array<MeshField::Mesh_Topology, 1> | ||||||||||||||||||||||||||||||||
| getTopology() const { | ||||||||||||||||||||||||||||||||
| return {MeshField::Tetrahedron}; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| KOKKOS_FUNCTION MeshField::ElementToDofHolderMap | ||||||||||||||||||||||||||||||||
| operator()(MeshField::LO tetNodeIdx, MeshField::LO tetCompIdx, | ||||||||||||||||||||||||||||||||
| MeshField::LO tet, MeshField::Mesh_Topology topo) const { | ||||||||||||||||||||||||||||||||
| assert(topo == MeshField::Tetrahedron); | ||||||||||||||||||||||||||||||||
| const auto tetDim = 3; | ||||||||||||||||||||||||||||||||
| const auto vtxDim = 0; | ||||||||||||||||||||||||||||||||
| const auto ignored = -1; | ||||||||||||||||||||||||||||||||
| const auto localVtxIdx = | ||||||||||||||||||||||||||||||||
| (Omega_h::simplex_down_template(tetDim, vtxDim, tetNodeIdx, ignored) + | ||||||||||||||||||||||||||||||||
| 3) % | ||||||||||||||||||||||||||||||||
| 4; | ||||||||||||||||||||||||||||||||
| const auto tetToVtxDegree = Omega_h::simplex_degree(tetDim, vtxDim); | ||||||||||||||||||||||||||||||||
| const MeshField::LO vtx = tetVerts[(tet * tetToVtxDegree) + localVtxIdx]; | ||||||||||||||||||||||||||||||||
| return {0, tetCompIdx, vtx, MeshField::Vertex}; // node, comp, ent, topo | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||
| struct QuadraticTriangleToField { | ||||||||||||||||||||||||||||||||
| Omega_h::LOs triVerts; | ||||||||||||||||||||||||||||||||
| Omega_h::LOs triEdges; | ||||||||||||||||||||||||||||||||
|
|
@@ -151,6 +182,59 @@ | |||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| struct QuadraticTetrahedronToField { | ||||||||||||||||||||||||||||||||
| Omega_h::LOs tetVerts; | ||||||||||||||||||||||||||||||||
| Omega_h::LOs tetEdges; | ||||||||||||||||||||||||||||||||
| QuadraticTetrahedronToField(Omega_h::Mesh &mesh) | ||||||||||||||||||||||||||||||||
| : tetVerts(mesh.ask_elem_verts()), | ||||||||||||||||||||||||||||||||
| tetEdges(mesh.ask_down(mesh.dim(), 1).ab2b) { | ||||||||||||||||||||||||||||||||
| if (mesh.dim() != 3 && mesh.family() != OMEGA_H_SIMPLEX) { | ||||||||||||||||||||||||||||||||
| MeshField::fail( | ||||||||||||||||||||||||||||||||
| "The mesh passed to %s must be 3D and simplex (tetrahedron)", | ||||||||||||||||||||||||||||||||
| __func__); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| KOKKOS_FUNCTION Kokkos::Array<MeshField::Mesh_Topology, 1> | ||||||||||||||||||||||||||||||||
| getTopology() const { | ||||||||||||||||||||||||||||||||
| return {MeshField::Tetrahedron}; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| KOKKOS_FUNCTION MeshField::ElementToDofHolderMap | ||||||||||||||||||||||||||||||||
| operator()(MeshField::LO tetNodeIdx, MeshField::LO tetCompIdx, | ||||||||||||||||||||||||||||||||
| MeshField::LO tet, MeshField::Mesh_Topology topo) const { | ||||||||||||||||||||||||||||||||
| assert(topo == MeshField::Tetrahedron); | ||||||||||||||||||||||||||||||||
| const MeshField::LO tetNode2DofHolder[10] = {0, 1, 2, 3, 3, 0, 4, 5, 2, 1}; | ||||||||||||||||||||||||||||||||
| const MeshField::Mesh_Topology tetNode2DofHolderTopo[10] = { | ||||||||||||||||||||||||||||||||
| MeshField::Vertex, MeshField::Vertex, MeshField::Vertex, | ||||||||||||||||||||||||||||||||
| MeshField::Vertex, MeshField::Edge, MeshField::Edge, | ||||||||||||||||||||||||||||||||
| MeshField::Edge, MeshField::Edge, MeshField::Edge, | ||||||||||||||||||||||||||||||||
| MeshField::Edge}; | ||||||||||||||||||||||||||||||||
| const auto dofHolderIdx = tetNode2DofHolder[tetNodeIdx]; | ||||||||||||||||||||||||||||||||
| const auto dofHolderTopo = tetNode2DofHolderTopo[tetNodeIdx]; | ||||||||||||||||||||||||||||||||
| Omega_h::LO osh_ent; | ||||||||||||||||||||||||||||||||
| if (dofHolderTopo == MeshField::Vertex) { | ||||||||||||||||||||||||||||||||
| const auto tetDim = 3; | ||||||||||||||||||||||||||||||||
| const auto vtxDim = 0; | ||||||||||||||||||||||||||||||||
| const auto ignored = -1; | ||||||||||||||||||||||||||||||||
| const auto localVtxIdx = (Omega_h::simplex_down_template( | ||||||||||||||||||||||||||||||||
| tetDim, vtxDim, dofHolderIdx, ignored) + | ||||||||||||||||||||||||||||||||
| 3) % | ||||||||||||||||||||||||||||||||
| 4; | ||||||||||||||||||||||||||||||||
| const auto tetToVtxDegree = Omega_h::simplex_degree(tetDim, vtxDim); | ||||||||||||||||||||||||||||||||
| osh_ent = tetVerts[(tet * tetToVtxDegree) + localVtxIdx]; | ||||||||||||||||||||||||||||||||
| } else if (dofHolderTopo == MeshField::Edge) { | ||||||||||||||||||||||||||||||||
| const auto tetDim = 3; | ||||||||||||||||||||||||||||||||
| const auto edgeDim = 1; | ||||||||||||||||||||||||||||||||
| const auto tetToEdgeDegree = Omega_h::simplex_degree(tetDim, edgeDim); | ||||||||||||||||||||||||||||||||
| osh_ent = tetEdges[(tet * tetToEdgeDegree) + dofHolderIdx]; | ||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||
| assert(false); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| return {0, tetCompIdx, osh_ent, dofHolderTopo}; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| template <int ShapeOrder> auto getTriangleElement(Omega_h::Mesh &mesh) { | ||||||||||||||||||||||||||||||||
| static_assert(ShapeOrder == 1 || ShapeOrder == 2); | ||||||||||||||||||||||||||||||||
| if constexpr (ShapeOrder == 1) { | ||||||||||||||||||||||||||||||||
|
|
@@ -169,6 +253,24 @@ | |||||||||||||||||||||||||||||||
| QuadraticTriangleToField(mesh)}; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| template <int ShapeOrder> auto getTetrahedronElement(Omega_h::Mesh &mesh) { | ||||||||||||||||||||||||||||||||
| static_assert(ShapeOrder == 1 || ShapeOrder == 2); | ||||||||||||||||||||||||||||||||
| if constexpr (ShapeOrder == 1) { | ||||||||||||||||||||||||||||||||
| struct result { | ||||||||||||||||||||||||||||||||
| MeshField::LinearTetrahedronShape shp; | ||||||||||||||||||||||||||||||||
| LinearTetrahedronToVertexField map; | ||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||
| return result{MeshField::LinearTetrahedronShape(), | ||||||||||||||||||||||||||||||||
| LinearTetrahedronToVertexField(mesh)}; | ||||||||||||||||||||||||||||||||
| } else if constexpr (ShapeOrder == 2) { | ||||||||||||||||||||||||||||||||
| struct result { | ||||||||||||||||||||||||||||||||
| MeshField::QuadraticTetrahedronShape shp; | ||||||||||||||||||||||||||||||||
| QuadraticTetrahedronToField map; | ||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||
| return result{MeshField::QuadraticTetrahedronShape(), | ||||||||||||||||||||||||||||||||
| QuadraticTetrahedronToField(mesh)}; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| } // namespace Omegah | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
|
|
@@ -252,6 +354,32 @@ | |||||||||||||||||||||||||||||||
| auto eval = MeshField::evaluate(f, localCoords, offsets); | ||||||||||||||||||||||||||||||||
| return eval; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| template <typename ViewType, typename ShapeField> | ||||||||||||||||||||||||||||||||
| auto tetrahedronLocalPointEval(ViewType localCoords, size_t NumPtsPerElem, | ||||||||||||||||||||||||||||||||
| ShapeField field) { | ||||||||||||||||||||||||||||||||
| auto offsets = createOffsets(meshInfo.numTet, NumPtsPerElem); | ||||||||||||||||||||||||||||||||
| auto eval = tetrahedronLocalPointEval(localCoords, offsets, field); | ||||||||||||||||||||||||||||||||
| return eval; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| template <typename ViewType, typename ShapeField> | ||||||||||||||||||||||||||||||||
| auto tetrahedronLocalPointEval(ViewType localCoords, | ||||||||||||||||||||||||||||||||
| Kokkos::View<LO *> offsets, ShapeField field) { | ||||||||||||||||||||||||||||||||
Check noticeCode scanning / CodeQL Large object passed by value Note
This parameter of type
ShapeField<3UL, KokkosController<HostSpace, Serial, double ***, double ***>, QuadraticTetrahedronShape, QuadraticAccessor<Field<KokkosSliceWrapper<View<double ***, HostSpace>, double ***>>, Field<KokkosSliceWrapper<View<double ***, HostSpace>, double ***>>>> Error loading related location Loading This parameter of type ShapeField<2UL, KokkosController<HostSpace, Serial, double ***, double ***>, QuadraticTetrahedronShape, QuadraticAccessor<Field<KokkosSliceWrapper<View<double ***, HostSpace>, double ***>>, Field<KokkosSliceWrapper<View<double ***, HostSpace>, double ***>>>> Error loading related location Loading This parameter of type ShapeField<3UL, KokkosController<HostSpace, Serial, double ***>, LinearTetrahedronShape, LinearAccessor<Field<KokkosSliceWrapper<View<double ***, HostSpace>, double ***>>>> is 200 bytes - consider passing a const pointer/reference instead. This parameter of type ShapeField<2UL, KokkosController<HostSpace, Serial, double ***>, LinearTetrahedronShape, LinearAccessor<Field<KokkosSliceWrapper<View<double ***, HostSpace>, double ***>>>> is 200 bytes - consider passing a const pointer/reference instead. This parameter of type ShapeField<1UL, KokkosController<HostSpace, Serial, double ***, double ***>, QuadraticTetrahedronShape, QuadraticAccessor<Field<KokkosSliceWrapper<View<double ***, HostSpace>, double ***>>, Field<KokkosSliceWrapper<View<double ***, HostSpace>, double ***>>>> is 344 bytes - consider passing a const pointer/reference instead. This parameter of type ShapeField<1UL, KokkosController<HostSpace, Serial, double ***>, LinearTetrahedronShape, LinearAccessor<Field<KokkosSliceWrapper<View<double ***, HostSpace>, double ***>>>> is 200 bytes - consider passing a const pointer/reference instead. This parameter of type ShapeField<1UL, KokkosController<HostSpace, Serial, double ***, double ***>, QuadraticTriangleShape, QuadraticAccessor<Field<KokkosSliceWrapper<View<double ***, HostSpace>, double ***>>, Field<KokkosSliceWrapper<View<double ***, HostSpace>, double ***>>>> is 344 bytes - consider passing a const pointer/reference instead. This parameter of type ShapeField<1UL, KokkosController<HostSpace, Serial, double ***>, LinearTriangleShape, LinearAccessor<Field<KokkosSliceWrapper<View<double ***, HostSpace>, double ***>>>> is 200 bytes - consider passing a const pointer/reference instead.
Copilot AutofixAI 5 months ago To fix the problem, we should change the
Suggested changeset
1
src/MeshField.hpp
Copilot is powered by AI and may make mistakes. Always verify output.
Refresh and try again.
|
||||||||||||||||||||||||||||||||
| const auto MeshDim = 3; | ||||||||||||||||||||||||||||||||
| if (mesh.dim() != MeshDim) { | ||||||||||||||||||||||||||||||||
| MeshField::fail("input mesh must be 3d\n"); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| const auto ShapeOrder = ShapeField::Order; | ||||||||||||||||||||||||||||||||
| if (ShapeOrder != 1 && ShapeOrder != 2) { | ||||||||||||||||||||||||||||||||
| MeshField::fail("input field order must be 1 or 2\n"); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| const auto [shp, map] = Omegah::getTetrahedronElement<ShapeOrder>(mesh); | ||||||||||||||||||||||||||||||||
| MeshField::FieldElement<ShapeField, decltype(shp), decltype(map)> f( | ||||||||||||||||||||||||||||||||
| meshInfo.numTet, field, shp, map); | ||||||||||||||||||||||||||||||||
| auto eval = MeshField::evaluate(f, localCoords, offsets); | ||||||||||||||||||||||||||||||||
| return eval; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| } // namespace MeshField | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should rename this to Likewise, in another PR we should add tests for multiple components and the cabana backend. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,139 @@ | ||
| #include <Kokkos_Core.hpp> | ||
| #include <MeshField.hpp> | ||
| #include <Omega_h_build.hpp> | ||
| #include <Omega_h_mesh.hpp> | ||
| template <size_t order> void runTest(Omega_h::Mesh mesh) { | ||
|
||
| MeshField::OmegahMeshField<Kokkos::DefaultExecutionSpace, 3> mesh_field(mesh); | ||
| auto shape_field = | ||
| mesh_field.template CreateLagrangeField<double, order, 1>(); | ||
| auto dim = mesh.dim(); | ||
| auto coords = mesh.coords(); | ||
| auto f = KOKKOS_LAMBDA(double x, double y, double z)->double { | ||
| return 2 * x + 3 * y + 4 * z; | ||
| }; | ||
| auto edge2vtx = mesh.ask_down(1, 0).ab2b; | ||
| auto edgeMap = mesh.ask_down(dim, 1).ab2b; | ||
| Kokkos::parallel_for( | ||
| mesh.nverts(), KOKKOS_LAMBDA(int vtx) { | ||
| auto x = coords[vtx * dim]; | ||
| auto y = coords[vtx * dim + 1]; | ||
| auto z = coords[vtx * dim + 2]; | ||
| shape_field(vtx, 0, 0, MeshField::Mesh_Topology::Vertex) = f(x, y, z); | ||
| }); | ||
| if (order == 2) { | ||
| Kokkos::parallel_for( | ||
| mesh.nedges(), KOKKOS_LAMBDA(int edge) { | ||
| const auto left = edge2vtx[edge * 2]; | ||
| const auto right = edge2vtx[edge * 2 + 1]; | ||
| const auto x = (coords[left * dim] + coords[right * dim]) / 2.0; | ||
| const auto y = | ||
| (coords[left * dim + 1] + coords[right * dim + 1]) / 2.0; | ||
| const auto z = | ||
| (coords[left * dim + 2] + coords[right * dim + 2]) / 2.0; | ||
| shape_field(edge, 0, 0, MeshField::Mesh_Topology::Edge) = f(x, y, z); | ||
| }); | ||
| } | ||
| const auto numNodesPerElem = order == 2 ? 10 : 4; | ||
| Kokkos::View<double **> local_coords("", mesh.nelems() * numNodesPerElem, 4); | ||
| Kokkos::parallel_for( | ||
| "set", mesh.nelems() * numNodesPerElem, KOKKOS_LAMBDA(const int &i) { | ||
| const auto val = i % numNodesPerElem; | ||
| local_coords(i, 0) = (val == 0); | ||
| local_coords(i, 1) = (val == 1); | ||
| local_coords(i, 2) = (val == 2); | ||
| local_coords(i, 3) = (val == 3); | ||
| if constexpr (order == 2) { | ||
| if (val == 4) { | ||
| local_coords(i, 0) = 1 / 2.0; | ||
| local_coords(i, 1) = 1 / 2.0; | ||
| } else if (val == 5) { | ||
| local_coords(i, 1) = 1 / 2.0; | ||
| local_coords(i, 2) = 1 / 2.0; | ||
| } else if (val == 6) { | ||
| local_coords(i, 0) = 1 / 2.0; | ||
| local_coords(i, 2) = 1 / 2.0; | ||
| } else if (val == 7) { | ||
| local_coords(i, 0) = 1 / 2.0; | ||
| local_coords(i, 3) = 1 / 2.0; | ||
| } else if (val == 8) { | ||
| local_coords(i, 1) = 1 / 2.0; | ||
| local_coords(i, 3) = 1 / 2.0; | ||
| } else if (val == 9) { | ||
| local_coords(i, 2) = 1 / 2.0; | ||
| local_coords(i, 3) = 1 / 2.0; | ||
| } | ||
| } | ||
| }); | ||
| auto eval_results = mesh_field.tetrahedronLocalPointEval( | ||
| local_coords, numNodesPerElem, shape_field); | ||
|
|
||
| int errors = 0; | ||
| const auto tetVerts = mesh.ask_elem_verts(); | ||
| const auto coordField = mesh_field.getCoordField(); | ||
| Kokkos::parallel_reduce( | ||
| "test", mesh.nelems(), | ||
| KOKKOS_LAMBDA(const int &tet, int &errors) { | ||
| for (int node = 0; node < 4; ++node) { | ||
| const auto tetDim = 3; | ||
| const auto vtxDim = 0; | ||
| const auto ignored = -1; | ||
| const auto localVtxIdx = | ||
| Omega_h::simplex_down_template(tetDim, vtxDim, node, ignored); | ||
| const auto tetToVtxDegree = Omega_h::simplex_degree(tetDim, vtxDim); | ||
| int vtx = tetVerts[(tet * tetToVtxDegree) + localVtxIdx]; | ||
| auto x = coords[vtx * dim]; | ||
| auto y = coords[vtx * dim + 1]; | ||
| auto z = coords[vtx * dim + 2]; | ||
| auto expected = f(x, y, z); | ||
| auto actual = eval_results(tet * numNodesPerElem + node, 0); | ||
| if (Kokkos::fabs(expected - actual) > MeshField::MachinePrecision) { | ||
| ++errors; | ||
|
|
||
| Kokkos::printf( | ||
| "expected: %lf, actual: %lf, element: %d, node(vtx): %d\n", | ||
| expected, actual, tet, node); | ||
| } | ||
| } | ||
| for (int node = 4; node < numNodesPerElem; ++node) { | ||
| const auto tetDim = 3; | ||
| const auto edgeDim = 1; | ||
| const auto tetToEdgeDegree = Omega_h::simplex_degree(tetDim, edgeDim); | ||
| const MeshField::LO tetNode2DofHolder[6] = {0, 1, 2, 3, 4, 5}; | ||
| int edge = | ||
| edgeMap[(tet * tetToEdgeDegree) + tetNode2DofHolder[node - 4]]; | ||
| auto left = edge2vtx[edge * 2]; | ||
| auto right = edge2vtx[edge * 2 + 1]; | ||
| const auto x = (coords[left * dim] + coords[right * dim]) / 2.0; | ||
| const auto y = | ||
| (coords[left * dim + 1] + coords[right * dim + 1]) / 2.0; | ||
| const auto z = | ||
| (coords[left * dim + 2] + coords[right * dim + 2]) / 2.0; | ||
| auto expected = f(x, y, z); | ||
| auto actual = eval_results(tet * numNodesPerElem + node, 0); | ||
| if (Kokkos::fabs(expected - actual) > MeshField::MachinePrecision) { | ||
| ++errors; | ||
| Kokkos::printf( | ||
| "expected: %lf, actual: %lf, element: %d, node(edge): %d\n", | ||
| expected, actual, tet, node); | ||
| } | ||
| } | ||
| }, | ||
| errors); | ||
| if (errors > 0) { | ||
| MeshField::fail("One or more mappings did not match\n"); | ||
| } | ||
| } | ||
|
|
||
| int main(int argc, char **argv) { | ||
| Kokkos::initialize(argc, argv); | ||
| auto lib = Omega_h::Library(&argc, &argv); | ||
| { | ||
| auto world = lib.world(); | ||
| auto mesh = | ||
| Omega_h::build_box(world, OMEGA_H_SIMPLEX, 1, 1, 1, 10, 10, 10, false); | ||
| runTest<1>(mesh); | ||
| runTest<2>(mesh); | ||
| } | ||
| Kokkos::finalize(); | ||
| return 0; | ||
| } | ||
Check notice
Code scanning / CodeQL
Large object passed by value Note
Copilot Autofix
AI 5 months ago
To fix the problem, we should change the parameter type of
fieldin the functiontetrahedronLocalPointEval(lines 359–364) from being passed by value to being passed by const reference. This means changing the function signature fromShapeField fieldtoconst ShapeField& field. This change should be made in both the declaration and the definition of the function template. Since the function is a template, this change will not affect its usage elsewhere, as template argument deduction will still work. No other code changes are needed unless there are other overloads or calls that rely on the value semantics, but from the provided snippet, this is not the case.