Compadre 1.7.2
Loading...
Searching...
No Matches
Compadre_GMLS.cpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Compadre: COMpatible PArticle Discretization and REmap Toolkit
4//
5// Copyright 2018 NTESS and the Compadre contributors.
6// SPDX-License-Identifier: BSD-2-Clause
7// *****************************************************************************
8// @HEADER
9#include "Compadre_GMLS.hpp"
10#include "Compadre_Functors.hpp"
11
12namespace Compadre {
13
14void GMLS::generatePolynomialCoefficients(const int number_of_batches, const bool keep_coefficients, const bool clear_cache) {
15
16 compadre_assert_release( (keep_coefficients==false || number_of_batches==1)
17 && "keep_coefficients is set to true, but number of batches exceeds 1.");
18
19 /*
20 * Verify PointConnections are valid
21 */
22 this->verifyPointConnections(true);
24
25 // ensure that solution set has neighbor list consistent with point connections
26 _h_ss._neighbor_lists = _pc._nla;
27 _h_ss._max_evaluation_sites_per_target = _additional_pc._nla.getMaxNumNeighbors() + 1;
28
29 /*
30 * Generate Quadrature
31 */
33
34 /*
35 * Generate SolutionSet on device
36 */
38
39 /*
40 * Operations to Device
41 */
42
43 // copy over operations
44 _operations = decltype(_operations)("operations", _h_ss._lro.size());
45 _host_operations = Kokkos::create_mirror_view(_operations);
46
47 // make sure at least one target operation specified
48 compadre_assert_release((_h_ss._lro.size() > 0)
49 && "No target operations added to GMLS class before calling generatePolynomialCoefficients().");
50
51 // loop through list of linear reconstruction operations to be performed and set them on the host
52 for (size_t i=0; i<_h_ss._lro.size(); ++i) _host_operations(i) = _h_ss._lro[i];
53
54 // get copy of operations on the device
55 Kokkos::deep_copy(_operations, _host_operations);
56
57 /*
58 * Initialize Alphas and Prestencil Weights
59 */
60
61 // throw an assertion for QR solver incompatibility
62 // TODO: this is a temporary location for this check, in the future the
63 // constraint type could be an object that can check when given a dense_solver_type
66 && "Cannot solve GMLS problems with the NEUMANN_GRAD_SCALAR constraint using QR Factorization.");
67
68 // calculate the additional size for different constraint problems
71
72 // initialize all alpha values to be used for taking the dot product with data to get a reconstruction
73 try {
75 int total_added_alphas = _pc._target_coordinates.extent(0)*_d_ss._added_alpha_size;
76 _d_ss._alphas =
77 decltype(_d_ss._alphas)("alphas", (total_neighbors + TO_GLOBAL(total_added_alphas))
78 *TO_GLOBAL(_d_ss._total_alpha_values)*TO_GLOBAL(_d_ss._max_evaluation_sites_per_target));
79 // this deep copy writes to all theoretically allocated memory,
80 // ensuring that allocation attempted was successful
81 Kokkos::deep_copy(_d_ss._alphas, 0.0);
82 } catch(std::exception &e) {
83 printf("Insufficient memory to store alphas: \n\n%s", e.what());
84 throw e;
85 }
86
87 // initialize the prestencil weights that are applied to sampling data to put it into a form
88 // that the GMLS operator will be able to operate on
90 int max_num_neighbors = _pc._nla.getMaxNumNeighbors();
91 try {
92 _prestencil_weights = decltype(_prestencil_weights)("Prestencil weights",
93 std::pow(2,sro.use_target_site_weights),
94 (sro.transform_type==DifferentEachTarget
95 || sro.transform_type==DifferentEachNeighbor) ?
96 this->getNeighborLists()->getNumberOfTargets() : 1,
97 (sro.transform_type==DifferentEachNeighbor) ?
98 max_num_neighbors : 1,
99 (sro.output_rank>0) ?
101 (sro.input_rank>0) ?
103 } catch(std::exception &e) {
104 printf("Insufficient memory to store prestencil weights: \n\n%s", e.what());
105 throw e;
106 }
107 Kokkos::fence();
108
109 /*
110 * Determine if Nonstandard Sampling Dimension or Basis Component Dimension
111 */
112
113 // calculate the dimension of the basis (a vector space on a manifold requires two components, for example)
115
116 // calculate sampling dimension
118
119 // effective number of components in the basis
121
122 // special case for using a higher order for sampling from a polynomial space that are gradients of a scalar polynomial
124 // if the reconstruction is being made with a gradient of a basis, then we want that basis to be one order higher so that
125 // the gradient is consistent with the convergence order expected.
126 _poly_order += 1;
128 }
129
130 /*
131 * Dimensions
132 */
133
134 // for tallying scratch space needed for device kernel calls
135 int team_scratch_size_a = 0;
136
137 // TEMPORARY, take to zero after conversion
138 int team_scratch_size_b = 0;
139 int thread_scratch_size_a = 0;
140 int thread_scratch_size_b = 0;
141
142 // dimensions that are relevant for each subproblem
143 int max_num_rows = _sampling_multiplier*max_num_neighbors;
144 int this_num_cols = _basis_multiplier*_NP;
145 int manifold_NP = 0;
146
147 // determines whether RHS will be stored implicitly
148 // if true, instead of RHS storing the full sqrt(W) explicitly,
149 // only the diagonal entries of sqrt(W) will be stored as a
150 // 1D array beginning at entry with matrix coordinate (0,0)
151 bool implicit_RHS = (_dense_solver_type != DenseSolverType::LU);
152
153 int basis_powers_space_multiplier = (_reconstruction_space == BernsteinPolynomial) ? 2 : 1;
155 // these dimensions already calculated differ in the case of manifolds
158 const int max_manifold_NP = (manifold_NP > _NP) ? manifold_NP : _NP;
159 this_num_cols = _basis_multiplier*max_manifold_NP;
160 const int max_poly_order = (_poly_order > _curvature_poly_order) ? _poly_order : _curvature_poly_order;
161
162 /*
163 * Calculate Scratch Space Allocations
164 */
165
166 team_scratch_size_b += scratch_matrix_right_type::shmem_size(_dimensions, _dimensions); // PTP matrix
167 team_scratch_size_b += scratch_vector_type::shmem_size( (_dimensions-1)*max_num_neighbors ); // manifold_gradient
168
169 thread_scratch_size_a += scratch_vector_type::shmem_size(this_num_cols); // delta, used for each thread
170 thread_scratch_size_a += scratch_vector_type::shmem_size(
171 (max_poly_order+1)*_global_dimensions*basis_powers_space_multiplier); // temporary space for powers in basis
173 team_scratch_size_b += scratch_vector_type::shmem_size(max_num_neighbors); // t1 work vector for prestencils
174 team_scratch_size_b += scratch_vector_type::shmem_size(max_num_neighbors); // t2 work vector for prestencils
175 thread_scratch_size_b += scratch_vector_type::shmem_size(_dimensions*_dimensions); // temporary tangent calculations, used for each thread
176 }
177
178 // allocate data on the device (initialized to zero)
180 _T = Kokkos::View<double*>("tangent approximation",_pc._target_coordinates.extent(0)*_dimensions*_dimensions);
181 Kokkos::deep_copy(_T, 0.0);
182 } else {
183 compadre_assert_release(_T.extent(0)/(_dimensions*_dimensions)==_pc._target_coordinates.extent(0) &&
184 "Provided tangent_directions has number of targets different than target_coordinates");
185 }
186 _manifold_curvature_coefficients = Kokkos::View<double*>("manifold curvature coefficients",
187 _pc._target_coordinates.extent(0)*manifold_NP);
188 Kokkos::deep_copy(_manifold_curvature_coefficients, 0.0);
189
190 } else { // Standard GMLS
191
192 /*
193 * Calculate Scratch Space Allocations
194 */
195
196 thread_scratch_size_a += scratch_vector_type::shmem_size(this_num_cols); // delta, used for each thread
197 thread_scratch_size_a += scratch_vector_type::shmem_size(
198 (_poly_order+1)*_global_dimensions*basis_powers_space_multiplier); // temporary space for powers in basis
199
200 }
201 _pm.setTeamScratchSize(0, team_scratch_size_a);
202 _pm.setTeamScratchSize(1, team_scratch_size_b);
203 _pm.setThreadScratchSize(0, thread_scratch_size_a);
204 _pm.setThreadScratchSize(1, thread_scratch_size_b);
205
206 /*
207 * Calculate the size for matrix P and RHS
208 */
209
210 int RHS_dim_0, RHS_dim_1;
211 getRHSDims(_dense_solver_type, _constraint_type, _reconstruction_space, _dimensions, max_num_rows, this_num_cols, RHS_dim_0, RHS_dim_1);
212
213 int P_dim_0, P_dim_1;
214 getPDims(_dense_solver_type, _constraint_type, _reconstruction_space, _dimensions, max_num_rows, this_num_cols, P_dim_0, P_dim_1);
215
216 /*
217 * Allocate Global Device Storage of Data Needed Over Multiple Calls
218 */
219
220 global_index_type max_batch_size = (_pc._target_coordinates.extent(0) + TO_GLOBAL(number_of_batches) - 1) / TO_GLOBAL(number_of_batches);
221 try {
222 _RHS = Kokkos::View<double*>("RHS", max_batch_size*TO_GLOBAL(RHS_dim_0)*TO_GLOBAL(RHS_dim_1));
223 _P = Kokkos::View<double*>("P", max_batch_size*TO_GLOBAL(P_dim_0)*TO_GLOBAL(P_dim_1));
224 _w = Kokkos::View<double*>("w", max_batch_size*TO_GLOBAL(max_num_rows));
225 _Z = Kokkos::View<double*>("Z", max_batch_size*TO_GLOBAL(_d_ss._total_alpha_values*_d_ss._max_evaluation_sites_per_target*this_num_cols));
226
227 } catch (std::exception &e) {
228 printf("Failed to allocate space for RHS, P, and w. Consider increasing number_of_batches: \n\n%s", e.what());
229 throw e;
230 }
231 Kokkos::fence();
232
233 /*
234 * Calculate Optimal Threads Based On Levels of Parallelism
235 */
236
239 && "Normal vectors are required for solving GMLS problems with the NEUMANN_GRAD_SCALAR constraint.");
240 }
241
243 for (int batch_num=0; batch_num<number_of_batches; ++batch_num) {
244
245 auto this_batch_size = std::min(_pc._target_coordinates.extent(0)-_initial_index_for_batch, max_batch_size);
246 Kokkos::deep_copy(_RHS, 0.0);
247 Kokkos::deep_copy(_P, 0.0);
248 Kokkos::deep_copy(_w, 0.0);
249 Kokkos::deep_copy(_Z, 0.0);
250
251 auto gmls_basis_data = this->extractBasisData();
252 auto gmls_solution_data = this->extractSolutionData();
253
254 auto tp = _pm.TeamPolicyThreadsAndVectors(this_batch_size);
255
257
258 /*
259 * MANIFOLD Problems
260 */
261
262 //auto functor_name = Name(gmls_basis_data);
263 //Kokkos::parallel_for("Name", tp, functor_name);
264 if (!_orthonormal_tangent_space_provided) { // user did not specify orthonormal tangent directions, so we approximate them first
265 // coarse tangent plane approximation construction of P^T*P
266 auto functor_compute_coarse_tangent_plane = ComputeCoarseTangentPlane(gmls_basis_data);
267 Kokkos::parallel_for("ComputeCoarseTangentPlane", tp, functor_compute_coarse_tangent_plane);
268
269 // if the user provided the reference outward normal direction, then orient the computed or user provided
270 // outward normal directions in the tangent bundle
272 // use the reference outward normal direction provided by the user to orient
273 // the tangent bundle
274 auto functor_fix_tangent_direction_ordering = FixTangentDirectionOrdering(gmls_basis_data);
275 Kokkos::parallel_for("FixTangentDirectionOrdering", tp, functor_fix_tangent_direction_ordering);
276 }
277
278 // assembles the P*sqrt(weights) matrix and constructs sqrt(weights)*Identity for curvature
279 auto functor_assemble_curvature_psqrtw = AssembleCurvaturePsqrtW(gmls_basis_data);
280 Kokkos::parallel_for("AssembleCurvaturePsqrtW", tp, functor_assemble_curvature_psqrtw);
281
283 // solves P^T*P against P^T*W with LU, stored in P
284 Kokkos::Profiling::pushRegion("Curvature LU Factorization");
285 // batchLU expects layout_left matrix tiles for B
286 // by giving it layout_right matrix tiles with reverse ordered ldb and ndb
287 // it effects a transpose of _P in layout_left
288 GMLS_LinearAlgebra::batchQRPivotingSolve<layout_right,layout_left,layout_right>(_pm, _RHS.data(), RHS_dim_0, RHS_dim_1, _P.data(), P_dim_1, P_dim_0, manifold_NP, manifold_NP, max_num_neighbors, this_batch_size, implicit_RHS);
289 Kokkos::Profiling::popRegion();
290 } else {
291 // solves P*sqrt(weights) against sqrt(weights)*Identity with QR, stored in RHS
292 Kokkos::Profiling::pushRegion("Curvature QR+Pivoting Factorization");
293 GMLS_LinearAlgebra::batchQRPivotingSolve<layout_right,layout_right,layout_right>(_pm, _P.data(), P_dim_0, P_dim_1, _RHS.data(), RHS_dim_0, RHS_dim_1, max_num_neighbors, manifold_NP, max_num_neighbors, this_batch_size, implicit_RHS);
294 Kokkos::Profiling::popRegion();
295 }
296
297 // evaluates targets, applies target evaluation to polynomial coefficients for curvature
298 auto functor_get_accurate_tangent_directions = GetAccurateTangentDirections(gmls_basis_data);
299 Kokkos::parallel_for("GetAccurateTangentDirections", tp, functor_get_accurate_tangent_directions);
300
301 // Due to converting layout, entries that are assumed zeros may become non-zeros.
302 Kokkos::deep_copy(_P, 0.0);
303
304 if (batch_num==number_of_batches-1) {
305 // copy tangent bundle from device back to host
306 _host_T = Kokkos::create_mirror_view(_T);
307 Kokkos::deep_copy(_host_T, _T);
308 }
309 }
310
311 // this time assembling curvature PsqrtW matrix is using a highly accurate approximation of the tangent, previously calculated
312 // assembles the P*sqrt(weights) matrix and constructs sqrt(weights)*Identity for curvature
313 auto functor_assemble_curvature_psqrtw = AssembleCurvaturePsqrtW(gmls_basis_data);
314 Kokkos::parallel_for("AssembleCurvaturePsqrtW", tp, functor_assemble_curvature_psqrtw);
315
317 // solves P^T*P against P^T*W with LU, stored in P
318 Kokkos::Profiling::pushRegion("Curvature LU Factorization");
319 GMLS_LinearAlgebra::batchQRPivotingSolve<layout_right,layout_left,layout_right>(_pm, _RHS.data(), RHS_dim_0, RHS_dim_1, _P.data(), P_dim_1, P_dim_0, manifold_NP, manifold_NP, max_num_neighbors, this_batch_size, implicit_RHS);
320 Kokkos::Profiling::popRegion();
321 } else {
322 // solves P*sqrt(weights) against sqrt(weights)*Identity, stored in RHS
323 Kokkos::Profiling::pushRegion("Curvature QR+Pivoting Factorization");
324 GMLS_LinearAlgebra::batchQRPivotingSolve<layout_right,layout_right,layout_right>(_pm, _P.data(), P_dim_0, P_dim_1, _RHS.data(), RHS_dim_0, RHS_dim_1, max_num_neighbors, manifold_NP, max_num_neighbors, this_batch_size, implicit_RHS);
325 Kokkos::Profiling::popRegion();
326 }
327
328 // evaluates targets, applies target evaluation to polynomial coefficients for curvature
329 auto functor_apply_curvature_targets = ApplyCurvatureTargets(gmls_basis_data);
330 Kokkos::parallel_for("ApplyCurvatureTargets", tp, functor_apply_curvature_targets);
331 Kokkos::fence();
332
333 // prestencil weights calculated here. appropriate because:
334 // precedes polynomial reconstruction from data (replaces contents of _RHS)
335 // follows reconstruction of geometry
336 // calculate prestencil weights
337 auto functor_compute_prestencil_weights = ComputePrestencilWeights(gmls_basis_data);
338 Kokkos::parallel_for("ComputePrestencilWeights", tp, functor_compute_prestencil_weights);
339
340 // Due to converting layout, entried that are assumed zeros may become non-zeros.
341 Kokkos::deep_copy(_P, 0.0);
342
343 // assembles the P*sqrt(weights) matrix and constructs sqrt(weights)*Identity
344 auto functor_assemble_manifold_psqrtw = AssembleManifoldPsqrtW(gmls_basis_data);
345 Kokkos::parallel_for("AssembleManifoldPsqrtW", tp, functor_assemble_manifold_psqrtw);
346
347 // solves P*sqrt(weights) against sqrt(weights)*Identity, stored in RHS
349 Kokkos::Profiling::pushRegion("Manifold LU Factorization");
350 GMLS_LinearAlgebra::batchQRPivotingSolve<layout_right,layout_left,layout_right>(_pm, _RHS.data(), RHS_dim_0, RHS_dim_1, _P.data(), P_dim_1, P_dim_0, this_num_cols, this_num_cols, max_num_rows, this_batch_size, implicit_RHS);
351 Kokkos::Profiling::popRegion();
352 } else {
353 Kokkos::Profiling::pushRegion("Manifold QR+Pivoting Factorization");
354 GMLS_LinearAlgebra::batchQRPivotingSolve<layout_right,layout_right,layout_right>(_pm, _P.data(), P_dim_0, P_dim_1, _RHS.data(), RHS_dim_0, RHS_dim_1, max_num_rows, this_num_cols, max_num_rows, this_batch_size, implicit_RHS);
355 Kokkos::Profiling::popRegion();
356 }
357 Kokkos::fence();
358
359 } else {
360
361 /*
362 * STANDARD GMLS Problems
363 */
364
365 // assembles the P*sqrt(weights) matrix and constructs sqrt(weights)*Identity
366 auto functor_assemble_standard_psqrtw = AssembleStandardPsqrtW(gmls_basis_data);
367 //printf("size of assemble: %lu\n", sizeof(functor_assemble_standard_psqrtw));
368 Kokkos::parallel_for("AssembleStandardPsqrtW", tp, functor_assemble_standard_psqrtw);
369 Kokkos::fence();
370
371 // solves P*sqrt(weights) against sqrt(weights)*Identity, stored in RHS
373 Kokkos::Profiling::pushRegion("LU Factorization");
374 GMLS_LinearAlgebra::batchQRPivotingSolve<layout_right,layout_left,layout_right>(_pm, _RHS.data(), RHS_dim_0, RHS_dim_1, _P.data(), P_dim_1, P_dim_0, this_num_cols + added_coeff_size, this_num_cols + added_coeff_size, max_num_rows + _d_ss._added_alpha_size, this_batch_size, implicit_RHS);
375 Kokkos::Profiling::popRegion();
376 } else {
377 Kokkos::Profiling::pushRegion("QR+Pivoting Factorization");
379 GMLS_LinearAlgebra::batchQRPivotingSolve<layout_right,layout_right,layout_right>(_pm, _RHS.data(), RHS_dim_0, RHS_dim_1, _P.data(), P_dim_1, P_dim_0, this_num_cols + added_coeff_size, this_num_cols + added_coeff_size, max_num_rows + _d_ss._added_alpha_size, this_batch_size, implicit_RHS);
380 } else {
381 GMLS_LinearAlgebra::batchQRPivotingSolve<layout_right,layout_right,layout_right>(_pm, _P.data(), P_dim_0, P_dim_1, _RHS.data(), RHS_dim_0, RHS_dim_1, max_num_rows, this_num_cols, max_num_rows, this_batch_size, implicit_RHS);
382 }
383 Kokkos::Profiling::popRegion();
384 }
385
386 auto functor_compute_prestencil_weights = ComputePrestencilWeights(gmls_basis_data);
387 Kokkos::parallel_for("ComputePrestencilWeights", tp, functor_compute_prestencil_weights);
388 Kokkos::fence();
389 }
390
391 /*
392 * Calculate Optimal Threads Based On Levels of Parallelism
393 */
394
396
397 /*
398 * MANIFOLD Problems
399 */
400
401 // evaluates targets, applies target evaluation to polynomial coefficients to store in _alphas
402 auto functor_evaluate_manifold_targets = EvaluateManifoldTargets(gmls_basis_data);
403 Kokkos::parallel_for("EvaluateManifoldTargets", tp, functor_evaluate_manifold_targets);
404
405 } else {
406
407 /*
408 * STANDARD GMLS Problems
409 */
410
411 // evaluates targets, applies target evaluation to polynomial coefficients to store in _alphas
412 auto functor_evaluate_standard_targets = EvaluateStandardTargets(gmls_basis_data);
413 Kokkos::parallel_for("EvaluateStandardTargets", tp, functor_evaluate_standard_targets);
414 }
415
416
417 // fine grain control over applying target (most expensive part after QR solve)
419 tp = pm.TeamPolicyThreadsAndVectors(this_batch_size);
420 const auto work_item_property = Kokkos::Experimental::WorkItemProperty::HintLightWeight;
421 const auto tp2 = Kokkos::Experimental::require(tp, work_item_property);
422 auto functor_apply_targets = ApplyTargets(gmls_solution_data);
423 //printf("size of apply: %lu\n", sizeof(functor_apply_targets));
424 Kokkos::parallel_for("ApplyTargets", tp2, functor_apply_targets);
425
426
427 _initial_index_for_batch += this_batch_size;
428 if ((size_t)_initial_index_for_batch == _pc._target_coordinates.extent(0)) break;
429 } // end of batch loops
430
431 if (clear_cache) {
432 // deallocate _P and _w
433 _w = Kokkos::View<double*>("w",0);
434 _Z = Kokkos::View<double*>("Z",0);
435 if (number_of_batches > 1) { // no reason to keep coefficients if they aren't all in memory
436 _RHS = Kokkos::View<double*>("RHS",0);
437 _P = Kokkos::View<double*>("P",0);
439 } else {
441 _RHS = Kokkos::View<double*>("RHS", 0);
442 if (!keep_coefficients) _P = Kokkos::View<double*>("P", 0);
443 } else {
445 _P = Kokkos::View<double*>("P", 0);
446 if (!keep_coefficients) _RHS = Kokkos::View<double*>("RHS", 0);
447 } else {
448 _RHS = Kokkos::View<double*>("RHS", 0);
449 if (!keep_coefficients) _P = Kokkos::View<double*>("P", 0);
450 }
451 }
452 if (keep_coefficients) _store_PTWP_inv_PTW = true;
453 }
454 }
455
456 /*
457 * Device to Host Copy Of Solution
458 */
459 // copy computed alphas back to the host
460 this->_d_ss._contains_valid_alphas = true;
463 _host_prestencil_weights = Kokkos::create_mirror_view(_prestencil_weights);
465 }
466
467}
468
469void GMLS::generateAlphas(const int number_of_batches, const bool keep_coefficients, const bool clear_cache) {
470
471 this->generatePolynomialCoefficients(number_of_batches, keep_coefficients, clear_cache);
472
473}
474
476 auto gmls = *this;
477 auto data = GMLSSolutionData();
478 data._sampling_multiplier = gmls._sampling_multiplier;
479 data._initial_index_for_batch = gmls._initial_index_for_batch;
480 data._d_ss = gmls._d_ss;
481
482 // store results of calculation in struct
483 const int max_num_neighbors = gmls._pc._nla.getMaxNumNeighbors();
484 const int max_num_rows = gmls._sampling_multiplier*max_num_neighbors;
485
486 // applyTargetsToCoefficients currently uses data.this_num_cols for the
487 // dot product range. Even for manifold problems, it is still appropriate to
488 // use gmls._basis_multiplier*gmls._NP. If GMLSSolutionData was ever to be
489 // used for applying solution coefficients for the curvature reconstruction,
490 // the manifolf_NP would have to be used for that application (requiring an
491 // extra argument to applyTargetsToCoefficients)
492 data.this_num_cols = gmls._basis_multiplier*gmls._NP;
493
494 int RHS_dim_0, RHS_dim_1;
495 getRHSDims(gmls._dense_solver_type, gmls._constraint_type, gmls._reconstruction_space,
496 gmls._dimensions, max_num_rows, data.this_num_cols, RHS_dim_0, RHS_dim_1);
497 int P_dim_0, P_dim_1;
498 getPDims(gmls._dense_solver_type, gmls._constraint_type, gmls._reconstruction_space,
499 gmls._dimensions, max_num_rows, data.this_num_cols, P_dim_0, P_dim_1);
500
501 if ((gmls._constraint_type == ConstraintType::NO_CONSTRAINT) && (gmls._dense_solver_type != DenseSolverType::LU)) {
502 data.Coeffs_data = gmls._RHS.data();
503 data.Coeffs_dim_0 = RHS_dim_0;
504 data.Coeffs_dim_1 = RHS_dim_1;
505 } else {
506 data.Coeffs_data = gmls._P.data();
507 data.Coeffs_dim_0 = P_dim_1;
508 data.Coeffs_dim_1 = P_dim_0;
509 }
510
511 data.P_target_row_dim_0 = gmls._d_ss._total_alpha_values*gmls._d_ss._max_evaluation_sites_per_target;
512 data.P_target_row_dim_1 = data.this_num_cols;
513 data.P_target_row_data = gmls._Z.data();
514
515 data.operations_size = gmls._operations.size();
516
517 data.number_of_neighbors_list = gmls._pc._nla._number_of_neighbors_list;
518 data.additional_number_of_neighbors_list = gmls._additional_pc._nla._number_of_neighbors_list;
519
520 return data;
521}
522
524 auto gmls = *this;
525 auto data = GMLSBasisData();
526 data._source_extra_data = gmls._source_extra_data;
527 data._target_extra_data = gmls._target_extra_data;
528 data._pc = gmls._pc;
529 data._epsilons = gmls._epsilons ;
530 data._prestencil_weights = gmls._prestencil_weights ;
531 data._additional_pc = gmls._additional_pc;
532 data._poly_order = gmls._poly_order ;
533 data._curvature_poly_order = gmls._curvature_poly_order;
534 data._NP = gmls._NP;
535 data._global_dimensions = gmls._global_dimensions;
536 data._local_dimensions = gmls._local_dimensions;
537 data._dimensions = gmls._dimensions;
538 data._reconstruction_space = gmls._reconstruction_space;
539 data._reconstruction_space_rank = gmls._reconstruction_space_rank;
540 data._dense_solver_type = gmls._dense_solver_type;
541 data._problem_type = gmls._problem_type;
542 data._constraint_type = gmls._constraint_type;
543 data._polynomial_sampling_functional = gmls._polynomial_sampling_functional;
544 data._data_sampling_functional = gmls._data_sampling_functional;
545 data._curvature_support_operations = gmls._curvature_support_operations;
546 data._operations = gmls._operations;
547 data._weighting_type = gmls._weighting_type;
548 data._curvature_weighting_type = gmls._curvature_weighting_type;
549 data._weighting_p = gmls._weighting_p;
550 data._weighting_n = gmls._weighting_n;
551 data._curvature_weighting_p = gmls._curvature_weighting_p;
552 data._curvature_weighting_n = gmls._curvature_weighting_n;
553 data._basis_multiplier = gmls._basis_multiplier;
554 data._sampling_multiplier = gmls._sampling_multiplier;
555 data._data_sampling_multiplier = gmls._data_sampling_multiplier;
556 data._initial_index_for_batch = gmls._initial_index_for_batch;
557 data._pm = gmls._pm;
558 data._order_of_quadrature_points = gmls._order_of_quadrature_points;
559 data._dimension_of_quadrature_points = gmls._dimension_of_quadrature_points;
560 data._qm = gmls._qm;
561 data._d_ss = gmls._d_ss;
562
563 data.max_num_neighbors = gmls._pc._nla.getMaxNumNeighbors();
564 data.max_num_rows = gmls._sampling_multiplier*data.max_num_neighbors;
565 int basis_powers_space_multiplier = (gmls._reconstruction_space == BernsteinPolynomial) ? 2 : 1;
566 if (gmls._problem_type == ProblemType::MANIFOLD) {
567 data.manifold_NP = GMLS::getNP(gmls._curvature_poly_order, gmls._dimensions-1,
569 data.max_manifold_NP = (data.manifold_NP > gmls._NP) ? data.manifold_NP : gmls._NP;
570 data.this_num_cols = gmls._basis_multiplier*data.max_manifold_NP;
571 data.max_poly_order = (gmls._poly_order > gmls._curvature_poly_order) ?
572 gmls._poly_order : gmls._curvature_poly_order;
573
574 data.ref_N_data = gmls._ref_N.data();
575 data.ref_N_dim = gmls._dimensions;
576
577 data.thread_workspace_dim = (data.max_poly_order+1)*gmls._global_dimensions*basis_powers_space_multiplier;
578 data.manifold_gradient_dim = (gmls._dimensions-1)*data.max_num_neighbors;
579
580 data.manifold_curvature_coefficients_data = gmls._manifold_curvature_coefficients.data();
581
582 } else {
583 data.manifold_NP = 0;
584 data.this_num_cols = gmls._basis_multiplier*gmls._NP;
585 data.thread_workspace_dim = (gmls._poly_order+1)*gmls._global_dimensions*basis_powers_space_multiplier;
586 data.manifold_gradient_dim = 0;
587 }
588
589
590 data.T_data = gmls._T.data();
591
592 data.P_target_row_dim_0 = gmls._d_ss._total_alpha_values*gmls._d_ss._max_evaluation_sites_per_target;
593 data.P_target_row_dim_1 = data.this_num_cols;
594 data.P_target_row_data = gmls._Z.data();
595
596 data.RHS_data = gmls._RHS.data();
597 getRHSDims(gmls._dense_solver_type, gmls._constraint_type, gmls._reconstruction_space,
598 gmls._dimensions, data.max_num_rows, data.this_num_cols, data.RHS_dim_0, data.RHS_dim_1);
599
600 data.P_data = gmls._P.data();
601 getPDims(gmls._dense_solver_type, gmls._constraint_type, gmls._reconstruction_space,
602 gmls._dimensions, data.max_num_rows, data.this_num_cols, data.P_dim_0, data.P_dim_1);
603
604 data.w_data = gmls._w.data();
605
606 if ((gmls._constraint_type == ConstraintType::NO_CONSTRAINT) && (gmls._dense_solver_type != DenseSolverType::LU)) {
607 data.Coeffs_data = gmls._RHS.data();
608 data.Coeffs_dim_0 = data.RHS_dim_0;
609 data.Coeffs_dim_1 = data.RHS_dim_1;
610 } else {
611 data.Coeffs_data = gmls._P.data();
612 data.Coeffs_dim_0 = data.P_dim_1;
613 data.Coeffs_dim_1 = data.P_dim_0;
614 }
615
616 return data;
617}
618
619} // Compadre
#define TO_GLOBAL(variable)
#define compadre_assert_release(condition)
SolutionSet< device_memory_space > _d_ss
neighbor_lists_type * getNeighborLists() const
Get neighbor list accessor.
std::string _quadrature_type
quadrature rule type
Kokkos::View< double * > _T
point_connections_type _additional_pc
(OPTIONAL) connections between additional points and neighbors
bool _reference_outward_normal_direction_provided
whether or not the reference outward normal directions were provided by the user.
ReconstructionSpace _reconstruction_space
reconstruction space for GMLS problems, set at GMLS class instantiation
const GMLSSolutionData extractSolutionData() const
Get GMLS solution data.
int _order_of_quadrature_points
order of exact polynomial integration for quadrature rule
int _global_dimensions
spatial dimension of the points, set at class instantiation only
void generatePolynomialCoefficients(const int number_of_batches=1, const bool keep_coefficients=false, const bool clear_cache=true)
Generates polynomial coefficients by setting up and solving least squares problems Sets up the batch ...
ProblemType _problem_type
DenseSolverType _dense_solver_type
solver type for GMLS problem - can be QR, SVD or LU
Kokkos::View< TargetOperation * >::host_mirror_type _host_operations
vector containing target functionals to be applied for reconstruction problem (host)
Kokkos::View< double * > _Z
stores evaluations of targets applied to basis
int _initial_index_for_batch
initial index for current batch
int _NP
dimension of basis for polynomial reconstruction
void generateAlphas(const int number_of_batches=1, const bool keep_coefficients=false, const bool clear_cache=true)
Meant to calculate target operations and apply the evaluations to the previously constructed polynomi...
int _poly_order
order of basis for polynomial reconstruction
bool verifyPointConnections(bool assert_valid=false)
Verify whether _pc is valid.
Kokkos::View< double * > _manifold_curvature_coefficients
curvature polynomial coefficients for all problems
SamplingFunctional _data_sampling_functional
generally the same as _polynomial_sampling_functional, but can differ if specified at
SolutionSet< host_memory_space > _h_ss
Solution Set (contains all alpha values from solution and alpha layout methods).
ConstraintType _constraint_type
constraint type for GMLS problem
int _dimensions
dimension of the problem, set at class instantiation only
int _curvature_poly_order
order of basis for curvature reconstruction
bool _use_reference_outward_normal_direction_provided_to_orient_surface
whether or not to use reference outward normal directions to orient the surface in a manifold problem...
Kokkos::View< double * >::host_mirror_type _host_T
tangent vectors information (host)
ParallelManager _pm
determines scratch level spaces and is used to call kernels
Kokkos::View< TargetOperation * > _operations
vector containing target functionals to be applied for reconstruction problem (device)
bool _orthonormal_tangent_space_provided
Kokkos::View< double * > _RHS
sqrt(w)*Identity matrix for all problems, later holds polynomial coefficients for all problems
SamplingFunctional _polynomial_sampling_functional
Kokkos::View< double * > _P
P*sqrt(w) matrix for all problems.
static KOKKOS_INLINE_FUNCTION int getNP(const int m, const int dimension=3, const ReconstructionSpace r_space=ReconstructionSpace::ScalarTaylorPolynomial)
const GMLSBasisData extractBasisData() const
Get GMLS basis data.
Kokkos::View< constdouble *****, layout_right >::host_mirror_type _host_prestencil_weights
point_connections_type _pc
connections between points and neighbors
Kokkos::View< double *****, layout_right > _prestencil_weights
Kokkos::View< double * > _w
contains weights for all problems
bool _entire_batch_computed_at_once
int _local_dimensions
dimension of the problem, set at class instantiation only. For manifolds, generally _global_dimension...
bool verifyAdditionalPointConnections(bool assert_valid=false)
Verify whether _additional_pc is valid.
bool _store_PTWP_inv_PTW
whether polynomial coefficients were requested to be stored (in a state not yet applied to data)
int _dimension_of_quadrature_points
dimension of quadrature rule
Quadrature _qm
manages and calculates quadrature
Kokkos::TeamPolicy< execution_space > TeamPolicyThreadsAndVectors(const global_index_type batch_size, const int threads_per_team=-1, const int vector_lanes_per_thread=-1) const
template void batchQRPivotingSolve< layout_right, layout_left, layout_right >(ParallelManager, double *, int, int, double *, int, int, int, int, int, const int, const bool)
template void batchQRPivotingSolve< layout_right, layout_right, layout_right >(ParallelManager, double *, int, int, double *, int, int, int, int, int, const int, const bool)
constexpr SamplingFunctional VaryingManifoldVectorPointSample
For integrating polynomial dotted with normal over an edge.
KOKKOS_INLINE_FUNCTION int getAdditionalCoeffSizeFromConstraintAndSpace(DenseSolverType dense_solver_type, ConstraintType constraint_type, ReconstructionSpace reconstruction_space, const int dimension)
KOKKOS_INLINE_FUNCTION void getRHSDims(DenseSolverType dense_solver_type, ConstraintType constraint_type, ReconstructionSpace reconstruction_space, const int dimension, const int M, const int N, int &RHS_row, int &RHS_col)
@ NEUMANN_GRAD_SCALAR
Neumann Gradient Scalar Type.
@ NO_CONSTRAINT
No constraint.
constexpr SamplingFunctional PointSample
Available sampling functionals.
@ BernsteinPolynomial
Bernstein polynomial basis.
KOKKOS_INLINE_FUNCTION int calculateBasisMultiplier(const ReconstructionSpace rs, const int local_dimensions)
Calculate basis_multiplier.
KOKKOS_INLINE_FUNCTION int calculateSamplingMultiplier(const ReconstructionSpace rs, const SamplingFunctional sro, const int local_dimensions)
Calculate sampling_multiplier.
constexpr SamplingFunctional StaggeredEdgeAnalyticGradientIntegralSample
Analytical integral of a gradient source vector is just a difference of the scalar source at neighbor...
KOKKOS_INLINE_FUNCTION int getAdditionalAlphaSizeFromConstraint(DenseSolverType dense_solver_type, ConstraintType constraint_type)
KOKKOS_INLINE_FUNCTION void getPDims(DenseSolverType dense_solver_type, ConstraintType constraint_type, ReconstructionSpace reconstruction_space, const int dimension, const int M, const int N, int &out_row, int &out_col)
@ LU
LU factorization performed on P^T*W*P matrix.
@ QR
QR+Pivoting factorization performed on P*sqrt(w) matrix.
@ DifferentEachNeighbor
Each target applies a different transform for each neighbor.
@ DifferentEachTarget
Each target applies a different data transform, but the same to each neighbor.
std::size_t global_index_type
KOKKOS_INLINE_FUNCTION int getOutputDimensionOfSampling(SamplingFunctional sro, const int local_dimensions)
Functor to evaluate curvature targets and apply to coefficients of curvature reconstruction.
Functor to apply target evaluation to polynomial coefficients to store in _alphas.
Functor to assemble the P*sqrt(weights) matrix and construct sqrt(weights)*Identity for curvature.
Functor to assemble the P*sqrt(weights) matrix and construct sqrt(weights)*Identity.
Functor to assemble the P*sqrt(weights) matrix and construct sqrt(weights)*Identity.
Functor to create a coarse tangent approximation from a given neighborhood of points.
Functor to calculate prestencil weights to apply to data to transform into a format expected by a GML...
Functor to evaluate targets on a manifold.
Functor to evaluate targets operations on the basis.
Functor to evaluate curvature targets and construct accurate tangent direction approximation for mani...
global_index_type getTotalNeighborsOverAllListsHost() const
Get the sum of the number of neighbors of all targets' neighborhoods (host).