Skip to content

Commit 1a475b5

Browse files
authored
Merge pull request #4368 from ChengHauYang/project_vector_solution
Allow specifying element range in project_vector/project_solution
2 parents 502d428 + 75159ac commit 1a475b5

6 files changed

Lines changed: 436 additions & 68 deletions

File tree

include/numerics/wrapped_functor.h

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,28 @@ class WrappedFunctor : public FEMFunctionBase<Output>
123123
template <typename Output>
124124
void WrappedFunctor<Output>::init_context (const FEMContext & c)
125125
{
126-
for (auto dim : c.elem_dimensions())
126+
// If the context was constructed with an active var subset (e.g. projector
127+
// projecting only selected variables), then only those FE objects are
128+
// guaranteed to exist.
129+
const std::vector<unsigned int> * active = c.active_vars();
130+
131+
auto check_and_init = [&c](unsigned int v, unsigned short dim)
132+
{
133+
FEAbstract * fe = nullptr;
134+
c.get_element_fe(v, fe, dim);
135+
libmesh_assert_msg(fe, "FEAbstract pointer is null for variable "
136+
<< v << " in dimension " << dim);
137+
fe->get_nothing();
138+
};
139+
140+
for (const auto dim : c.elem_dimensions())
127141
{
128-
for (auto v : make_range(c.n_vars()))
129-
{
130-
FEAbstract * fe;
131-
c.get_element_fe(v, fe, dim);
132-
fe->get_nothing();
133-
}
142+
if (active)
143+
for (const auto v : *active)
144+
check_and_init(v, dim);
145+
else
146+
for (const auto v : make_range(c.n_vars()))
147+
check_and_init(v, dim);
134148
}
135149
}
136150

include/systems/system.h

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <string_view>
4141
#include <vector>
4242
#include <memory>
43+
#include <optional>
4344

4445
// This define may be useful in --disable-optional builds when it is
4546
// possible that libmesh will not have any solvers available.
@@ -514,19 +515,31 @@ class System : public ReferenceCountedObject<System>,
514515
* user-provided cloneable functors.
515516
* A gradient \p g is only required/used for projecting onto finite
516517
* element spaces with continuous derivatives.
518+
* elem_range \p active_local_range, if provided, indicates the range of elements
519+
* over which to perform the projection.
520+
* variable_numbers \p variable_numbers, if provided, indicates the variable numbers
521+
* onto which to project.
517522
*/
518523
void project_solution (FunctionBase<Number> * f,
519-
FunctionBase<Gradient> * g = nullptr) const;
524+
FunctionBase<Gradient> * g = nullptr,
525+
std::optional<ConstElemRange> active_local_range = std::nullopt,
526+
std::optional<std::vector<unsigned int>> variable_numbers = std::nullopt) const;
520527

521528
/**
522529
* Projects arbitrary functions onto the current solution.
523530
* The function value \p f and its gradient \p g are
524531
* user-provided cloneable functors.
525532
* A gradient \p g is only required/used for projecting onto finite
526533
* element spaces with continuous derivatives.
534+
* elem_range \p active_local_range, if provided, indicates the range of elements
535+
* over which to perform the projection.
536+
* variable_numbers \p variable_numbers, if provided, indicates the variable numbers
537+
* onto which to project.
527538
*/
528539
void project_solution (FEMFunctionBase<Number> * f,
529-
FEMFunctionBase<Gradient> * g = nullptr) const;
540+
FEMFunctionBase<Gradient> * g = nullptr,
541+
std::optional<ConstElemRange> active_local_range = std::nullopt,
542+
std::optional<std::vector<unsigned int>> variable_numbers = std::nullopt) const;
530543

