Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
4f0f46c
core of the solvegroup api
fractalsbyx Dec 8, 2025
48c5fa9
added a necessary function to check if an aux group is present
fractalsbyx Dec 11, 2025
d5b174d
add validity checking to dependency utility
fractalsbyx Dec 11, 2025
6a82b6b
intermediate
fractalsbyx Dec 12, 2025
097b6aa
most of solution handler and dof manager
fractalsbyx Dec 14, 2025
68ceb65
triangulation manager
fractalsbyx Dec 14, 2025
a3ffcc2
solution manager mostly complete
fractalsbyx Dec 15, 2025
7f3ad20
intermediate
fractalsbyx Dec 15, 2025
b36881a
intermediate
fractalsbyx Dec 16, 2025
76719dc
much of constraint manager
fractalsbyx Dec 16, 2025
32a6872
constraint manager touch ups
fractalsbyx Dec 17, 2025
d0c0781
started explicit
fractalsbyx Dec 17, 2025
01972c9
poco
fractalsbyx Dec 17, 2025
4cedeb0
solution indexer
fractalsbyx Dec 18, 2025
a5f3b13
work mostly on mf operator and field container
fractalsbyx Dec 18, 2025
030635f
field container gets and sets
fractalsbyx Dec 18, 2025
4ea4158
intermediate
fractalsbyx Dec 19, 2025
b765c12
Intermediate
fractalsbyx Dec 19, 2025
04ae4d4
inter
fractalsbyx Dec 22, 2025
155c84a
bleh
fractalsbyx Dec 22, 2025
aca80a0
red
fractalsbyx Dec 23, 2025
826e38d
misc
fractalsbyx Jan 5, 2026
7b6cf07
more container stuff
fractalsbyx Jan 5, 2026
13e0c81
more dst container things
fractalsbyx Jan 7, 2026
ac5c872
interm
fractalsbyx Jan 7, 2026
b6a2393
more
fractalsbyx Jan 8, 2026
aa77fe1
moved solve implementation to headers for my sanity
fractalsbyx Jan 9, 2026
31ba76a
clean up solvers
fractalsbyx Jan 9, 2026
dfe4eff
multigrid outline
fractalsbyx Jan 10, 2026
ae87eb8
sdmfkmdsfak
fractalsbyx Feb 9, 2026
50caf13
oops
fractalsbyx Feb 11, 2026
ce0d66c
today
fractalsbyx Feb 11, 2026
82ee938
sigh
fractalsbyx Feb 13, 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
10 changes: 10 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ CheckOptions:
- key: readability-function-cognitive-complexity.IgnoreMacros
value: 'true'

# Ignore bool conversion
- key: readability-implicit-bool-conversion.AllowIntegerConditions
value: 'true'
- key: readability-implicit-bool-conversion.AllowPointerConditions
value: 'true'

# Structs are meant to be public
- key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
value: 'true'

# Naming conventions
- key: readability-identifier-naming.ClassCase
value: CamelCase
Expand Down
222 changes: 222 additions & 0 deletions include/prismspf/core/constraint_manager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
// SPDX-FileCopyrightText: © 2025 PRISMS Center at the University of Michigan
// SPDX-License-Identifier: GNU Lesser General Public Version 2.1

#pragma once

#include <deal.II/base/mg_level_object.h>
#include <deal.II/dofs/dof_handler.h>
#include <deal.II/fe/mapping.h>
#include <deal.II/lac/affine_constraints.h>

#include <prismspf/core/dof_manager.h>
#include <prismspf/core/field_attributes.h>
#include <prismspf/core/pde_operator.h>
#include <prismspf/core/solve_group.h>
#include <prismspf/core/type_enums.h>

#include <prismspf/user_inputs/boundary_parameters.h>
#include <prismspf/user_inputs/user_input_parameters.h>

#include <prismspf/config.h>

#include "prismspf/core/types.h"

PRISMS_PF_BEGIN_NAMESPACE

// TODO (fractalsbyx): The following snippet is from dealii. Using this (by
// pre-constructing the needed maps and functions) may be cleaner than how dirichlet are
// currently done.
/* template <int dim, int spacedim, typename number>
void
interpolate_boundary_values(
const Mapping<dim, spacedim> &mapping,
const DoFHandler<dim, spacedim> &dof,
const std::map<types::boundary_id, const Function<spacedim, number> *>
&function_map,
AffineConstraints<number> &constraints,
const ComponentMask &component_mask = {}); */

