Skip to content
Open
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
4e47613
Merge pull request #3 from SimVascular/main
zasexton Jun 9, 2025
3bdfb91
Merge branch 'SimVascular:main' into main
zasexton Aug 26, 2025
3fb5364
Merge branch 'SimVascular:main' into main
zasexton Sep 18, 2025
4749c70
Merge branch 'SimVascular:main' into main
zasexton Oct 6, 2025
47a7985
Merge branch 'SimVascular:main' into main
zasexton Oct 27, 2025
2d4f8ed
Merge pull request #5 from SimVascular/main
zasexton Nov 11, 2025
1154fe8
Merge branch 'SimVascular:main' into main
zasexton Jan 5, 2026
690a92c
Merge branch 'SimVascular:main' into main
zasexton Feb 27, 2026
e6dd7e9
Merge branch 'SimVascular:main' into main
zasexton Mar 25, 2026
b831ea1
Merge branch 'SimVascular:main' into main
zasexton Apr 8, 2026
1e117c2
Merge branch 'SimVascular:main' into main
zasexton Apr 21, 2026
35cc8fe
Merge branch 'SimVascular:main' into main
zasexton Apr 30, 2026
42b23df
Merge branch 'SimVascular:main' into main
zasexton May 12, 2026
f412876
Merge branch 'SimVascular:main' into main
zasexton May 26, 2026
3a6af11
Merge branch 'SimVascular:main' into main
zasexton Jun 1, 2026
c5e934f
Merge branch 'SimVascular:main' into main
zasexton Jul 1, 2026
b34bfb3
Merge branch 'SimVascular:main' into main
zasexton Jul 1, 2026
a2f1677
Define the FE Quadrature module boundary
zasexton Jul 22, 2026
a07b87b
Add immutable reference-space quadrature rules
zasexton Jul 22, 2026
fbf3630
Establish Quadrature Phase 01 baselines
zasexton Jul 22, 2026
6110849
Run API documentation from the repository root
zasexton Jul 22, 2026
593f765
Polish quadrature validation result handling
zasexton Jul 22, 2026
4449885
Simplify reference-cell validation
zasexton Jul 23, 2026
454c7dd
Use FE vectors for quadrature points
zasexton Jul 23, 2026
f9ec988
Separate quadrature dimensions and zeroth moment
zasexton Jul 23, 2026
2e48f4c
Inline binary64 weight accumulation
zasexton Jul 23, 2026
0b4d7bf
Simplify quadrature validation diagnostics
zasexton Jul 23, 2026
02aff30
Keep quadrature validation policy internal
zasexton Jul 23, 2026
bad9188
Remove redundant reference measure alias
zasexton Jul 23, 2026
752bbee
Clarify the quadrature rule contract
zasexton Jul 23, 2026
fba6733
Simplify quadrature rule validation
zasexton Jul 23, 2026
b1433cb
Use exact summation for quadrature validation
zasexton Jul 23, 2026
ce8ca07
fixing spacing for exact binary summation
zasexton Jul 23, 2026
d66e30c
Document binary64 validation assumptions
zasexton Jul 24, 2026
e8d3680
Qualify quadrature vector include
zasexton Jul 24, 2026
42c9e9e
Use reference cell measure terminology
zasexton Jul 24, 2026
4feee78
Complete reference cell measure documentation
zasexton Jul 24, 2026
6fb1dad
Focus quadrature tests on new infrastructure
zasexton Jul 24, 2026
970f3c0
Merge branch 'main' into quadrature-P01
zasexton Jul 24, 2026
dbc6a6c
Pass quadrature construction data directly
zasexton Jul 28, 2026
ae426e8
Inline reference cell metadata validation
zasexton Jul 28, 2026
49d0568
Derive quadrature dimension from cell family
zasexton Jul 28, 2026
ee8a927
Make QuadratureRule a concrete value type
zasexton Jul 28, 2026
fe657df
Flatten quadrature rule validation
zasexton Jul 28, 2026
c0beffd
Simplify quadrature weight summation
zasexton Jul 29, 2026
30bfaa9
Reduce quadrature point validation
zasexton Jul 29, 2026
a719342
Derive reference-cell measure from family
zasexton Jul 29, 2026
1c28f9e
Merge branch 'main' into quadrature-P01
zasexton Jul 29, 2026
413acf3
Condense quadrature rule documentation
zasexton Jul 29, 2026
6264ee9
Merge remote-tracking branch 'origin/quadrature-P01' into quadrature-P01
zasexton Jul 30, 2026
d7172e0
Limit quadrature validation to structure
zasexton Aug 17, 2026
2b59827
Make QuadratureRule an abstract base
zasexton Aug 18, 2026
991aea3
Merge branch 'main' into quadrature-P01
zasexton Aug 20, 2026
3c3163e
Keep CMake documentation in build tree
zasexton Aug 20, 2026
a4e14cc
Align reference-cell table
zasexton Aug 20, 2026
5ee42cb
Clarify quadrature construction requirements
zasexton Aug 20, 2026
261e66d
Document construction-time validation
zasexton Aug 20, 2026
8c6735a
Raise on unsupported cell families
zasexton Aug 20, 2026
7c74acf
Use size type for reference dimensions
zasexton Aug 20, 2026
ec18918
Iterate over quadrature point size
zasexton Aug 20, 2026
f41839c
Inline quadrature data validation
zasexton Aug 20, 2026
0fb7416
Demonstrate concrete quadrature construction
zasexton Aug 20, 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
8 changes: 5 additions & 3 deletions Code/CMake/SimVascularExternals.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ find_package(Doxygen)
if(DOXYGEN_FOUND)
file(TO_NATIVE_PATH "${SV_BINARY_DIR}/Doxygen/" SV_DOCS_DIR_WORK)
set(SV_DOCS_DIR ${SV_DOCS_DIR_WORK} CACHE PATH "Location to place docs")
configure_file(${SV_SOURCE_DIR}/../Documentation/Doxyfile
configure_file(${SV_SOURCE_DIR}/../Documentation/Doxyfile.cmake.in
${SV_BINARY_DIR}/Doxyfile @ONLY)
add_custom_target(doc
${DOXYGEN_EXECUTABLE} ${SV_BINARY_DIR}/Doxyfile
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMAND "${CMAKE_COMMAND}" -E remove_directory
"${SV_DOCS_DIR}"
COMMAND "${DOXYGEN_EXECUTABLE}" "${SV_BINARY_DIR}/Doxyfile"
WORKING_DIRECTORY "${SV_SOURCE_DIR}/.."
Comment on lines +12 to +15

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.

If I understand this right, the purpose of this is to fix the make doc recipe (whereas as of now the documentation would have to be built by calling doxygen manually from the repository root folder). Is this correct?

If so, is the documentation now generated into the build folder, or into the source folder as in the current main branch?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The changes here should remove any stale documents generated prior to regenerating a doxygen build but they should not be relocating the written destination of generated. The Documentation/build is still the appropriate target location since this is used by current github actions.

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.

Thanks for clarifying. I understand this is the current state of the GitHub pipelines (and that it is unrelated to this PR), but.

In my local installation, running make doc from build/svMultiPhysics-build fails to generate the documentation. If I interpret the error correctly, this is because there is a mismatch between the paths used in the Doxyfile and the paths that make doc runs with. This command changes the target so that make doc runs doxygen from the repository's source directory, so I believe that these issues should be fixed.

Having said all this, do you know the rationale behind generating the documentation in a separate build folder, rather than in the already existing, CMake-configured build folder? I would think the latter to be the more natural thing to do, and I'm generally wary of situations where running make in a folder generates/modifies files outside of that folder.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I think this is a combination of my changes and the existing paths... I think the mismatch with make doc might have already been around, but yes this should definitely be addressed. I'll make sure that we are generating within the already built folder

COMMENT "Generating API documentation with Doxygen" VERBATIM
)
endif(DOXYGEN_FOUND)
Expand Down
6 changes: 6 additions & 0 deletions Code/Source/solver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -267,11 +267,17 @@ file(GLOB SOLVER_FE_MATH_SRCS CONFIGURE_DEPENDS
FE/Math/*.h
)

file(GLOB SOLVER_FE_QUADRATURE_SRCS CONFIGURE_DEPENDS
FE/Quadrature/*.cpp
FE/Quadrature/*.h
)

list(APPEND CSRCS
${SOLVER_CORE_SRCS}
${SOLVER_FE_COMMON_SRCS}
${SOLVER_FE_BASIS_SRCS}
${SOLVER_FE_MATH_SRCS}
${SOLVER_FE_QUADRATURE_SRCS}
)
Comment thread
zasexton marked this conversation as resolved.

# Set PETSc interace code.
Expand Down
28 changes: 7 additions & 21 deletions Code/Source/solver/FE/Common/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,9 @@ enum class CellFamily {
* @brief Shared vocabulary types, constants, and exception infrastructure used by every FE module.
*
* @details The Common module collects the foundational definitions that the
* rest of the FE library builds on: index and scalar type aliases; element,
* basis, quadrature, and field enumerations; sentinel constants and strong
* type wrappers; and the FE exception hierarchy together with its
* argument-checking helpers.
* rest of the FE library builds on: index and scalar type aliases; shared
* enumerations and strong types; sentinel constants; and the FE exception
* hierarchy together with its argument-checking helpers.
*/

namespace svmp::FE {
Expand All @@ -83,10 +82,10 @@ namespace svmp::FE {
* @brief Core type aliases, enumerations, constants, geometric types, and compile-time traits.
*
* @details This group documents the index and identifier types used for
* element-local and global numbering, the element/basis/quadrature/field
* enumerations shared across modules, sentinel constants, reference- and
* physical-space geometric aliases, and the strong-type utilities that
* prevent accidental mixing of conceptually distinct values.
* element-local and global numbering, the enumerations shared across modules,
* sentinel constants, reference- and physical-space geometric aliases, and
* the strong-type utilities that prevent accidental mixing of conceptually
* distinct values.
* @{
*/

Expand Down Expand Up @@ -242,19 +241,6 @@ enum class ElementType : std::uint8_t {
Unknown ///< Unrecognized or uninitialized element type
};

/**
* @brief Quadrature rule types
*/
enum class QuadratureType : std::uint8_t {
GaussLegendre, ///< Standard Gaussian quadrature
GaussLobatto, ///< Includes endpoints (for spectral elements)
Newton, ///< Newton-Cotes rules
Reduced, ///< Order-based reduced integration for locking
PositionBased, ///< Position-based reduced integration (legacy compatible)
Composite, ///< Composite rules for adaptivity
Custom ///< User-defined quadrature points
};

/**
* @brief Basis function families
*/
Expand Down
3 changes: 2 additions & 1 deletion Code/Source/solver/FE/FE.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
* This header intentionally contains no declarations. It gives Doxygen a
* header-based home for the top-level FE group; submodule groups attach to it
* from their own headers, including FE_Basis (Basis/BasisFunction.h),
* FE_Common (Common/Types.h), and FE_Math (Math/Vector.h).
* FE_Common (Common/Types.h), FE_Math (Math/Vector.h), and FE_Quadrature
* (Quadrature/QuadratureRule.h).
*/

/**
Expand Down
131 changes: 131 additions & 0 deletions Code/Source/solver/FE/Quadrature/QuadratureRule.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// SPDX-FileCopyrightText: Copyright (c) Stanford University, The Regents of the University of California, and others.
// SPDX-License-Identifier: BSD-3-Clause

/**
* @file QuadratureRule.cpp
* @brief Internal construction and structural validation for quadrature rules.
* @ingroup FE_Quadrature
*/

#include "FE/Quadrature/QuadratureRule.h"

#include "FE/Common/FEException.h"

#include <cmath>
#include <string>
#include <utility>

namespace svmp::FE::quadrature {
namespace {

std::size_t reference_dimension(svmp::CellFamily family)
{
switch (family) {
case svmp::CellFamily::Point:
return 0u;
case svmp::CellFamily::Line:
return 1u;
case svmp::CellFamily::Triangle:
case svmp::CellFamily::Quad:
return 2u;
case svmp::CellFamily::Tetra:
case svmp::CellFamily::Hex:
case svmp::CellFamily::Wedge:
return 3u;
default:
svmp::raise<InvalidArgumentException>(
"QuadratureRule: unsupported reference-cell family");
}
}

double reference_measure(svmp::CellFamily family)
{
switch (family) {
case svmp::CellFamily::Point:
return 1.0;
case svmp::CellFamily::Line:
return 2.0;
case svmp::CellFamily::Triangle:
return 0.5;
case svmp::CellFamily::Quad:
return 4.0;
case svmp::CellFamily::Tetra:
return 1.0 / 6.0;
case svmp::CellFamily::Hex:
return 8.0;
case svmp::CellFamily::Wedge:
return 1.0;
default:
svmp::raise<InvalidArgumentException>(
"QuadratureRule: unsupported reference-cell family");
}
}

} // namespace

QuadratureRule::~QuadratureRule() = default;

std::size_t QuadratureRule::dimension() const
{
return reference_dimension(cell_family_);
}

double QuadratureRule::reference_cell_measure() const
{
return reference_measure(cell_family_);
}

QuadratureRule::QuadratureRule(
svmp::CellFamily family,
int polynomial_exactness,
std::vector<QuadPoint> points,
std::vector<double> weights)
: cell_family_(family),
polynomial_exactness_(polynomial_exactness),
points_(std::move(points)),
weights_(std::move(weights))
{
const std::size_t dimension = reference_dimension(cell_family_);
svmp::check<InvalidArgumentException>(
polynomial_exactness_ >= 0,
"QuadratureRule: polynomial exactness must be non-negative");
svmp::check<InvalidArgumentException>(
!points_.empty(),
"QuadratureRule: a rule must contain at least one point");
svmp::check<InvalidArgumentException>(
points_.size() == weights_.size(),
"QuadratureRule: points/weights size mismatch");

for (std::size_t point_index = 0;
point_index < points_.size();
++point_index) {
const QuadPoint& point = points_[point_index];
for (std::size_t component = 0;
component < point.size();
++component) {
if (!std::isfinite(point[component])) {
svmp::raise<InvalidArgumentException>(
std::string{
"QuadratureRule: quadrature point contains a non-finite "
"coordinate at point index "} +
std::to_string(point_index));
}
if (component >= dimension && point[component] != 0.0) {
svmp::raise<InvalidArgumentException>(
std::string{
"QuadratureRule: quadrature point has a nonzero inactive "
"coordinate at point index "} +
std::to_string(point_index));
}
}
if (!std::isfinite(weights_[point_index])) {
svmp::raise<InvalidArgumentException>(
std::string{
"QuadratureRule: quadrature weight must be finite at point "
"index "} +
std::to_string(point_index));
}
}
}

} // namespace svmp::FE::quadrature
152 changes: 152 additions & 0 deletions Code/Source/solver/FE/Quadrature/QuadratureRule.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
// SPDX-FileCopyrightText: Copyright (c) Stanford University, The Regents of the University of California, and others.
// SPDX-License-Identifier: BSD-3-Clause

#ifndef SVMP_FE_QUADRATURE_RULE_H
#define SVMP_FE_QUADRATURE_RULE_H

/**
* @file QuadratureRule.h
* @brief Abstract base for reference-space quadrature rules.
* @ingroup FE_Quadrature
*/

/**
* @defgroup FE_Quadrature Quadrature
* @ingroup FE
* @brief Integration rules on canonical reference cells.
*
* @details
* A QuadratureRule owns ordered reference coordinates and weights for
* @f[
* \int_{\hat K} f(\hat x)\,d\hat x
* \approx \sum_q w_q f(\hat x_q).
* @f]
* Supported families use these canonical reference cells:
*
* | Family | Reference cell | Measure |
* |----------|-------------------------------------------|-----------|
* | Point | @f$(0,0,0)@f$ | @f$1@f$ |
* | Line | @f$[-1,1]@f$ | @f$2@f$ |
* | Triangle | @f$\{(x,y):x,y\geq0,\ x+y\leq1\}@f$ | @f$1/2@f$ |
* | Quad | @f$[-1,1]^2@f$ | @f$4@f$ |
* | Tetra | @f$\{(x,y,z):x,y,z\geq0,\ x+y+z\leq1\}@f$ | @f$1/6@f$ |
* | Hex | @f$[-1,1]^3@f$ | @f$8@f$ |
* | Wedge | unit triangle @f$\times[-1,1]@f$ | @f$1@f$ |
*
* The family therefore determines both reference dimension and cell measure.
* Quadrature points are not required to lie inside the reference cell.
* Generating code is responsible for verifying weight normalization and
* declared polynomial exactness through analytic moment tests.
*/

#include "FE/Common/Types.h"
#include "FE/Math/Vector.h"

#include <cstddef>
#include <vector>

namespace svmp::FE::quadrature {

/** @addtogroup FE_Quadrature
* @{
*/

/**
* @brief Three-component coordinate used for every reference quadrature point.
*
* Only the first QuadratureRule::dimension() components are active; remaining
* components must be zero.
*/
using QuadPoint = math::Vector<double, 3>;

/**
* @brief Owning abstract base for quadrature rules on canonical reference cells.
*
* Construction requires:
*
* - a supported cell family and non-negative polynomial exactness;
* - a vector of points, with at least one element;
* - for all points, coordinates must be finite;
* - for all points, coordinates beyond the reference dimension of the cell
* family must be equal to zero; and
* - a vector of finite weights, with as many elements as the points.
*
* The constructor checks each requirement and throws InvalidArgumentException
* when one is violated.
*
* Points may be duplicate or outside the reference cell, and weights may be
* zero or negative. Construction does not verify weight normalization or
* polynomial exactness.
*/
class QuadratureRule {
public:
/** @brief Enable polymorphic destruction of concrete quadrature rules. */
virtual ~QuadratureRule() = 0;

/** @brief Return the number of point/weight pairs. */
std::size_t num_points() const noexcept { return points_.size(); }

/** @brief Return the declared total-degree polynomial exactness. */
int polynomial_exactness() const noexcept { return polynomial_exactness_; }

/**
* @brief Return the reference dimension and active QuadPoint component count.
*/
std::size_t dimension() const;

/** @brief Return the canonical reference-cell family. */
svmp::CellFamily cell_family() const noexcept { return cell_family_; }

/**
* @brief Return point @p i without bounds checking.
* @pre @p i is less than num_points().
*/
const QuadPoint& point(std::size_t i) const noexcept { return points_[i]; }

/**
* @brief Return the weight paired with point @p i without bounds checking.
* @pre @p i is less than num_points().
*/
double weight(std::size_t i) const noexcept { return weights_[i]; }
Comment thread
zasexton marked this conversation as resolved.

/** @brief Return all points in integration order. */
const std::vector<QuadPoint>& points() const noexcept { return points_; }

/** @brief Return all weights in point order. */
const std::vector<double>& weights() const noexcept { return weights_; }

/** @brief Return the reference-cell measure derived from cell_family(). */
double reference_cell_measure() const;

protected:
/**
* @brief Initialize a concrete rule from complete point and weight data.
* @param family Reference-cell family; also determines dimension and measure.
* @param polynomial_exactness Declared total-degree polynomial exactness.
* @param points Ordered reference coordinates.
* @param weights Weights paired with @p points.
* @throws InvalidArgumentException If a construction requirement is violated.
*/
explicit QuadratureRule(
svmp::CellFamily family,
int polynomial_exactness,
std::vector<QuadPoint> points,
std::vector<double> weights);
Comment on lines +133 to +134

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.

  1. It'd be better to pass these by const reference, I think.
  2. Since points and weights are required to have the same size, wouldn't it be better to store them (or at least require the caller to provide them) as std::vector<std::pair<QuadPoint, double>> points_and_weights? This way, the same-size constraint would be impossible to violate. Should this be used for the data members as well, I think the overhead for access through the weight() and point() getters is essentially zero, while there'd be a bit more overhead for the vector accesses points and weights.


QuadratureRule(const QuadratureRule&) = default;
QuadratureRule(QuadratureRule&&) noexcept = default;
QuadratureRule& operator=(const QuadratureRule&) = default;
QuadratureRule& operator=(QuadratureRule&&) noexcept = default;

private:
svmp::CellFamily cell_family_; ///< Canonical reference topology.
int polynomial_exactness_; ///< Exactness declared by the generator.
std::vector<QuadPoint> points_; ///< Ordered reference coordinates.
std::vector<double> weights_; ///< Weights paired with points_.
};

/** @} */

} // namespace svmp::FE::quadrature

#endif // SVMP_FE_QUADRATURE_RULE_H
5 changes: 5 additions & 0 deletions Documentation/Doxyfile.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# SPDX-FileCopyrightText: Copyright (c) Stanford University, The Regents of the University of California, and others.
# SPDX-License-Identifier: BSD-3-Clause

@INCLUDE = "@SV_SOURCE_DIR@/../Documentation/Doxyfile"
OUTPUT_DIRECTORY = "@SV_DOCS_DIR@"
Loading
Loading