531544
/**
532545
* Projects arbitrary functions onto the current solution.
@@ -545,7 +558,9 @@ class System : public ReferenceCountedObject<System>,
545558
const std::string & unknown_name);
546559
void project_solution (ValueFunctionPointer fptr,
547560
GradientFunctionPointer gptr,
548-
const Parameters & parameters) const;
561+
const Parameters & parameters,
562+
std::optional<ConstElemRange> active_local_range = std::nullopt,
563+
std::optional<std::vector<unsigned int>> variable_numbers = std::nullopt) const;
549564

550565
/**
551566
* Projects arbitrary functions onto a vector of degree of freedom
@@ -554,14 +569,20 @@ class System : public ReferenceCountedObject<System>,
554569
* user-provided cloneable functors.
555570
* A gradient \p g is only required/used for projecting onto finite
556571
* element spaces with continuous derivatives.
572+
* elem_range \p active_local_range, if provided, indicates the range of elements
573+
* over which to perform the projection.
574+
* variable_numbers \p variable_numbers, if provided, indicates the variable numbers
575+
* onto which to project.
557576
*
558577
* Constrain the new vector using the requested adjoint rather than
559578
* primal constraints if is_adjoint is non-negative.
560579
*/
561580
void project_vector (NumericVector<Number> & new_vector,
562581
FunctionBase<Number> * f,
563582
FunctionBase<Gradient> * g = nullptr,
564-
int is_adjoint = -1) const;
583+
int is_adjoint = -1,
584+
std::optional<ConstElemRange> active_local_range = std::nullopt,
585+
std::optional<std::vector<unsigned int>> variable_numbers = std::nullopt) const;
565586

566587
/**
567588
* Projects arbitrary functions onto a vector of degree of freedom
@@ -570,14 +591,20 @@ class System : public ReferenceCountedObject<System>,
570591
* user-provided cloneable functors.
571592
* A gradient \p g is only required/used for projecting onto finite
572593
* element spaces with continuous derivatives.
594+
* elem_range \p active_local_range, if provided, indicates the range of elements
595+
* over which to perform the projection.
596+
* variable_numbers \p variable_numbers, if provided, indicates the variable numbers
597+
* onto which to project.
573598
*
574599
* Constrain the new vector using the requested adjoint rather than
575600
* primal constraints if is_adjoint is non-negative.
576601
*/
577602
void project_vector (NumericVector<Number> & new_vector,
578603
FEMFunctionBase<Number> * f,
579604
FEMFunctionBase<Gradient> * g = nullptr,
580-
int is_adjoint = -1) const;
605+
int is_adjoint = -1,
606+
std::optional<ConstElemRange> active_local_range = std::nullopt,
607+
std::optional<std::vector<unsigned int>> variable_numbers = std::nullopt) const;
581608

582609
/**
583610
* Projects arbitrary functions onto a vector of degree of freedom
@@ -586,6 +613,10 @@ class System : public ReferenceCountedObject<System>,
586613
* represented by function pointers.
587614
* A gradient \p gptr is only required/used for projecting onto
588615
* finite element spaces with continuous derivatives.
616+
* elem_range \p active_local_range, if provided, indicates the range of elements
617+
* over which to perform the projection.
618+
* variable_numbers \p variable_numbers, if provided, indicates the variable numbers
619+
* onto which to project.
589620
*
590621
* Constrain the new vector using the requested adjoint rather than
591622
* primal constraints if is_adjoint is non-negative.
@@ -594,7 +625,9 @@ class System : public ReferenceCountedObject<System>,
594625
GradientFunctionPointer gptr,
595626
const Parameters & parameters,
596627
NumericVector<Number> & new_vector,
597-
int is_adjoint = -1) const;
628+
int is_adjoint = -1,
629+
std::optional<ConstElemRange> active_local_range = std::nullopt,
630+
std::optional<std::vector<unsigned int>> variable_numbers = std::nullopt) const;
598631

599632
/**
600633
* Projects arbitrary boundary functions onto a vector of degree of
@@ -607,11 +640,14 @@ class System : public ReferenceCountedObject<System>,
607640
* user-provided cloneable functors.
608641
* A gradient \p g is only required/used for projecting onto finite
609642
* element spaces with continuous derivatives.
643+
* elem_range \p active_local_range, if provided, indicates the range of elements
644+
* over which to perform the projection.
610645
*/
611646
void boundary_project_solution (const std::set<boundary_id_type> & b,
612647
const std::vector<unsigned int> & variables,
613648
FunctionBase<Number> * f,
614-
FunctionBase<Gradient> * g = nullptr);
649+
FunctionBase<Gradient> * g = nullptr,
650+
std::optional<ConstElemRange> active_local_range = std::nullopt);
615651

