Line data Source code
1 : //* This file is part of the MOOSE framework
2 : //* https://mooseframework.inl.gov
3 : //*
4 : //* All rights reserved, see COPYRIGHT for full restrictions
5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 : //*
7 : //* Licensed under LGPL 2.1, please see LICENSE for details
8 : //* https://www.gnu.org/licenses/lgpl-2.1.html
9 :
10 : #pragma once
11 :
12 : // MOOSE includes
13 : #include "ElementUserObject.h"
14 :
15 : class ElementSubdomainModifierBase;
16 :
17 : class NodalPatchRecoveryBase : public ElementUserObject
18 : {
19 : public:
20 : static InputParameters validParams();
21 :
22 : NodalPatchRecoveryBase(const InputParameters & parameters);
23 :
24 : /**
25 : * Solve the least-squares problem. Use the fitted coefficients to calculate the value at the
26 : * requested point.
27 : *
28 : * @param p Point at which to compute the fitted value
29 : * @param elem_ids Ids of the elements in the patch
30 : * @return The fitted value
31 : */
32 : virtual Real nodalPatchRecovery(const Point & p, const std::vector<dof_id_type> & elem_ids) const;
33 :
34 : /**
35 : * Compute coefficients without reading or writing cached values
36 : * The coefficients returned by this function are intended to be multiplied with the multi-index
37 : * table to build the corresponding polynomial. For details on the multi-index table, refer to the
38 : * comments in the multiIndex() function.
39 : *
40 : * @param elem_ids Ids of the elements in the patch
41 : * @return The coefficients of the polynomial
42 : */
43 : const RealEigenVector getCoefficients(const std::vector<dof_id_type> & elem_ids) const;
44 :
45 : /**
46 : * Compute coefficients, using cached values if available, and store any newly computed
47 : * coefficients in cache
48 : * The coefficients returned by this function are intended to be multiplied with the multi-index
49 : * table to build the corresponding polynomial. For details on the multi-index table, refer to the
50 : * comments in the multiIndex() function.
51 : *
52 : * @param elem_ids Ids of the elements in the patch
53 : * @return The coefficients of the polynomial
54 : */
55 : const RealEigenVector getCachedCoefficients(const std::vector<dof_id_type> & elem_ids);
56 :
57 : void initialize() override;
58 : void execute() override;
59 : void threadJoin(const UserObject &) override;
60 : void finalize() override;
61 :
62 : /// Returns the multi-index table
63 765 : const std::vector<std::vector<unsigned int>> & multiIndex() const { return _multi_index; }
64 :
65 : protected:
66 : /// Compute the quantity to recover using nodal patch recovery
67 : virtual Real computeValue() = 0;
68 :
69 : unsigned int _qp;
70 :
71 : private:
72 : /// Builds a query map of element IDs that require data from other processors.
73 : /// This version of this method only checks data communication needs for a provided vector of elements.
74 : /// @param specific_elems Set of elements that we need the information about Ae and be (which may be own by current processor
75 : /// or need to be requested from another processor).
76 : /// @return Map of processor id to vector of non-local elements on the current processor that belong to
77 : /// that processor. Used to ensure that all non-local evaluable elements are properly synchronized
78 : std::unordered_map<processor_id_type, std::vector<dof_id_type>>
79 : gatherRequestList(const std::vector<dof_id_type> & specific_elems);
80 :
81 : /// Builds a query map of element IDs that require data from other processors.
82 : /// This version of this method iterates over all semi-local evaluable elements (including ghost elements)
83 : /// and records those belonging to a different processor and request from them.
84 : /// @return Map of processor id to vector of semilocal elements on the current processor that belong to
85 : /// that processor. Used to ensure that all semi-local evaluable elements are properly synchronized
86 : std::unordered_map<processor_id_type, std::vector<dof_id_type>> gatherRequestList();
87 :
88 : /**
89 : * Compute the P vector at a given point
90 : * i.e. given dim = 2, order = 2, polynomial P has the following terms:
91 : * 1
92 : * x
93 : * y
94 : * x^2
95 : * xy
96 : * y^2
97 : *
98 : * @param q_point point at which to evaluate the polynomial basis
99 : */
100 : RealEigenVector evaluateBasisFunctions(const Point & q_point) const;
101 :
102 : /**
103 : * @brief Synchronizes local matrices and vectors (_Ae, _be) across processors.
104 : *
105 : * @param specific_elems: the elements that will be synchronized.
106 : * This is typically used when the monomial basis needs to be built from a
107 : * specific patch, or a subset of that patch.
108 : */
109 : void sync(const std::vector<dof_id_type> & specific_elems);
110 :
111 : /**
112 : * @brief Synchronizes local matrices and vectors (_Ae, _be) across processors.
113 : * all ghosted evaluable elements are synchronized.
114 : */
115 : void sync();
116 :
117 : /**
118 : * @brief Helper function to perform the actual communication of _Ae and _be.
119 : */
120 : void
121 : syncHelper(const std::unordered_map<processor_id_type, std::vector<dof_id_type>> & query_ids);
122 :
123 : /**
124 : * @brief Adds an element to the map provided in query_ids if it belongs to a different processor.
125 : * @param elem Pointer to element to be considered for addition to the map
126 : * @param query_ids Map of processor id to vector of semilocal elements on the current processor
127 : * that belong to that processor.
128 : */
129 : void
130 : addToQuery(const libMesh::Elem * elem,
131 : std::unordered_map<processor_id_type, std::vector<dof_id_type>> & query_ids) const;
132 :
133 : /// The polynomial order, default is variable order
134 : const unsigned int _patch_polynomial_order;
135 :
136 : /**
137 : * Multi-index table for a polynomial basis.
138 : *
139 : * Each multi-index is a vector of exponents [i, j, k], representing monomials like x^i y^j z^k.
140 : * The table contains all unique multi-indices where the sum of exponents is <= order.
141 : *
142 : * Ordering:
143 : * - Grouped by total degree (sum of exponents), from 0 to order.
144 : * - Within each group, ordered colexicographically (last index varies fastest).
145 : *
146 : * Examples:
147 : * dim = 1, order = 3: [0], [1], [2], [3]
148 : * dim = 2, order = 2: [0,0], [0,1], [1,0], [0,2], [1,1], [2,0]
149 : * dim = 3, order = 2: [0,0,0], [0,0,1], [0,1,0], [1,0,0], [0,0,2], [0,1,1], [1,0,1], [0,2,0],
150 : * [1,1,0], [2,0,0]
151 : */
152 : const std::vector<std::vector<unsigned int>> _multi_index;
153 :
154 : /// Number of basis functions
155 : const unsigned int _q;
156 :
157 : /// The element-level A matrix
158 : std::map<dof_id_type, RealEigenMatrix> _Ae;
159 :
160 : /// The element-level b vector
161 : std::map<dof_id_type, RealEigenVector> _be;
162 :
163 : /// @brief Cache for least-squares coefficients used in nodal patch recovery.
164 : /// Typically, there is a one-to-one mapping from element to coefficients,
165 : /// so only a single set of coefficients is cached rather than a full map.
166 : mutable std::vector<dof_id_type> _cached_elem_ids;
167 : mutable RealEigenVector _cached_coef;
168 :
169 : /// @brief Whether the mesh is distributed
170 : bool _distributed_mesh;
171 :
172 : /// @brief The processor IDs vector in the running
173 : std::vector<int> _proc_ids;
174 :
175 : friend class ElementSubdomainModifierBase;
176 : };
|