// TODO (fractalsbyx): This class seems to parallel DofManager quite a bit. Consider
// merging them?
/**
* @brief The class handles the generation and application of boundary conditions based on
* the user-inputs.
*/
template <unsigned int dim, unsigned int degree, typename number>
class ConstraintManager
{
public:
/**
* @brief Constructor.
*/
ConstraintManager(const std::vector<FieldAttributes> &field_attributes,
const std::set<SolveGroup> &solve_groups,
const DofManager<dim> &_dof_manager,
const PDEOperator<dim, degree, number> &_pde_operator);

/**
* @brief Getter function for the constraints.
*/
[[nodiscard]] std::vector<const dealii::AffineConstraints<number> *>
get_constraints(const std::set<unsigned int> &field_indices,
unsigned int relative_level = 0) const;

/**
* @brief Getter function for the constraint of an index (constant reference).
*/
[[nodiscard]] const dealii::AffineConstraints<number> &
get_constraint(Types::Index index, unsigned int relative_level = 0) const;

/**
* @brief Getter function for the constraints.
*/
[[nodiscard]] std::vector<const dealii::AffineConstraints<number> *>
get_change_constraints(const std::set<unsigned int> &field_indices,
unsigned int relative_level = 0) const;

/**
* @brief Getter function for the constraint of an index (constant reference).
*/
[[nodiscard]] const dealii::AffineConstraints<number> &
get_change_constraint(Types::Index index, unsigned int relative_level = 0) const;

/**
* @brief Make constraints based on the inputs of the constructor.
*/
void
reinit(const dealii::Mapping<dim> &mapping);

/**
* @brief Update time-dependent constraints.
* For now this only updates the non-uniform dirichlet constraints.
*/
void
update_time_dependent_constraints(
const dealii::Mapping<dim> &mapping,
const std::vector<const dealii::DoFHandler<dim> *> &dof_handlers);

private:
/**
* @brief Create a component mask.
*/
static const std::array<dealii::ComponentMask, dim> vector_component_mask;
static const dealii::ComponentMask scalar_empty_mask;

/**
* @brief Add boundary conditions to a single constraint.
*/
void
make_bc_constraints(dealii::AffineConstraints<number> &constraint,
const dealii::Mapping<dim> &mapping,
const dealii::DoFHandler<dim> &dof_handler,
const std::map<unsigned int, BoundaryCondition> &boundary_condition,
FieldInfo::TensorRank tensor_rank,
Types::Index field_index,
bool for_change_term = false);

/**
* @brief Apply constraints for common boundary conditions.
*/
void
make_one_boundary_constraint(dealii::AffineConstraints<number> &_constraints,
unsigned int boundary_id,
unsigned int component,
BoundaryCondition::Type boundary_type,
number dirichlet_value,
const dealii::Mapping<dim> &mapping,
const dealii::DoFHandler<dim> &dof_handler,
FieldInfo::TensorRank tensor_rank,
Types::Index field_index,
bool for_change_term = false) const;

/**
* @brief Apply natural constraints.
*/
void
make_natural_constraints() const;

/**
* @brief make dirichlet constraints.
*/
void
make_uniform_dirichlet_constraints(dealii::AffineConstraints<number> &_constraints,
const dealii::Mapping<dim> &mapping,
const dealii::DoFHandler<dim> &dof_handler,
const unsigned int &boundary_id,
const bool &is_vector_field,
const number &value,

const dealii::ComponentMask &mask) const;

/**
* @brief make nonuniform dirichlet constraints.
*/
void
make_nonuniform_dirichlet_constraints(dealii::AffineConstraints<number> &_constraints,
const dealii::Mapping<dim> &mapping,
const dealii::DoFHandler<dim> &dof_handler,
const unsigned int &boundary_id,
const unsigned int &field_index,
const bool &is_vector_field,
const dealii::ComponentMask &mask,
bool is_change_term = false) const;

/**
* @brief make periodic constraints.
*/
void
make_periodic_constraints(dealii::AffineConstraints<number> &_constraints,
const dealii::DoFHandler<dim> &dof_handler,
const unsigned int &boundary_id,
const dealii::ComponentMask &mask) const;

/**
* @brief Set the dirichlet constraint for the pinned point.
*/
void
set_pinned_point(dealii::AffineConstraints<number> &constraint,
const dealii::Point<dim> &target_point,
const std::array<number, dim> &value,
const dealii::DoFHandler<dim> &dof_handler,
FieldInfo::TensorRank tensor_rank,
bool is_change_term = false) const;

/**
* @brief User-inputs.
*/
const UserInputParameters<dim> *user_inputs;

/**
* @brief Dof manager pointer.
*/
std::shared_ptr<const DofManager<dim>> dof_manager;

/**
* @brief PDE operator number.
*/
std::shared_ptr<const PDEOperator<dim, degree, number>> pde_operator;

/**
* @brief Whether we have multigrid.
*/
bool has_multigrid = false;

/**
* @brief Global minimum level for multigrid.
*/
unsigned int global_min_level = 0;

/**
* @brief Constraints. Outer vector is indexed by field index. Inner vector is indexed
* by relative mg level.
*/
std::vector<std::vector<std::shared_ptr<dealii::AffineConstraints<float>>>> constraints;
/**
* @brief Constraints for Newton-Change solutions. Outer vector is indexed by field
* index. Inner vector is indexed by relative mg level.
*/
std::vector<std::vector<std::shared_ptr<dealii::AffineConstraints<float>>>>
change_constraints;
};

PRISMS_PF_END_NAMESPACE
Loading
Loading