616652
/**
617653
* Projects arbitrary boundary functions onto a vector of degree of
@@ -624,12 +660,15 @@ class System : public ReferenceCountedObject<System>,
624660
* represented by function pointers.
625661
* A gradient \p gptr is only required/used for projecting onto
626662
* finite element spaces with continuous derivatives.
663+
* elem_range \p active_local_range, if provided, indicates the range of elements
664+
* over which to perform the projection.
627665
*/
628666
void boundary_project_solution (const std::set<boundary_id_type> & b,
629667
const std::vector<unsigned int> & variables,
630668
ValueFunctionPointer fptr,
631669
GradientFunctionPointer gptr,
632-
const Parameters & parameters);
670+
const Parameters & parameters,
671+
std::optional<ConstElemRange> active_local_range = std::nullopt);
633672

634673
/**
635674
* Projects arbitrary boundary functions onto a vector of degree of
@@ -642,6 +681,8 @@ class System : public ReferenceCountedObject<System>,
642681
* user-provided cloneable functors.
643682
* A gradient \p g is only required/used for projecting onto finite
644683
* element spaces with continuous derivatives.
684+
* elem_range \p active_local_range, if provided, indicates the range of elements
685+
* over which to perform the projection.
645686
*
646687
* Constrain the new vector using the requested adjoint rather than
647688
* primal constraints if is_adjoint is non-negative.
@@ -651,7 +692,8 @@ class System : public ReferenceCountedObject<System>,
651692
NumericVector<Number> & new_vector,
652693
FunctionBase<Number> * f,
653694
FunctionBase<Gradient> * g = nullptr,
654-
int is_adjoint = -1) const;
695+
int is_adjoint = -1,
696+
std::optional<ConstElemRange> active_local_range = std::nullopt) const;
655697

656698
/**
657699
* Projects arbitrary boundary functions onto a vector of degree of
@@ -664,6 +706,8 @@ class System : public ReferenceCountedObject<System>,
664706
* represented by function pointers.
665707
* A gradient \p gptr is only required/used for projecting onto
666708
* finite element spaces with continuous derivatives.
709+
* elem_range \p active_local_range, if provided, indicates the range of elements
710+
* over which to perform the projection.
667711
*
668712
* Constrain the new vector using the requested adjoint rather than
669713
* primal constraints if is_adjoint is non-negative.
@@ -674,7 +718,8 @@ class System : public ReferenceCountedObject<System>,
674718
GradientFunctionPointer gptr,
675719
const Parameters & parameters,
676720
NumericVector<Number> & new_vector,
677-
int is_adjoint = -1) const;
721+
int is_adjoint = -1,
722+
std::optional<ConstElemRange> active_local_range = std::nullopt) const;
678723

679724
/**
680725
* \returns The system number.
@@ -1984,7 +2029,9 @@ class System : public ReferenceCountedObject<System>,
19842029
* primal constraints if is_adjoint is non-negative.
19852030
*/
19862031
void project_vector (NumericVector<Number> &,
1987-
int is_adjoint = -1) const;
2032+
int is_adjoint = -1,
2033+
std::optional<ConstElemRange> active_local_range = std::nullopt,
2034+
std::optional<std::vector<unsigned int>> variable_numbers = std::nullopt) const;
19882035

19892036
/**
19902037
* Projects the vector defined on the old mesh onto the
@@ -1996,7 +2043,9 @@ class System : public ReferenceCountedObject<System>,
19962043
*/
19972044
void project_vector (const NumericVector<Number> &,
19982045
NumericVector<Number> &,
1999-
int is_adjoint = -1) const;
2046+
int is_adjoint = -1,
2047+
std::optional<ConstElemRange> active_local_range = std::nullopt,
2048+
std::optional<std::vector<unsigned int>> variable_numbers = std::nullopt) const;
20002049

20012050
/**
20022051
* Whether this object should condense out constrained degrees of freedom

0 commit comments

Comments
 (0)