Compadre  1.2.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Compadre_GMLS.hpp
Go to the documentation of this file.
1 #ifndef _COMPADRE_GMLS_HPP_
2 #define _COMPADRE_GMLS_HPP_
3 
4 #include "Compadre_Config.h"
5 #include "Compadre_Typedefs.hpp"
6 
7 #include "Compadre_Misc.hpp"
8 #include "Compadre_Operators.hpp"
11 #include "Compadre_Quadrature.hpp"
15 
16 namespace Compadre {
17 
18 //! Generalized Moving Least Squares (GMLS)
19 /*!
20 * This class sets up a batch of GMLS problems from a given set of neighbor lists, target sites, and source sites.
21 * GMLS requires a target functional, reconstruction space, and sampling functional to be specified.
22 * For a given choice of reconstruction space and sampling functional, multiple targets can be generated with very little
23 * additional computation, which is why this class allows for multiple target functionals to be specified.
24 */
25 class GMLS {
26 protected:
27 
28  // random numbe generator pool
30 
31  // matrices that may be needed for matrix factorization on the device
32  // supports batched matrix factorization dispatch
33 
34  //! contains weights for all problems
35  Kokkos::View<double*> _w;
36 
37  //! P*sqrt(w) matrix for all problems
38  Kokkos::View<double*> _P;
39 
40  //! sqrt(w)*Identity matrix for all problems, later holds polynomial coefficients for all problems
41  Kokkos::View<double*> _RHS;
42 
43  //! Rank 3 tensor for high order approximation of tangent vectors for all problems. First rank is
44  //! for the target index, the second is for the local direction to the manifolds 0..(_dimensions-1)
45  //! are tangent, _dimensions is the normal, and the third is for the spatial dimension (_dimensions)
46  Kokkos::View<double*> _T;
47 
48  //! Rank 2 tensor for high order approximation of tangent vectors for all problems. First rank is
49  //! for the target index, the second is for the spatial dimension (_dimensions)
50  Kokkos::View<double*> _ref_N;
51 
52  //! tangent vectors information (host)
53  Kokkos::View<double*>::HostMirror _host_T;
54 
55  //! reference outward normal vectors information (host)
56  Kokkos::View<double*>::HostMirror _host_ref_N;
57 
58  //! metric tensor inverse for all problems
59  Kokkos::View<double*> _manifold_metric_tensor_inverse;
60 
61  //! curvature polynomial coefficients for all problems
62  Kokkos::View<double*> _manifold_curvature_coefficients;
63 
64  //! _dimension-1 gradient values for curvature for all problems
65  Kokkos::View<double*> _manifold_curvature_gradient;
66 
67  //! Extra data available to basis functions (optional)
68  Kokkos::View<double**, layout_right> _source_extra_data;
69 
70  //! Extra data available to target operations (optional)
71  Kokkos::View<double**, layout_right> _target_extra_data;
72 
73  //! Accessor to get neighbor list data, offset data, and number of neighbors per target
75 
76  //! convenient copy on host of number of neighbors
77  Kokkos::View<int*, host_memory_space> _host_number_of_neighbors_list;
78 
79  //! all coordinates for the source for which _neighbor_lists refers (device)
80  Kokkos::View<double**, layout_right> _source_coordinates;
81 
82  //! coordinates for target sites for reconstruction (device)
83  Kokkos::View<double**, layout_right> _target_coordinates;
84 
85  //! h supports determined through neighbor search (device)
86  Kokkos::View<double*> _epsilons;
87 
88  //! h supports determined through neighbor search (host)
89  Kokkos::View<double*>::HostMirror _host_epsilons;
90 
91  //! generated alpha coefficients (device)
92  Kokkos::View<double*, layout_right> _alphas;
93 
94  //! generated alpha coefficients (host)
95  Kokkos::View<const double*, layout_right>::HostMirror _host_alphas;
96 
97  //! generated weights for nontraditional samples required to transform data into expected sampling
98  //! functional form (device).
99  Kokkos::View<double*****, layout_right> _prestencil_weights;
100 
101  //! generated weights for nontraditional samples required to transform data into expected sampling
102  //! functional form (host)
103  Kokkos::View<const double*****, layout_right>::HostMirror _host_prestencil_weights;
104 
105  //! (OPTIONAL) user provided additional coordinates for target operation evaluation (device)
106  Kokkos::View<double**, layout_right> _additional_evaluation_coordinates;
107 
108  //! (OPTIONAL) contains indices of entries in the _additional_evaluation_coordinates view (device)
109  Kokkos::View<int**, layout_right> _additional_evaluation_indices;
110 
111  //! (OPTIONAL) contains indices of entries in the _additional_evaluation_coordinates view (host)
112  Kokkos::View<int**, layout_right>::HostMirror _host_additional_evaluation_indices;
113 
114  //! (OPTIONAL) contains the # of additional coordinate indices for each target
116 
117 
118  //! order of basis for polynomial reconstruction
120 
121  //! order of basis for curvature reconstruction
123 
124  //! dimension of basis for polynomial reconstruction
125  int _NP;
126 
127  //! spatial dimension of the points, set at class instantiation only
129 
130  //! dimension of the problem, set at class instantiation only. For manifolds, generally _global_dimensions-1
132 
133  //! dimension of the problem, set at class instantiation only
135 
136  //! reconstruction space for GMLS problems, set at GMLS class instantiation
138 
139  //! actual rank of reconstruction basis
141 
142  //! solver type for GMLS problem - can be QR, SVD or LU
144 
145  //! problem type for GMLS problem, can also be set to STANDARD for normal or MANIFOLD for manifold problems
147 
148  //! constraint type for GMLS problem
150 
151  //! polynomial sampling functional used to construct P matrix, set at GMLS class instantiation
153 
154  //! generally the same as _polynomial_sampling_functional, but can differ if specified at
155  //! GMLS class instantiation
157 
158  //! vector containing target functionals to be applied for curvature
159  Kokkos::View<TargetOperation*> _curvature_support_operations;
160 
161  //! vector containing target functionals to be applied for reconstruction problem (device)
162  Kokkos::View<TargetOperation*> _operations;
163 
164  //! vector containing target functionals to be applied for reconstruction problem (host)
165  Kokkos::View<TargetOperation*>::HostMirror _host_operations;
166 
167 
168 
169  //! weighting kernel type for GMLS
171 
172  //! weighting kernel type for curvature problem
174 
175  //! power to be used for weighting kernel
177 
178  //! power to be used for weighting kernel for curvature
180 
181  //! dimension of the reconstructed function
182  //! e.g. reconstruction of vector on a 2D manifold in 3D would have _basis_multiplier of 2
184 
185  //! actual dimension of the sampling functional
186  //! e.g. reconstruction of vector on a 2D manifold in 3D would have _basis_multiplier of 2
187  //! e.g. in 3D, a scalar will be 1, a vector will be 3, and a vector of reused scalars will be 1
189 
190  //! effective dimension of the data sampling functional
191  //! e.g. in 3D, a scalar will be 1, a vector will be 3, and a vector of reused scalars will be 3
193 
194  //! whether or not operator to be inverted for GMLS problem has a nontrivial nullspace (requiring SVD)
196 
197  //! whether or not the orthonormal tangent directions were provided by the user. If they are not,
198  //! then for the case of calculations on manifolds, a GMLS approximation of the tangent space will
199  //! be made and stored for use.
201 
202  //! whether or not the reference outward normal directions were provided by the user.
204 
205  //! whether or not to use reference outward normal directions to orient the surface in a manifold problem.
207 
208  //! whether entire calculation was computed at once
209  //! the alternative is that it was broken up over many smaller groups, in which case
210  //! this is false, and so the _RHS matrix can not be stored or requested
212 
213  //! whether polynomial coefficients were requested to be stored (in a state not yet applied to data)
215 
216  //! initial index for current batch
218 
219  //! maximum number of neighbors over all target sites
221 
222  //! maximum number of evaluation sites for each target (includes target site)
224 
225  //! vector of user requested target operations
226  std::vector<TargetOperation> _lro;
227 
228  //! vector containing a mapping from a target functionals enum value to the its place in the list
229  //! of target functionals to be applied
230  std::vector<int> _lro_lookup;
231 
232  //! index for where this operation begins the for _alpha coefficients (device)
233  Kokkos::View<int*> _lro_total_offsets;
234 
235  //! index for where this operation begins the for _alpha coefficients (host)
236  Kokkos::View<int*>::HostMirror _host_lro_total_offsets;
237 
238  //! dimensions ^ rank of tensor of output for each target functional (device)
239  Kokkos::View<int*> _lro_output_tile_size;
240 
241  //! dimensions ^ rank of tensor of output for each target functional (host)
242  Kokkos::View<int*>::HostMirror _host_lro_output_tile_size;
243 
244  //! dimensions ^ rank of tensor of output for each sampling functional (device)
245  Kokkos::View<int*> _lro_input_tile_size;
246 
247  //! dimensions ^ rank of tensor of output for each sampling functional (host)
248  Kokkos::View<int*>::HostMirror _host_lro_input_tile_size;
249 
250  //! tensor rank of target functional (device)
251  Kokkos::View<int*> _lro_output_tensor_rank;
252 
253  //! tensor rank of target functional (host)
254  Kokkos::View<int*>::HostMirror _host_lro_output_tensor_rank;
255 
256  //! tensor rank of sampling functional (device)
257  Kokkos::View<int*> _lro_input_tensor_rank;
258 
259  //! tensor rank of sampling functional (host)
260  Kokkos::View<int*>::HostMirror _host_lro_input_tensor_rank;
261 
262  //! used for sizing P_target_row and the _alphas view
264 
265  //! additional alpha coefficients due to constraints
267 
268  //! determines scratch level spaces and is used to call kernels
270 
271  //! order of exact polynomial integration for quadrature rule
273 
274  //! dimension of quadrature rule
276 
277  //! quadrature rule type
278  std::string _quadrature_type;
279 
280  //! manages and calculates quadrature
282 
283 
284 /** @name Private Modifiers
285  * Private function because information lives on the device
286  */
287 ///@{
288 
289  /*! \brief Evaluates the polynomial basis under a particular sampling function. Generally used to fill a row of P.
290  \param delta [in/out] - scratch space that is allocated so that each thread has its own copy. Must be at least as large as the _basis_multipler*the dimension of the polynomial basis.
291  \param thread_workspace [in/out] - scratch space that is allocated so that each thread has its own copy. Must be at least as large as the _poly_order*the spatial dimension of the polynomial basis.
292  \param target_index [in] - target number
293  \param neighbor_index [in] - index of neighbor for this target with respect to local numbering [0,...,number of neighbors for target]
294  \param alpha [in] - double to determine convex combination of target and neighbor site at which to evaluate polynomials. (1-alpha)*neighbor + alpha*target
295  \param dimension [in] - spatial dimension of basis to evaluate. e.g. dimension two basis of order one is 1, x, y, whereas for dimension 3 it is 1, x, y, z
296  \param poly_order [in] - polynomial basis degree
297  \param specific_order_only [in] - boolean for only evaluating one degree of polynomial when true
298  \param V [in] - orthonormal basis matrix size _dimensions * _dimensions whose first _dimensions-1 columns are an approximation of the tangent plane
299  \param reconstruction_space [in] - space of polynomial that a sampling functional is to evaluate
300  \param sampling_strategy [in] - sampling functional specification
301  \param additional_evaluation_local_index [in] - local index for evaluation sites
302  */
303  KOKKOS_INLINE_FUNCTION
304  void calcPij(const member_type& teamMember, double* delta, double* thread_workspace, const int target_index, int neighbor_index, const double alpha, const int dimension, const int poly_order, bool specific_order_only = false, const scratch_matrix_right_type* V = NULL, const ReconstructionSpace reconstruction_space = ReconstructionSpace::ScalarTaylorPolynomial, const SamplingFunctional sampling_strategy = PointSample, const int additional_evaluation_local_index = 0) const;
305 
306  /*! \brief Evaluates the gradient of a polynomial basis under the Dirac Delta (pointwise) sampling function.
307  \param delta [in/out] - scratch space that is allocated so that each thread has its own copy. Must be at least as large is the _basis_multipler*the dimension of the polynomial basis.
308  \param thread_workspace [in/out] - scratch space that is allocated so that each thread has its own copy. Must be at least as large as the _poly_order*the spatial dimension of the polynomial basis.
309  \param target_index [in] - target number
310  \param neighbor_index [in] - index of neighbor for this target with respect to local numbering [0,...,number of neighbors for target]
311  \param alpha [in] - double to determine convex combination of target and neighbor site at which to evaluate polynomials. (1-alpha)*neighbor + alpha*target
312  \param partial_direction [in] - direction that partial is taken with respect to, e.g. 0 is x direction, 1 is y direction
313  \param dimension [in] - spatial dimension of basis to evaluate. e.g. dimension two basis of order one is 1, x, y, whereas for dimension 3 it is 1, x, y, z
314  \param poly_order [in] - polynomial basis degree
315  \param specific_order_only [in] - boolean for only evaluating one degree of polynomial when true
316  \param V [in] - orthonormal basis matrix size _dimensions * _dimensions whose first _dimensions-1 columns are an approximation of the tangent plane
317  \param reconstruction_space [in] - space of polynomial that a sampling functional is to evaluate
318  \param sampling_strategy [in] - sampling functional specification
319  \param additional_evaluation_local_index [in] - local index for evaluation sites
320  */
321  KOKKOS_INLINE_FUNCTION
322  void calcGradientPij(const member_type& teamMember, double* delta, double* thread_workspace, const int target_index, int neighbor_index, const double alpha, const int partial_direction, const int dimension, const int poly_order, bool specific_order_only, const scratch_matrix_right_type* V, const ReconstructionSpace reconstruction_space, const SamplingFunctional sampling_strategy, const int additional_evaluation_local_index = 0) const;
323 
324  /*! \brief Evaluates the Hessian of a polynomial basis under the Dirac Delta (pointwise) sampling function.
325  \param delta [in/out] - scratch space that is allocated so that each thread has its own copy. Must be at least as large is the _basis_multipler*the dimension of the polynomial basis.
326  \param thread_workspace [in/out] - scratch space that is allocated so that each thread has its own copy. Must be at least as large as the _poly_order*the spatial dimension of the polynomial basis.
327  \param target_index [in] - target number
328  \param neighbor_index [in] - index of neighbor for this target with respect to local numbering [0,...,number of neighbors for target]
329  \param alpha [in] - double to determine convex combination of target and neighbor site at which to evaluate polynomials. (1-alpha)*neighbor + alpha*target
330  \param partial_direction_1 [in] - first direction that partial is taken with respect to, e.g. 0 is x direction, 1 is y direction
331  \param partial_direction_2 [in] - second direction that partial is taken with respect to, e.g. 0 is x direction, 1 is y direction
332  \param dimension [in] - spatial dimension of basis to evaluate. e.g. dimension two basis of order one is 1, x, y, whereas for dimension 3 it is 1, x, y, z
333  \param poly_order [in] - polynomial basis degree
334  \param specific_order_only [in] - boolean for only evaluating one degree of polynomial when true
335  \param V [in] - orthonormal basis matrix size _dimensions * _dimensions whose first _dimensions-1 columns are an approximation of the tangent plane
336  \param reconstruction_space [in] - space of polynomial that a sampling functional is to evaluate
337  \param sampling_strategy [in] - sampling functional specification
338  \param additional_evaluation_local_index [in] - local index for evaluation sites
339  */
340  KOKKOS_INLINE_FUNCTION
341  void calcHessianPij(const member_type& teamMember, double* delta, double* thread_workspace, const int target_index, int neighbor_index, const double alpha, const int partial_direction_1, const int partial_direction_2, const int dimension, const int poly_order, bool specific_order_only, const scratch_matrix_right_type* V, const ReconstructionSpace reconstruction_space, const SamplingFunctional sampling_strategy, const int additional_evaluation_local_index = 0) const;
342 
343  /*! \brief Fills the _P matrix with either P or P*sqrt(w)
344  \param teamMember [in] - Kokkos::TeamPolicy member type (created by parallel_for)
345  \param delta [in/out] - scratch space that is allocated so that each thread has its own copy. Must be at least as large is the _basis_multipler*the dimension of the polynomial basis.
346  \param thread_workspace [in/out] - scratch space that is allocated so that each thread has its own copy. Must be at least as large as the _poly_order*the spatial dimension of the polynomial basis.
347  \param P [out] - 2D Kokkos View which will contain evaluation of sampling functional on polynomial basis for each neighbor the target has (stored column major)
348  \param w [out] - 1D Kokkos View which will contain weighting kernel values for the target with each neighbor if weight_p = true
349  \param dimension [in] - spatial dimension of basis to evaluate. e.g. dimension two basis of order one is 1, x, y, whereas for dimension 3 it is 1, x, y, z
350  \param polynomial_order [in] - polynomial basis degree
351  \param weight_p [in] - boolean whether to fill w with kernel weights
352  \param V [in] - orthonormal basis matrix size _dimensions * _dimensions whose first _dimensions-1 columns are an approximation of the tangent plane
353  \param reconstruction_space [in] - space of polynomial that a sampling functional is to evaluate
354  \param sampling_strategy [in] - sampling functional specification
355  */
356  KOKKOS_INLINE_FUNCTION
357  void createWeightsAndP(const member_type& teamMember, scratch_vector_type delta, scratch_vector_type thread_workspace, scratch_matrix_right_type P, scratch_vector_type w, const int dimension, int polynomial_order, bool weight_p = false, scratch_matrix_right_type* V = NULL, const ReconstructionSpace reconstruction_space = ReconstructionSpace::ScalarTaylorPolynomial, const SamplingFunctional sampling_strategy = PointSample) const;
358 
359  /*! \brief Fills the _P matrix with P*sqrt(w) for use in solving for curvature
360 
361  Uses _curvature_poly_order as the polynomial order of the basis
362 
363  \param teamMember [in] - Kokkos::TeamPolicy member type (created by parallel_for)
364  \param delta [in/out] - scratch space that is allocated so that each thread has its own copy. Must be at least as large is the _basis_multipler*the dimension of the polynomial basis.
365  \param thread_workspace [in/out] - scratch space that is allocated so that each thread has its own copy. Must be at least as large as the _poly_order*the spatial dimension of the polynomial basis.
366  \param P [out] - 2D Kokkos View which will contain evaluation of sampling functional on polynomial basis for each neighbor the target has (stored column major)
367  \param w [out] - 1D Kokkos View which will contain weighting kernel values for the target with each neighbor if weight_p = true
368  \param dimension [in] - spatial dimension of basis to evaluate. e.g. dimension two basis of order one is 1, x, y, whereas for dimension 3 it is 1, x, y, z
369  \param only_specific_order [in] - boolean for only evaluating one degree of polynomial when true
370  \param V [in] - orthonormal basis matrix size _dimensions * _dimensions whose first _dimensions-1 columns are an approximation of the tangent plane
371  */
372  KOKKOS_INLINE_FUNCTION
373  void createWeightsAndPForCurvature(const member_type& teamMember, scratch_vector_type delta, scratch_vector_type thread_workspace, scratch_matrix_right_type P, scratch_vector_type w, const int dimension, bool only_specific_order, scratch_matrix_right_type* V = NULL) const;
374 
375  /*! \brief Evaluates a polynomial basis with a target functional applied to each member of the basis
376  \param teamMember [in] - Kokkos::TeamPolicy member type (created by parallel_for)
377  \param delta [in/out] - scratch space that is allocated so that each thread has its own copy. Must be at least as large is the _basis_multipler*the dimension of the polynomial basis.
378  \param thread_workspace [in/out] - scratch space that is allocated so that each team has its own copy. Must be at least as large is the _poly_order*_global_dimensions.
379  \param P_target_row [out] - 1D Kokkos View where the evaluation of the polynomial basis is stored
380  */
381  KOKKOS_INLINE_FUNCTION
383 
384  /*! \brief Evaluates a polynomial basis for the curvature with a gradient target functional applied
385 
386  _operations is used by this function which is set through a modifier function
387 
388  \param teamMember [in] - Kokkos::TeamPolicy member type (created by parallel_for)
389  \param delta [in/out] - scratch space that is allocated so that each thread has its own copy. Must be at least as large is the _basis_multipler*the dimension of the polynomial basis.
390  \param thread_workspace [in/out] - scratch space that is allocated so that each thread has its own copy. Must be at least as large as the _curvature_poly_order*the spatial dimension of the polynomial basis.
391  \param P_target_row [out] - 1D Kokkos View where the evaluation of the polynomial basis is stored
392  \param V [in] - orthonormal basis matrix size _dimensions * _dimensions whose first _dimensions-1 columns are an approximation of the tangent plane
393  */
394  KOKKOS_INLINE_FUNCTION
395  void computeCurvatureFunctionals(const member_type& teamMember, scratch_vector_type t1, scratch_vector_type t2, scratch_matrix_right_type P_target_row, const scratch_matrix_right_type* V, const local_index_type local_neighbor_index = -1) const;
396 
397  /*! \brief Evaluates a polynomial basis with a target functional applied, using information from the manifold curvature
398 
399  _operations is used by this function which is set through a modifier function
400 
401  \param teamMember [in] - Kokkos::TeamPolicy member type (created by parallel_for)
402  \param delta [in/out] - scratch space that is allocated so that each thread has its own copy. Must be at least as large is the _basis_multipler*the dimension of the polynomial basis.
403  \param thread_workspace [in/out] - scratch space that is allocated so that each thread has its own copy. Must be at least as large as the _curvature_poly_order*the spatial dimension of the polynomial basis.
404  \param P_target_row [out] - 1D Kokkos View where the evaluation of the polynomial basis is stored
405  \param V [in] - orthonormal basis matrix size _dimensions * _dimensions whose first _dimensions-1 columns are an approximation of the tangent plane
406  \param G_inv [in] - (_dimensions-1)*(_dimensions-1) Kokkos View containing inverse of metric tensor
407  \param curvature_coefficients [in] - polynomial coefficients for curvature
408  \param curvature_gradients [in] - approximation of gradient of curvature, Kokkos View of size (_dimensions-1)
409  */
410  KOKKOS_INLINE_FUNCTION
412 
413  //! Helper function for applying the evaluations from a target functional to the polynomial coefficients
414  KOKKOS_INLINE_FUNCTION
416 
417 ///@}
418 
419 
420 
421 /** @name Private Accessors
422  * Private function because information lives on the device
423  */
424 ///@{
425 
426  //! Returns number of neighbors for a particular target
427  KOKKOS_INLINE_FUNCTION
428  int getNNeighbors(const int target_index) const {
429  return _neighbor_lists.getNumberOfNeighborsDevice(target_index);
430  }
431 
432  //! Mapping from [0,number of neighbors for a target] to the row that contains the source coordinates for
433  //! that neighbor
434  KOKKOS_INLINE_FUNCTION
435  int getNeighborIndex(const int target_index, const int neighbor_list_num) const {
436  return _neighbor_lists.getNeighborDevice(target_index, neighbor_list_num);
437  }
438 
439  //! Returns the maximum neighbor lists size over all target sites
440  KOKKOS_INLINE_FUNCTION
441  int getMaxNNeighbors() const {
443  }
444 
445  //! Returns the maximum number of evaluation sites over all target sites (target sites are included in total)
446  KOKKOS_INLINE_FUNCTION
449  }
450 
451  //! (OPTIONAL)
452  //! Returns number of additional evaluation sites for a particular target
453  KOKKOS_INLINE_FUNCTION
454  int getNEvaluationSitesPerTarget(const int target_index) const {
455  return _number_of_additional_evaluation_indices(target_index)+1;
456  }
457 
458  //! (OPTIONAL)
459  //! Mapping from [0,number of additional evaluation sites for a target] to the row that contains the coordinates for
460  //! that evaluation
461  KOKKOS_INLINE_FUNCTION
462  int getAdditionalEvaluationIndex(const int target_index, const int additional_list_num) const {
463  compadre_kernel_assert_debug((additional_list_num >= 1)
464  && "additional_list_num must be greater than or equal to 1, unlike neighbor lists which begin indexing at 0.");
465  return _additional_evaluation_indices(target_index, additional_list_num);
466  }
467 
468  //! Returns one component of the target coordinate for a particular target. Whether global or local coordinates
469  //! depends upon V being specified
470  KOKKOS_INLINE_FUNCTION
471  double getTargetCoordinate(const int target_index, const int dim, const scratch_matrix_right_type* V = NULL) const {
472  compadre_kernel_assert_debug((_target_coordinates.extent(0) >= (size_t)target_index) && "Target index is out of range for _target_coordinates.");
473  if (V==NULL) {
474  return _target_coordinates(target_index, dim);
475  } else {
476  XYZ target_coord = XYZ( _target_coordinates(target_index, 0),
477  _target_coordinates(target_index, 1),
478  _target_coordinates(target_index, 2));
479  return this->convertGlobalToLocalCoordinate(target_coord, dim, V);
480  }
481  }
482 
483  //! (OPTIONAL)
484  //! Returns one component of the additional evaluation coordinates. Whether global or local coordinates
485  //! depends upon V being specified
486  KOKKOS_INLINE_FUNCTION
487  double getTargetAuxiliaryCoordinate(const int target_index, const int additional_list_num, const int dim, const scratch_matrix_right_type* V = NULL) const {
488  auto additional_evaluation_index = getAdditionalEvaluationIndex(target_index, additional_list_num);
489  compadre_kernel_assert_debug((_additional_evaluation_coordinates.extent(0) >= (size_t)additional_evaluation_index) && "Additional evaluation index is out of range for _additional_evaluation_coordinates.");
490  if (V==NULL) {
491  return _additional_evaluation_coordinates(additional_evaluation_index, dim);
492  } else {
493  XYZ additional_target_coord = XYZ( _additional_evaluation_coordinates(additional_evaluation_index, 0),
494  _additional_evaluation_coordinates(additional_evaluation_index, 1),
495  _additional_evaluation_coordinates(additional_evaluation_index, 2));
496  return this->convertGlobalToLocalCoordinate(additional_target_coord, dim, V);
497  }
498  }
499 
500  //! Returns one component of the neighbor coordinate for a particular target. Whether global or local coordinates
501  //! depends upon V being specified
502  KOKKOS_INLINE_FUNCTION
503  double getNeighborCoordinate(const int target_index, const int neighbor_list_num, const int dim, const scratch_matrix_right_type* V = NULL) const {
504  compadre_kernel_assert_debug((_source_coordinates.extent(0) >= (size_t)(this->getNeighborIndex(target_index, neighbor_list_num))) && "Source index is out of range for _source_coordinates.");
505  if (V==NULL) {
506  return _source_coordinates(this->getNeighborIndex(target_index, neighbor_list_num), dim);
507  } else {
508  XYZ neighbor_coord = XYZ(_source_coordinates(this->getNeighborIndex(target_index, neighbor_list_num), 0), _source_coordinates(this->getNeighborIndex(target_index, neighbor_list_num), 1), _source_coordinates(this->getNeighborIndex(target_index, neighbor_list_num), 2));
509  return this->convertGlobalToLocalCoordinate(neighbor_coord, dim, V);
510  }
511  }
512 
513  //! Returns the relative coordinate as a vector between the target site and the neighbor site.
514  //! Whether global or local coordinates depends upon V being specified
515  KOKKOS_INLINE_FUNCTION
516  XYZ getRelativeCoord(const int target_index, const int neighbor_list_num, const int dimension, const scratch_matrix_right_type* V = NULL) const {
517  XYZ coordinate_delta;
518 
519  coordinate_delta.x = this->getNeighborCoordinate(target_index, neighbor_list_num, 0, V) - this->getTargetCoordinate(target_index, 0, V);
520  if (dimension>1) coordinate_delta.y = this->getNeighborCoordinate(target_index, neighbor_list_num, 1, V) - this->getTargetCoordinate(target_index, 1, V);
521  if (dimension>2) coordinate_delta.z = this->getNeighborCoordinate(target_index, neighbor_list_num, 2, V) - this->getTargetCoordinate(target_index, 2, V);
522 
523  return coordinate_delta;
524  }
525 
526  //! Returns a component of the local coordinate after transformation from global to local under the orthonormal basis V.
527  KOKKOS_INLINE_FUNCTION
528  double convertGlobalToLocalCoordinate(const XYZ global_coord, const int dim, const scratch_matrix_right_type* V) const {
529  // only written for 2d manifold in 3d space
530  double val = 0;
531  val += global_coord.x * (*V)(dim, 0);
532  val += global_coord.y * (*V)(dim, 1); // can't be called from dimension 1 problem
533  if (_dimensions>2) val += global_coord.z * (*V)(dim, 2);
534  return val;
535  }
536 
537  //! Returns a component of the global coordinate after transformation from local to global under the orthonormal basis V^T.
538  KOKKOS_INLINE_FUNCTION
539  double convertLocalToGlobalCoordinate(const XYZ local_coord, const int dim, const scratch_matrix_right_type* V) const {
540  // only written for 2d manifold in 3d space
541  double val;
542  if (dim == 0 && _dimensions==2) { // 2D problem with 1D manifold
543  val = local_coord.x * (*V)(0, dim);
544  } else if (dim == 0) { // 3D problem with 2D manifold
545  val = local_coord.x * ((*V)(0, dim) + (*V)(1, dim));
546  } else if (dim == 1) { // 3D problem with 2D manifold
547  val = local_coord.y * ((*V)(0, dim) + (*V)(1, dim));
548  }
549  return val;
550  }
551 
552  //! Handles offset from operation input/output + extra evaluation sites
553  int getTargetOffsetIndexHost(const int lro_num, const int input_component, const int output_component, const int additional_evaluation_local_index = 0) const {
554  return ( _total_alpha_values*additional_evaluation_local_index
555  + _host_lro_total_offsets[lro_num]
556  + input_component*_host_lro_output_tile_size[lro_num]
557  + output_component );
558  }
559 
560  //! Handles offset from operation input/output + extra evaluation sites
561  KOKKOS_INLINE_FUNCTION
562  int getTargetOffsetIndexDevice(const int lro_num, const int input_component, const int output_component, const int additional_evaluation_local_index = 0) const {
563  return ( _total_alpha_values*additional_evaluation_local_index
564  + _lro_total_offsets[lro_num]
565  + input_component*_lro_output_tile_size[lro_num]
566  + output_component );
567  }
568 
569 ///@}
570 
571 /** @name Private Utility
572  *
573  */
574 ///@{
575 
576  //! Parses a string to determine solver type
577  static DenseSolverType parseSolverType(const std::string& dense_solver_type) {
578  std::string solver_type_to_lower = dense_solver_type;
579  transform(solver_type_to_lower.begin(), solver_type_to_lower.end(), solver_type_to_lower.begin(), ::tolower);
580  if (solver_type_to_lower == "svd") {
581  return DenseSolverType::SVD;
582  } else if (solver_type_to_lower == "lu") {
583  return DenseSolverType::LU;
584  } else {
585  return DenseSolverType::QR;
586  }
587  }
588 
589  //! Parses a string to determine problem type
590  static ProblemType parseProblemType(const std::string& problem_type) {
591  std::string problem_type_to_lower = problem_type;
592  transform(problem_type_to_lower.begin(), problem_type_to_lower.end(), problem_type_to_lower.begin(), ::tolower);
593  if (problem_type_to_lower == "standard") {
594  return ProblemType::STANDARD;
595  } else if (problem_type_to_lower == "manifold") {
596  return ProblemType::MANIFOLD;
597  } else {
598  return ProblemType::STANDARD;
599  }
600  }
601 
602  //! Parses a string to determine constraint type
603  static ConstraintType parseConstraintType(const std::string& constraint_type) {
604  std::string constraint_type_to_lower = constraint_type;
605  transform(constraint_type_to_lower.begin(), constraint_type_to_lower.end(), constraint_type_to_lower.begin(), ::tolower);
606  if (constraint_type_to_lower == "none") {
608  } else if (constraint_type_to_lower == "neumann_grad_scalar") {
610  } else {
612  }
613  }
614 
615 ///@}
616 
617 public:
618 
619 /** @name Instantiation / Destruction
620  *
621  */
622 ///@{
623 
624  //! Minimal constructor providing no data (neighbor lists, source sites, target sites)
625  GMLS(ReconstructionSpace reconstruction_space,
626  const SamplingFunctional polynomial_sampling_strategy,
627  const SamplingFunctional data_sampling_strategy,
628  const int poly_order,
629  const int dimensions = 3,
630  const std::string dense_solver_type = std::string("QR"),
631  const std::string problem_type = std::string("STANDARD"),
632  const std::string constraint_type = std::string("NO_CONSTRAINT"),
633  const int manifold_curvature_poly_order = 2) :
634  _poly_order(poly_order),
635  _curvature_poly_order(manifold_curvature_poly_order),
636  _dimensions(dimensions),
637  _reconstruction_space(reconstruction_space),
638  _dense_solver_type(parseSolverType(dense_solver_type)),
639  _problem_type(parseProblemType(problem_type)),
640  _constraint_type(parseConstraintType(constraint_type)),
642  && (polynomial_sampling_strategy == VectorPointSample)) ? ManifoldVectorPointSample : polynomial_sampling_strategy),
644  && (data_sampling_strategy == VectorPointSample)) ? ManifoldVectorPointSample : data_sampling_strategy)
645  {
646 
647  // seed random number generator pool
649 
650  _NP = this->getNP(_poly_order, dimensions, _reconstruction_space);
651  Kokkos::fence();
652 
653  // register curvature operations for manifold problems
655  _curvature_support_operations = Kokkos::View<TargetOperation*>
656  ("operations needed for manifold gradient reconstruction", 1);
657  auto curvature_support_operations_mirror =
658  Kokkos::create_mirror_view(_curvature_support_operations);
659  curvature_support_operations_mirror(0) =
661  Kokkos::deep_copy(_curvature_support_operations, curvature_support_operations_mirror);
662  }
663 
664  _lro_lookup = std::vector<int>(TargetOperation::COUNT,-1); // hard coded against number of operations defined
665  _lro = std::vector<TargetOperation>();
666 
667  // various initializations
669 
672  _weighting_power = 2;
674 
676 
677  _basis_multiplier = 1;
679 
680  _nontrivial_nullspace = false;
685  _store_PTWP_inv_PTW = false;
686 
688 
689  _max_num_neighbors = 0;
691 
692  _global_dimensions = dimensions;
694  _local_dimensions = dimensions-1;
695  } else {
696  _local_dimensions = dimensions;
697  }
698 
701  }
702 
703  //! Constructor for the case when the data sampling functional does not match the polynomial
704  //! sampling functional. Only case anticipated is staggered Laplacian.
705  GMLS(const int poly_order,
706  const int dimensions = 3,
707  const std::string dense_solver_type = std::string("QR"),
708  const std::string problem_type = std::string("STANDARD"),
709  const std::string constraint_type = std::string("NO_CONSTRAINT"),
710  const int manifold_curvature_poly_order = 2)
711  : GMLS(ReconstructionSpace::VectorOfScalarClonesTaylorPolynomial, VectorPointSample, VectorPointSample, poly_order, dimensions, dense_solver_type, problem_type, constraint_type, manifold_curvature_poly_order) {}
712 
713  //! Constructor for the case when nonstandard sampling functionals or reconstruction spaces
714  //! are to be used. Reconstruction space and sampling strategy can only be set at instantiation.
715  GMLS(ReconstructionSpace reconstruction_space,
716  SamplingFunctional dual_sampling_strategy,
717  const int poly_order,
718  const int dimensions = 3,
719  const std::string dense_solver_type = std::string("QR"),
720  const std::string problem_type = std::string("STANDARD"),
721  const std::string constraint_type = std::string("NO_CONSTRAINT"),
722  const int manifold_curvature_poly_order = 2)
723  : GMLS(reconstruction_space, dual_sampling_strategy, dual_sampling_strategy, poly_order, dimensions, dense_solver_type, problem_type, constraint_type, manifold_curvature_poly_order) {}
724 
725  //! Destructor
726  ~GMLS(){
727  };
728 
729 ///@}
730 
731 /** @name Functors
732  * Member functions that perform operations on the entire batch
733  */
734 ///@{
735 
736  //! Tag for functor to assemble the P*sqrt(weights) matrix and construct sqrt(weights)*Identity
738 
739  //! Tag for functor to evaluate targets, apply target evaluation to polynomial coefficients to
740  //! store in _alphas
742 
743  //! Tag for functor to create a coarse tangent approximation from a given neighborhood of points
745 
746  //! Tag for functor to assemble the P*sqrt(weights) matrix and construct sqrt(weights)*Identity for curvature
748 
749  //! Tag for functor to evaluate curvature targets and construct accurate tangent direction approximation for manifolds
751 
752  //! Tag for functor to determine if tangent directions need reordered, and to reorder them if needed
754 
755  //! Tag for functor to evaluate curvature targets and apply to coefficients of curvature reconstruction
757 
758  //! Tag for functor to assemble the P*sqrt(weights) matrix and construct sqrt(weights)*Identity
760 
761  //! Tag for functor to evaluate targets, apply target evaluation to polynomial coefficients to store in _alphas
763 
764  //! Tag for functor to calculate prestencil weights to apply to data to transform into a format expected by a GMLS stencil
766 
767 
768 
769  //! Functor to assemble the P*sqrt(weights) matrix and construct sqrt(weights)*Identity
770  KOKKOS_INLINE_FUNCTION
771  void operator() (const AssembleStandardPsqrtW&, const member_type& teamMember) const;
772 
773  //! Functor to evaluate targets, apply target evaluation to polynomial coefficients to store in _alphas
774  KOKKOS_INLINE_FUNCTION
775  void operator() (const ApplyStandardTargets&, const member_type& teamMember) const;
776 
777  //! Functor to create a coarse tangent approximation from a given neighborhood of points
778  KOKKOS_INLINE_FUNCTION
779  void operator() (const ComputeCoarseTangentPlane&, const member_type& teamMember) const;
780 
781  //! Functor to assemble the P*sqrt(weights) matrix and construct sqrt(weights)*Identity for curvature
782  KOKKOS_INLINE_FUNCTION
783  void operator() (const AssembleCurvaturePsqrtW&, const member_type& teamMember) const;
784 
785  //! Functor to evaluate curvature targets and construct accurate tangent direction approximation for manifolds
786  KOKKOS_INLINE_FUNCTION
787  void operator() (const GetAccurateTangentDirections&, const member_type& teamMember) const;
788 
789  //! Functor to determine if tangent directions need reordered, and to reorder them if needed
790  //! We require that the normal is consistent with a right hand rule on the tangent vectors
791  KOKKOS_INLINE_FUNCTION
792  void operator() (const FixTangentDirectionOrdering&, const member_type& teamMember) const;
793 
794  //! Functor to evaluate curvature targets and apply to coefficients of curvature reconstruction
795  KOKKOS_INLINE_FUNCTION
796  void operator() (const ApplyCurvatureTargets&, const member_type& teamMember) const;
797 
798  //! Functor to assemble the P*sqrt(weights) matrix and construct sqrt(weights)*Identity
799  KOKKOS_INLINE_FUNCTION
800  void operator() (const AssembleManifoldPsqrtW&, const member_type& teamMember) const;
801 
802  //! Functor to evaluate targets, apply target evaluation to polynomial coefficients to store in _alphas
803  KOKKOS_INLINE_FUNCTION
804  void operator() (const ApplyManifoldTargets&, const member_type& teamMember) const;
805 
806  //! Functor to calculate prestencil weights to apply to data to transform into a format expected by a GMLS stencil
807  KOKKOS_INLINE_FUNCTION
808  void operator() (const ComputePrestencilWeights&, const member_type& teamMember) const;
809 
810 ///@}
811 
812 /** @name Public Utility
813  *
814  */
815 ///@{
816 
817  //! Returns size of the basis for a given polynomial order and dimension
818  //! General to dimension 1..3 and polynomial order m
819  //! The divfree options will return the divergence-free basis if true
820  KOKKOS_INLINE_FUNCTION
821  static int getNP(const int m, const int dimension = 3, const ReconstructionSpace r_space = ReconstructionSpace::ScalarTaylorPolynomial) {
823  return ScalarTaylorPolynomialBasis::getSize(m, dimension);
824  } else {
825  return DivergenceFreePolynomialBasis::getSize(m, dimension);
826  }
827  }
828 
829  //! Returns number of neighbors needed for unisolvency for a given basis order and dimension
830  KOKKOS_INLINE_FUNCTION
831  static int getNN(const int m, const int dimension = 3, const ReconstructionSpace r_space = ReconstructionSpace::ScalarTaylorPolynomial) {
832  // may need div-free argument in the future
833  const int np = getNP(m, dimension, r_space);
834  int nn = np;
835  switch (dimension) {
836  case 3:
837  nn = np * (1.7 + m*0.1);
838  break;
839  case 2:
840  nn = np * (1.4 + m*0.03);
841  break;
842  case 1:
843  nn = np * 1.1;
844  }
845  return nn;
846  }
847 
848  /*! \brief Evaluates the weighting kernel
849  \param r [in] - Euclidean distance of relative vector. Euclidean distance of (target - neighbor) in some basis.
850  \param h [in] - window size. Kernel is guaranteed to take on a value of zero if it exceeds h.
851  \param weighting_type [in] - weighting type to be evaluated as the kernel. e,g. power, Gaussian, etc..
852  \param power [in] - power parameter to be given to the kernel.
853  */
854  KOKKOS_INLINE_FUNCTION
855  static double Wab(const double r, const double h, const WeightingFunctionType& weighting_type, const int power) {
856  if (weighting_type == WeightingFunctionType::Power) {
857  return std::pow(1.0-std::abs(r/h), power) * double(1.0-std::abs(r/h)>0.0);
858  } else if (weighting_type == WeightingFunctionType::Gaussian) {
859  // 2.5066282746310002416124 = sqrt(2*pi)
860  double h_over_3 = h/3.0;
861  return 1./( h_over_3 * 2.5066282746310002416124 ) * std::exp(-.5*r*r/(h_over_3*h_over_3));
862  } else if (weighting_type == WeightingFunctionType::CubicSpline) {
863  double x = r/h;
864  return ((1-x)+x*(1-x)*(1-2*x)) * double(r<=h);
865  } else { // no weighting power specified
866  compadre_kernel_assert_release(false && "Invalid WeightingFunctionType selected.");
867  return 0;
868  }
869  }
870 
871  //! Returns Euclidean norm of a vector
872  KOKKOS_INLINE_FUNCTION
873  static double EuclideanVectorLength(const XYZ& delta_vector, const int dimension) {
874  double inside_val = delta_vector.x*delta_vector.x;
875  switch (dimension) {
876  case 3:
877  inside_val += delta_vector.z*delta_vector.z;
878  // no break is intentional
879  case 2:
880  inside_val += delta_vector.y*delta_vector.y;
881  // no break is intentional
882  default:
883  break;
884  }
885  return std::sqrt(inside_val);
886  }
887 
888 
889  //! Helper function for finding alpha coefficients
890  static int getTargetOutputIndex(const int operation_num, const int output_component_axis_1, const int output_component_axis_2, const int dimensions) {
891  const int axis_1_size = (TargetOutputTensorRank[operation_num] > 1) ? dimensions : 1;
892  return axis_1_size*output_component_axis_1 + output_component_axis_2; // 0 for scalar, 0 for vector;
893  }
894 
895  //! Helper function for finding alpha coefficients
896  static int getSamplingOutputIndex(const SamplingFunctional sf, const int output_component_axis_1, const int output_component_axis_2) {
897  const int axis_1_size = (sf.output_rank > 1) ? sf.output_rank : 1;
898  return axis_1_size*output_component_axis_1 + output_component_axis_2; // 0 for scalar, 0 for vector;
899  }
900 
901  //! Output rank for sampling operation
903  return sro.output_rank;
904  }
905 
906  //! Input rank for sampling operation
908  return sro.input_rank;
909  }
910 
911 
912 ///@}
913 
914 /** @name Accessors
915  * Retrieve member variables through public member functions
916  */
917 ///@{
918 
919 
920  //! Returns (size of the basis used in instance's polynomial reconstruction) x (data input dimension)
922  host_managed_local_index_type sizes("sizes", 2);
923  sizes(0) = _basis_multiplier*_NP;
925  return sizes;
926  }
927 
928  //! Returns size of the basis used in instance's polynomial reconstruction
930  auto sizes = this->getPolynomialCoefficientsDomainRangeSize();
931  return sizes(0);
932  }
933 
934  //! Returns 2D array size in memory on which coefficients are stored
936  auto M_by_N = this->getPolynomialCoefficientsDomainRangeSize();
938  && "Entire batch not computed at once, so getFullPolynomialCoefficientsBasis() can not be called.");
940  && "generateAlphas() called with keep_coefficients set to false.");
941  host_managed_local_index_type sizes("sizes", 2);
944  sizes(0) = rhsdim;
945  sizes(1) = rhsdim;
946  } else {
947  getPDims(_dense_solver_type, _constraint_type, _reconstruction_space, _dimensions, M_by_N[1], M_by_N[0], sizes(1), sizes(0));
948  }
949  return sizes;
950  }
951 
952  //! Dimension of the GMLS problem, set only at class instantiation
953  int getDimensions() const { return _dimensions; }
954 
955  //! Dimension of the GMLS problem's point data (spatial description of points in ambient space), set only at class instantiation
956  int getGlobalDimensions() const { return _global_dimensions; }
957 
958  //! Local dimension of the GMLS problem (less than global dimension if on a manifold), set only at class instantiation
959  int getLocalDimensions() const { return _local_dimensions; }
960 
961  //! Get dense solver type
963 
964  //! Get problem type
966 
967  //! Get constraint type
969 
970  //! Type for weighting kernel for GMLS problem
972 
973  //! Type for weighting kernel for curvature
975 
976  //! Power for weighting kernel for GMLS problem
977  int getWeightingPower() const { return _weighting_power; }
978 
979  //! Power for weighting kernel for curvature
981 
982  //! Number of quadrature points
984 
985  //! Order of quadrature points
987 
988  //! Dimensions of quadrature points
990 
991  //! Type of quadrature points
992  std::string getQuadratureType() const { return _quadrature_type; }
993 
994  //! Get neighbor list accessor
996 
997  //! Get a view (device) of all tangent direction bundles.
998  decltype(_T) getTangentDirections() const { return _T; }
999 
1000  //! Get a view (device) of all reference outward normal directions.
1002 
1003  //! Get component of tangent or normal directions for manifold problems
1004  double getTangentBundle(const int target_index, const int direction, const int component) const {
1005  // Component index 0.._dimensions-2 will return tangent direction
1006  // Component index _dimensions-1 will return the normal direction
1007  scratch_matrix_right_type::HostMirror
1008  T(_host_T.data() + target_index*_dimensions*_dimensions, _dimensions, _dimensions);
1009  return T(direction, component);
1010  }
1011 
1012  //! Get component of tangent or normal directions for manifold problems
1013  double getReferenceNormalDirection(const int target_index, const int component) const {
1015  "getRefenceNormalDirection called, but reference outwrad normal directions were never provided.");
1016  scratch_vector_type::HostMirror
1017  ref_N(_host_ref_N.data() + target_index*_dimensions, _dimensions);
1018  return ref_N(component);
1019  }
1020 
1021  //! Get the local index (internal) to GMLS for a particular TargetOperation
1022  //! Every TargetOperation has a global index which can be readily found in Compadre::TargetOperation
1023  //! but this function returns the index used inside of the GMLS class
1025  return _lro_lookup[(int)lro];
1026  }
1027 
1028  //! Get a view (device) of all rank 2 preprocessing tensors
1029  //! This is a rank 5 tensor that is able to provide data transformation
1030  //! into a form that GMLS is able to operate on. The ranks are as follows:
1031  //!
1032  //! 1 - Either size 2 if it operates on the target site and neighbor site (staggered schemes)
1033  //! or 1 if it operates only on the neighbor sites (almost every scheme)
1034  //!
1035  //! 2 - If the data transform varies with each target site (but could be the same for each neighbor of that target site), then this is the number of target sites
1036  //!
1037  //! 3 - If the data transform varies with each neighbor of each target site, then this is the number of neighbors for each respective target (max number of neighbors for all target sites is its uniform size)
1038  //!
1039  //! 4 - Data transform resulting in rank 1 data for the GMLS operator will have size _local_dimensions, otherwise 1
1040  //!
1041  //! 5 - Data transform taking in rank 1 data will have size _global_dimensions, otherwise 1
1043  return _prestencil_weights;
1044  }
1045 
1046  //! Retrieves the offset for an operator based on input and output component, generic to row
1047  //! (but still multiplied by the number of neighbors for each row and then needs a neighbor number added
1048  //! to this returned value to be meaningful)
1049  int getAlphaColumnOffset(TargetOperation lro, const int output_component_axis_1,
1050  const int output_component_axis_2, const int input_component_axis_1,
1051  const int input_component_axis_2, const int additional_evaluation_local_index = 0) const {
1052 
1053  const int lro_number = _lro_lookup[(int)lro];
1054  compadre_assert_debug((lro_number >= 0) && "getAlphaColumnOffset called for a TargetOperation that was not registered.");
1055 
1056  // the target functional input indexing is sized based on the output rank of the sampling
1057  // functional used, which can not be inferred unless a specification of target functional,
1058  // reconstruction space, and sampling functional are all known (as was the case at the
1059  // construction of this class)
1060  const int input_index = getSamplingOutputIndex(_data_sampling_functional, input_component_axis_1, input_component_axis_2);
1061  const int output_index = getTargetOutputIndex((int)lro, output_component_axis_1, output_component_axis_2, _dimensions);
1062 
1063  return getTargetOffsetIndexHost(lro_number, input_index, output_index, additional_evaluation_local_index);
1064  }
1065 
1066  //! Get a view (device) of all alphas
1067  decltype(_alphas) getAlphas() const { return _alphas; }
1068 
1069  //! Get a view (device) of all polynomial coefficients basis
1072  && "Entire batch not computed at once, so getFullPolynomialCoefficientsBasis() can not be called.");
1074  && "generateAlphas() called with keep_coefficients set to false.");
1076  return _RHS;
1077  } else {
1078  return _P;
1079  }
1080  }
1081 
1082  //! Get the polynomial sampling functional specified at instantiation
1084 
1085  //! Get the data sampling functional specified at instantiation (often the same as the polynomial sampling functional)
1087 
1088  //! Get the reconstruction space specified at instantiation
1090 
1091  //! Helper function for getting alphas for scalar reconstruction from scalar data
1092  double getAlpha0TensorTo0Tensor(TargetOperation lro, const int target_index, const int neighbor_index, const int additional_evaluation_site = 0) const {
1093  // e.g. Dirac Delta target of a scalar field
1094  return getAlpha(lro, target_index, 0, 0, neighbor_index, 0, 0, additional_evaluation_site);
1095  }
1096 
1097  //! Helper function for getting alphas for vector reconstruction from scalar data
1098  double getAlpha0TensorTo1Tensor(TargetOperation lro, const int target_index, const int output_component, const int neighbor_index, const int additional_evaluation_site = 0) const {
1099  // e.g. gradient of a scalar field
1100  return getAlpha(lro, target_index, output_component, 0, neighbor_index, 0, 0, additional_evaluation_site);
1101  }
1102 
1103  //! Helper function for getting alphas for matrix reconstruction from scalar data
1104  double getAlpha0TensorTo2Tensor(TargetOperation lro, const int target_index, const int output_component_axis_1, const int output_component_axis_2, const int neighbor_index, const int additional_evaluation_site = 0) const {
1105  return getAlpha(lro, target_index, output_component_axis_1, output_component_axis_2, neighbor_index, 0, 0, additional_evaluation_site);
1106  }
1107 
1108  //! Helper function for getting alphas for scalar reconstruction from vector data
1109  double getAlpha1TensorTo0Tensor(TargetOperation lro, const int target_index, const int neighbor_index, const int input_component, const int additional_evaluation_site = 0) const {
1110  // e.g. divergence of a vector field
1111  return getAlpha(lro, target_index, 0, 0, neighbor_index, input_component, 0, additional_evaluation_site);
1112  }
1113 
1114  //! Helper function for getting alphas for vector reconstruction from vector data
1115  double getAlpha1TensorTo1Tensor(TargetOperation lro, const int target_index, const int output_component, const int neighbor_index, const int input_component, const int additional_evaluation_site = 0) const {
1116  // e.g. curl of a vector field
1117  return getAlpha(lro, target_index, output_component, 0, neighbor_index, input_component, 0, additional_evaluation_site);
1118  }
1119 
1120  //! Helper function for getting alphas for matrix reconstruction from vector data
1121  double getAlpha1TensorTo2Tensor(TargetOperation lro, const int target_index, const int output_component_axis_1, const int output_component_axis_2, const int neighbor_index, const int input_component, const int additional_evaluation_site = 0) const {
1122  // e.g. gradient of a vector field
1123  return getAlpha(lro, target_index, output_component_axis_1, output_component_axis_2, neighbor_index, input_component, 0, additional_evaluation_site);
1124  }
1125 
1126  //! Helper function for getting alphas for scalar reconstruction from matrix data
1127  double getAlpha2TensorTo0Tensor(TargetOperation lro, const int target_index, const int neighbor_index, const int input_component_axis_1, const int input_component_axis_2, const int additional_evaluation_site = 0) const {
1128  return getAlpha(lro, target_index, 0, 0, neighbor_index, input_component_axis_1, input_component_axis_2, additional_evaluation_site);
1129  }
1130 
1131  //! Helper function for getting alphas for vector reconstruction from matrix data
1132  double getAlpha2TensorTo1Tensor(TargetOperation lro, const int target_index, const int output_component, const int neighbor_index, const int input_component_axis_1, const int input_component_axis_2, const int additional_evaluation_site = 0) const {
1133  return getAlpha(lro, target_index, output_component, 0, neighbor_index, input_component_axis_1, input_component_axis_2, additional_evaluation_site);
1134  }
1135 
1136  //! Helper function for getting alphas for matrix reconstruction from matrix data
1137  double getAlpha2TensorTo2Tensor(TargetOperation lro, const int target_index, const int output_component_axis_1, const int output_component_axis_2, const int neighbor_index, const int input_component_axis_1, const int input_component_axis_2, const int additional_evaluation_site = 0) const {
1138  return getAlpha(lro, target_index, output_component_axis_1, output_component_axis_2, neighbor_index, input_component_axis_1, input_component_axis_2, additional_evaluation_site);
1139  }
1140 
1141  //! Gives index into alphas given two axes, which when incremented by the neighbor number transforms access into
1142  //! alphas from a rank 1 view into a rank 3 view.
1143  KOKKOS_INLINE_FUNCTION
1144  global_index_type getAlphaIndexDevice(const int target_index, const int alpha_column_offset) const {
1145 
1146  global_index_type total_neighbors_before_target = _neighbor_lists.getRowOffsetDevice(target_index);
1147  int total_added_alphas_before_target = target_index*_added_alpha_size;
1148 
1149  int alphas_per_tile_per_target = _neighbor_lists.getNumberOfNeighborsDevice(target_index) + _added_alpha_size;
1150 
1151  return (total_neighbors_before_target+TO_GLOBAL(total_added_alphas_before_target))
1153  + TO_GLOBAL(alpha_column_offset*alphas_per_tile_per_target);
1154 
1155  }
1156 
1157  //! Gives index into alphas given two axes, which when incremented by the neighbor number transforms access into
1158  //! alphas from a rank 1 view into a rank 3 view.
1159  global_index_type getAlphaIndexHost(const int target_index, const int alpha_column_offset) const {
1160 
1161  global_index_type total_neighbors_before_target = _neighbor_lists.getRowOffsetHost(target_index);
1162  int total_added_alphas_before_target = target_index*_added_alpha_size;
1163 
1164  int alphas_per_tile_per_target = _neighbor_lists.getNumberOfNeighborsHost(target_index) + _added_alpha_size;
1165 
1166  return (total_neighbors_before_target+TO_GLOBAL(total_added_alphas_before_target))
1168  + TO_GLOBAL(alpha_column_offset*alphas_per_tile_per_target);
1169 
1170  }
1171 
1172  //! Underlying function all interface helper functions call to retrieve alpha values
1173  double getAlpha(TargetOperation lro, const int target_index, const int output_component_axis_1, const int output_component_axis_2, const int neighbor_index, const int input_component_axis_1, const int input_component_axis_2, const int additional_evaluation_site = 0) const {
1174  // lro - the operator from TargetOperations
1175  // target_index - the # for the target site where information is required
1176  // neighbor_index - the # for the neighbor of the target
1177  //
1178  // This code support up to rank 2 tensors for inputs and outputs
1179  //
1180  // scalar reconstruction from scalar data: rank 0 to rank 0
1181  // provides 1 piece of information for each neighbor
1182  // scalar reconstruction from vector data (e.g. divergence): rank 1 to rank 0
1183  // provides 'd' pieces of information for each neighbor
1184  // vector reconstruction from scalar data (e.g. gradient): rank 0 to rank 1
1185  // provides 'd' piece of information for each neighbor
1186  // vector reconstruction from vector data (e.g. curl): rank 1 to rank 1
1187  // provides 'd'x'd' pieces of information for each neighbor
1188  //
1189  // This function would more reasonably be called from one of the getAlphaNTensorFromNTensor
1190  // which is much easier to understand with respect to indexing and only requesting indices
1191  // that are relavent to the operator in question.
1192  //
1193 
1194  const int alpha_column_offset = this->getAlphaColumnOffset( lro, output_component_axis_1,
1195  output_component_axis_2, input_component_axis_1, input_component_axis_2, additional_evaluation_site);
1196 
1197  auto alphas_index = this->getAlphaIndexHost(target_index, alpha_column_offset);
1198  return _host_alphas(alphas_index + neighbor_index);
1199  }
1200 
1201  //! Returns a stencil to transform data from its existing state into the input expected
1202  //! for some sampling functionals.
1203  double getPreStencilWeight(SamplingFunctional sro, const int target_index, const int neighbor_index, bool for_target, const int output_component = 0, const int input_component = 0) const {
1204  // for certain sampling strategies, linear combinations of the neighbor and target value are needed
1205  // for the traditional PointSample, this value is 1 for the neighbor and 0 for the target
1206  if (sro == PointSample ) {
1207  if (for_target) return 0; else return 1;
1208  }
1209 
1210  // these check conditions on the sampling operator and change indexing on target and neighbors
1211  // in order to reuse information, such as if the same data transformation is used, regardless
1212  // of target site or neighbor site
1213  const int target_index_in_weights =
1216  target_index : 0;
1217  const int neighbor_index_in_weights =
1219  neighbor_index : 0;
1220 
1221  return _host_prestencil_weights((int)for_target, target_index_in_weights, neighbor_index_in_weights,
1222  output_component, input_component);
1223  }
1224 
1225  //! Dimensions ^ output rank for target operation
1226  int getOutputDimensionOfOperation(TargetOperation lro, bool ambient = false) const {
1227  int return_val;
1228  if (ambient) return_val = std::pow(_global_dimensions, TargetOutputTensorRank[(int)lro]);
1229  else return_val = std::pow(_local_dimensions, TargetOutputTensorRank[(int)lro]);
1230  return return_val;
1231  }
1232 
1233  //! Dimensions ^ input rank for target operation (always in local chart if on a manifold, never ambient space)
1235  return this->_host_lro_input_tile_size[_lro_lookup[(int)lro]];
1236  // this is the same return values as the OutputDimensionOfSampling for the GMLS class's SamplingFunctional
1237  }
1238 
1239  //! Dimensions ^ output rank for sampling operation
1240  //! (always in local chart if on a manifold, never ambient space)
1242  return std::pow(_local_dimensions, sro.output_rank);
1243  }
1244 
1245  //! Dimensions ^ output rank for sampling operation
1246  //! (always in ambient space, never local chart on a manifold)
1248  return std::pow(_global_dimensions, sro.input_rank);
1249  }
1250 
1251  //! Calculate basis_multiplier
1253  // calculate the dimension of the basis
1254  // (a vector space on a manifold requires two components, for example)
1255  return std::pow(_local_dimensions, ActualReconstructionSpaceRank[(int)rs]);
1256  }
1257 
1258  //! Calculate sampling_multiplier
1260  // this would normally be SamplingOutputTensorRank[_data_sampling_functional], but we also want to handle the
1261  // case of reconstructions where a scalar basis is reused as a vector, and this handles everything
1262  // this handles scalars, vectors, and scalars that are reused as vectors
1263  int bm = this->calculateBasisMultiplier(rs);
1264  int sm = this->getOutputDimensionOfSampling(sro);
1266  // storage and computational efficiency by reusing solution to scalar problem for
1267  // a vector problem (in 3d, 27x cheaper computation, 9x cheaper storage)
1268  sm = std::min(bm,sm);
1269  }
1270  return sm;
1271  }
1272 
1273 
1274 ///@}
1275 
1276 
1277 /** @name Modifiers
1278  * Changed member variables through public member functions
1279  */
1280 ///@{
1281 
1283  if (_RHS.extent(0) > 0)
1284  _RHS = Kokkos::View<double*>("RHS",0);
1285  }
1286 
1287  //! Sets basic problem data (neighbor lists, source coordinates, and target coordinates)
1288  template<typename view_type_1, typename view_type_2, typename view_type_3, typename view_type_4>
1290  view_type_1 neighbor_lists,
1291  view_type_2 source_coordinates,
1292  view_type_3 target_coordinates,
1293  view_type_4 epsilons) {
1294  this->setNeighborLists<view_type_1>(neighbor_lists);
1295  this->setSourceSites<view_type_2>(source_coordinates);
1296  this->setTargetSites<view_type_3>(target_coordinates);
1297  this->setWindowSizes<view_type_4>(epsilons);
1298  }
1299 
1300  //! Sets basic problem data (neighbor lists data, number of neighbors list, source coordinates, and target coordinates)
1301  template<typename view_type_1, typename view_type_2, typename view_type_3, typename view_type_4>
1303  view_type_1 cr_neighbor_lists,
1304  view_type_1 number_of_neighbors_list,
1305  view_type_2 source_coordinates,
1306  view_type_3 target_coordinates,
1307  view_type_4 epsilons) {
1308  this->setNeighborLists<view_type_1>(cr_neighbor_lists, number_of_neighbors_list);
1309  this->setSourceSites<view_type_2>(source_coordinates);
1310  this->setTargetSites<view_type_3>(target_coordinates);
1311  this->setWindowSizes<view_type_4>(epsilons);
1312  }
1313 
1314  //! (OPTIONAL) Sets additional evaluation sites for each target site
1315  template<typename view_type_1, typename view_type_2>
1317  view_type_1 additional_evaluation_indices,
1318  view_type_2 additional_evaluation_coordinates) {
1319  this->setAuxiliaryEvaluationIndicesLists<view_type_1>(additional_evaluation_indices);
1320  this->setAuxiliaryEvaluationCoordinates<view_type_2>(additional_evaluation_coordinates);
1321  }
1322 
1323  //! Sets neighbor list information from compressed row neighborhood lists data (if same view_type).
1324  template <typename view_type>
1325  typename std::enable_if<view_type::rank==1&&std::is_same<decltype(_neighbor_lists)::internal_view_type,view_type>::value==1, void>::type
1326  setNeighborLists(view_type neighbor_lists, view_type number_of_neighbors_list) {
1327 
1328  _neighbor_lists = NeighborLists<view_type>(neighbor_lists, number_of_neighbors_list);
1331  Kokkos::parallel_for("copy neighbor list sizes", Kokkos::RangePolicy<host_execution_space>(0, _host_number_of_neighbors_list.extent(0)), KOKKOS_LAMBDA(const int i) {
1333  });
1334  Kokkos::fence();
1335  this->resetCoefficientData();
1336 
1337  }
1338 
1339  //! Sets neighbor list information from compressed row neighborhood lists data (if different view_type).
1340  template <typename view_type>
1341  typename std::enable_if<view_type::rank==1&&std::is_same<decltype(_neighbor_lists)::internal_view_type,view_type>::value==0, void>::type
1342  setNeighborLists(view_type neighbor_lists, view_type number_of_neighbors_list) {
1343 
1344  typedef decltype(_neighbor_lists)::internal_view_type gmls_view_type;
1345  gmls_view_type d_neighbor_lists("compressed row neighbor lists data", neighbor_lists.extent(0));
1346  gmls_view_type d_number_of_neighbors_list("number of neighbors list", number_of_neighbors_list.extent(0));
1347  Kokkos::deep_copy(d_neighbor_lists, neighbor_lists);
1348  Kokkos::deep_copy(d_number_of_neighbors_list, number_of_neighbors_list);
1349  Kokkos::fence();
1350  _neighbor_lists = NeighborLists<gmls_view_type>(d_neighbor_lists, d_number_of_neighbors_list);
1353  Kokkos::parallel_for("copy neighbor list sizes", Kokkos::RangePolicy<host_execution_space>(0, _host_number_of_neighbors_list.extent(0)), KOKKOS_LAMBDA(const int i) {
1355  });
1356  Kokkos::fence();
1357  this->resetCoefficientData();
1358 
1359  }
1360 
1361  //! Sets neighbor list information. Should be # targets x maximum number of neighbors for any target + 1.
1362  //! first entry in ever row should be the number of neighbors for the corresponding target.
1363  template <typename view_type>
1364  typename std::enable_if<view_type::rank==2, void>::type setNeighborLists(view_type neighbor_lists) {
1365 
1366  _neighbor_lists = Convert2DToCompressedRowNeighborLists<decltype(neighbor_lists), Kokkos::View<int*> >(neighbor_lists);
1369  Kokkos::parallel_for("copy neighbor list sizes", Kokkos::RangePolicy<host_execution_space>(0, _host_number_of_neighbors_list.extent(0)), KOKKOS_LAMBDA(const int i) {
1371  });
1372  Kokkos::fence();
1373  this->resetCoefficientData();
1374 
1375  }
1376 
1377  //! Sets source coordinate information. Rows of this 2D-array should correspond to neighbor IDs contained in the entries
1378  //! of the neighbor lists 2D array.
1379  template<typename view_type>
1380  void setSourceSites(view_type source_coordinates) {
1381 
1382  // allocate memory on device
1383  _source_coordinates = decltype(_source_coordinates)("device neighbor coordinates",
1384  source_coordinates.extent(0), source_coordinates.extent(1));
1385 
1386  typedef typename view_type::memory_space input_array_memory_space;
1387  if (std::is_same<input_array_memory_space, device_memory_space>::value) {
1388  // check if on the device, then copy directly
1389  // if it is, then it doesn't match the internal layout we use
1390  // then copy to the host mirror
1391  // switches potential layout mismatches
1392  Kokkos::deep_copy(_source_coordinates, source_coordinates);
1393  } else {
1394  // if is on the host, copy to the host mirror
1395  // then copy to the device
1396  // switches potential layout mismatches
1397  auto host_source_coordinates = Kokkos::create_mirror_view(_source_coordinates);
1398  Kokkos::deep_copy(host_source_coordinates, source_coordinates);
1399  // switches memory spaces
1400  Kokkos::deep_copy(_source_coordinates, host_source_coordinates);
1401  }
1402  this->resetCoefficientData();
1403  }
1404 
1405  //! Sets source coordinate information. Rows of this 2D-array should correspond to neighbor IDs contained in the entries
1406  //! of the neighbor lists 2D array.
1407  template<typename view_type>
1408  void setSourceSites(decltype(_source_coordinates) source_coordinates) {
1409  // allocate memory on device
1410  _source_coordinates = source_coordinates;
1411  this->resetCoefficientData();
1412  }
1413 
1414  //! Sets target coordinate information. Rows of this 2D-array should correspond to rows of the neighbor lists.
1415  template<typename view_type>
1416  void setTargetSites(view_type target_coordinates) {
1417  // allocate memory on device
1418  _target_coordinates = decltype(_target_coordinates)("device target coordinates",
1419  target_coordinates.extent(0), target_coordinates.extent(1));
1420 
1421  typedef typename view_type::memory_space input_array_memory_space;
1422  if (std::is_same<input_array_memory_space, device_memory_space>::value) {
1423  // check if on the device, then copy directly
1424  // if it is, then it doesn't match the internal layout we use
1425  // then copy to the host mirror
1426  // switches potential layout mismatches
1427  Kokkos::deep_copy(_target_coordinates, target_coordinates);
1428  } else {
1429  // if is on the host, copy to the host mirror
1430  // then copy to the device
1431  // switches potential layout mismatches
1432  auto host_target_coordinates = Kokkos::create_mirror_view(_target_coordinates);
1433  Kokkos::deep_copy(host_target_coordinates, target_coordinates);
1434  // switches memory spaces
1435  Kokkos::deep_copy(_target_coordinates, host_target_coordinates);
1436  }
1438  = decltype(_number_of_additional_evaluation_indices)("number of additional evaluation indices", target_coordinates.extent(0));
1439  Kokkos::deep_copy(_number_of_additional_evaluation_indices, 0);
1440  this->resetCoefficientData();
1441  }
1442 
1443  //! Sets target coordinate information. Rows of this 2D-array should correspond to rows of the neighbor lists.
1444  template<typename view_type>
1445  void setTargetSites(decltype(_target_coordinates) target_coordinates) {
1446  // allocate memory on device
1447  _target_coordinates = target_coordinates;
1449  = decltype(_number_of_additional_evaluation_indices)("number of additional evaluation indices", target_coordinates.extent(0));
1450  Kokkos::deep_copy(_number_of_additional_evaluation_indices, 0);
1451  this->resetCoefficientData();
1452  }
1453 
1454  //! Sets window sizes, also called the support of the kernel
1455  template<typename view_type>
1456  void setWindowSizes(view_type epsilons) {
1457 
1458  // allocate memory on device
1459  _epsilons = decltype(_epsilons)("device epsilons", epsilons.extent(0));
1460 
1461  _host_epsilons = Kokkos::create_mirror_view(_epsilons);
1462  Kokkos::deep_copy(_host_epsilons, epsilons);
1463  // copy data from host to device
1464  Kokkos::deep_copy(_epsilons, _host_epsilons);
1465  this->resetCoefficientData();
1466  }
1467 
1468  //! Sets window sizes, also called the support of the kernel (device)
1469  template<typename view_type>
1471  // allocate memory on device
1472  _epsilons = epsilons;
1473  this->resetCoefficientData();
1474  }
1475 
1476  //! (OPTIONAL)
1477  //! Sets orthonormal tangent directions for reconstruction on a manifold. The first rank of this 2D array
1478  //! corresponds to the target indices, i.e., rows of the neighbor lists 2D array. The second rank is the
1479  //! ordinal of the tangent direction (spatial dimensions-1 are tangent, last one is normal), and the third
1480  //! rank is indices into the spatial dimension.
1481  template<typename view_type>
1482  void setTangentBundle(view_type tangent_directions) {
1483  // accept input from user as a rank 3 tensor
1484  // but convert data to a rank 2 tensor with the last rank of dimension = _dimensions x _dimensions
1485  // this allows for nonstrided views on the device later
1486 
1487  // allocate memory on device
1488  _T = decltype(_T)("device tangent directions", _target_coordinates.extent(0)*_dimensions*_dimensions);
1489 
1490  compadre_assert_release( (std::is_same<decltype(_T)::memory_space, typename view_type::memory_space>::value) &&
1491  "Memory space does not match between _T and tangent_directions");
1492 
1493  auto this_dimensions = _dimensions;
1494  auto this_T = _T;
1495  // rearrange data on device from data given on host
1496  Kokkos::parallel_for("copy tangent vectors", Kokkos::RangePolicy<device_execution_space>(0, _target_coordinates.extent(0)), KOKKOS_LAMBDA(const int i) {
1497  scratch_matrix_right_type T(this_T.data() + i*this_dimensions*this_dimensions, this_dimensions, this_dimensions);
1498  for (int j=0; j<this_dimensions; ++j) {
1499  for (int k=0; k<this_dimensions; ++k) {
1500  T(j,k) = tangent_directions(i, j, k);
1501  }
1502  }
1503  });
1505 
1506  // copy data from device back to host in rearranged format
1507  _host_T = Kokkos::create_mirror_view(_T);
1508  Kokkos::deep_copy(_host_T, _T);
1509  this->resetCoefficientData();
1510  }
1511 
1512  //! (OPTIONAL)
1513  //! Sets outward normal direction. For manifolds this may be used for orienting surface. It is also accessible
1514  //! for sampling operators that require a normal direction.
1515  template<typename view_type>
1516  void setReferenceOutwardNormalDirection(view_type outward_normal_directions, bool use_to_orient_surface = true) {
1517  // accept input from user as a rank 2 tensor
1518 
1519  // allocate memory on device
1520  _ref_N = decltype(_ref_N)("device normal directions", _target_coordinates.extent(0)*_dimensions);
1521  // to assist LAMBDA capture
1522  auto this_ref_N = this->_ref_N;
1523  auto this_dimensions = this->_dimensions;
1524 
1525  // rearrange data on device from data given on host
1526  Kokkos::parallel_for("copy normal vectors", Kokkos::RangePolicy<device_execution_space>(0, _target_coordinates.extent(0)), KOKKOS_LAMBDA(const int i) {
1527  for (int j=0; j<this_dimensions; ++j) {
1528  this_ref_N(i*this_dimensions + j) = outward_normal_directions(i, j);
1529  }
1530  });
1531  Kokkos::fence();
1534 
1535  // copy data from device back to host in rearranged format
1536  _host_ref_N = Kokkos::create_mirror_view(_ref_N);
1537  Kokkos::deep_copy(_host_ref_N, _ref_N);
1538  this->resetCoefficientData();
1539  }
1540 
1541  //! (OPTIONAL)
1542  //! Sets extra data to be used by sampling functionals in certain instances.
1543  template<typename view_type>
1544  void setSourceExtraData(view_type extra_data) {
1545 
1546  // allocate memory on device
1547  _source_extra_data = decltype(_source_extra_data)("device source extra data", extra_data.extent(0), extra_data.extent(1));
1548 
1549  auto host_extra_data = Kokkos::create_mirror_view(_source_extra_data);
1550  Kokkos::deep_copy(host_extra_data, extra_data);
1551  // copy data from host to device
1552  Kokkos::deep_copy(_source_extra_data, host_extra_data);
1553  this->resetCoefficientData();
1554  }
1555 
1556  //! (OPTIONAL)
1557  //! Sets extra data to be used by sampling functionals in certain instances. (device)
1558  template<typename view_type>
1560  // allocate memory on device
1561  _source_extra_data = extra_data;
1562  this->resetCoefficientData();
1563  }
1564 
1565  //! (OPTIONAL)
1566  //! Sets extra data to be used by target operations in certain instances.
1567  template<typename view_type>
1568  void setTargetExtraData(view_type extra_data) {
1569 
1570  // allocate memory on device
1571  _target_extra_data = decltype(_target_extra_data)("device target extra data", extra_data.extent(0), extra_data.extent(1));
1572 
1573  auto host_extra_data = Kokkos::create_mirror_view(_target_extra_data);
1574  Kokkos::deep_copy(host_extra_data, extra_data);
1575  // copy data from host to device
1576  Kokkos::deep_copy(_target_extra_data, host_extra_data);
1577  this->resetCoefficientData();
1578  }
1579 
1580  //! (OPTIONAL)
1581  //! Sets extra data to be used by target operations in certain instances. (device)
1582  template<typename view_type>
1584  // allocate memory on device
1585  _target_extra_data = extra_data;
1586  this->resetCoefficientData();
1587  }
1588 
1589  //! (OPTIONAL)
1590  //! Sets additional points for evaluation of target operation on polynomial reconstruction.
1591  //! If this is never called, then the target sites are the only locations where the target
1592  //! operations will be evaluated and applied to polynomial reconstructions.
1593  template <typename view_type>
1594  void setAuxiliaryEvaluationCoordinates(view_type evaluation_coordinates) {
1595  // allocate memory on device
1596  _additional_evaluation_coordinates = decltype(_additional_evaluation_coordinates)("device additional evaluation coordinates",
1597  evaluation_coordinates.extent(0), evaluation_coordinates.extent(1));
1598 
1599  typedef typename view_type::memory_space input_array_memory_space;
1600  if (std::is_same<input_array_memory_space, device_memory_space>::value) {
1601  // check if on the device, then copy directly
1602  // if it is, then it doesn't match the internal layout we use
1603  // then copy to the host mirror
1604  // switches potential layout mismatches
1605  Kokkos::deep_copy(_additional_evaluation_coordinates, evaluation_coordinates);
1606  } else {
1607  // if is on the host, copy to the host mirror
1608  // then copy to the device
1609  // switches potential layout mismatches
1610  auto host_additional_evaluation_coordinates = Kokkos::create_mirror_view(_additional_evaluation_coordinates);
1611  Kokkos::deep_copy(host_additional_evaluation_coordinates, evaluation_coordinates);
1612  // switches memory spaces
1613  Kokkos::deep_copy(_additional_evaluation_coordinates, host_additional_evaluation_coordinates);
1614  }
1615  this->resetCoefficientData();
1616  }
1617 
1618  //! (OPTIONAL)
1619  //! Sets additional points for evaluation of target operation on polynomial reconstruction.
1620  //! If this is never called, then the target sites are the only locations where the target
1621  //! operations will be evaluated and applied to polynomial reconstructions. (device)
1622  template <typename view_type>
1624  _additional_evaluation_coordinates = evaluation_coordinates;
1625  this->resetCoefficientData();
1626  }
1627 
1628  //! (OPTIONAL)
1629  //! Sets the additional target evaluation coordinate indices list information. Should be # targets x maximum number of indices
1630  //! evaluation indices for any target + 1. first entry in every row should be the number of indices for the corresponding target.
1631  template <typename view_type>
1632  void setAuxiliaryEvaluationIndicesLists(view_type indices_lists) {
1633  // allocate memory on device
1634  _additional_evaluation_indices = decltype(_additional_evaluation_indices)("device additional evaluation indices",
1635  indices_lists.extent(0), indices_lists.extent(1));
1636 
1638 
1639  typedef typename view_type::memory_space input_array_memory_space;
1640  if (std::is_same<input_array_memory_space, device_memory_space>::value) {
1641  // check if on the device, then copy directly
1642  // if it is, then it doesn't match the internal layout we use
1643  // then copy to the host mirror
1644  // switches potential layout mismatches
1645  Kokkos::deep_copy(_additional_evaluation_indices, indices_lists);
1647  } else {
1648  // if is on the host, copy to the host mirror
1649  // then copy to the device
1650  // switches potential layout mismatches
1651  Kokkos::deep_copy(_host_additional_evaluation_indices, indices_lists);
1652  // copy data from host to device
1654  }
1655 
1657  auto number_of_additional_evaluation_indices = _number_of_additional_evaluation_indices;
1658  auto additional_evaluation_indices = _additional_evaluation_indices;
1659  Kokkos::parallel_reduce("additional evaluation indices",
1660  Kokkos::RangePolicy<device_execution_space>(0, _additional_evaluation_indices.extent(0)),
1661  KOKKOS_LAMBDA(const int i, int& t_max_evaluation_sites_per_target) {
1662  number_of_additional_evaluation_indices(i) = additional_evaluation_indices(i,0);
1663  t_max_evaluation_sites_per_target = (t_max_evaluation_sites_per_target > number_of_additional_evaluation_indices(i)+1)
1664  ? t_max_evaluation_sites_per_target : number_of_additional_evaluation_indices(i)+1;
1665  }, Kokkos::Max<int>(_max_evaluation_sites_per_target));
1666  Kokkos::fence();
1667  this->resetCoefficientData();
1668  }
1669 
1670  //! (OPTIONAL)
1671  //! Sets the additional target evaluation coordinate indices list information. Should be # targets x maximum number of indices
1672  //! evaluation indices for any target + 1. first entry in every row should be the number of indices for the corresponding target.
1673  template <typename view_type>
1675  // allocate memory on device
1676  _additional_evaluation_indices = indices_lists;
1677 
1679  // copy data from host to device
1681 
1683  auto number_of_additional_evaluation_indices = _number_of_additional_evaluation_indices;
1684  auto additional_evaluation_indices = _additional_evaluation_indices;
1685  Kokkos::parallel_reduce("additional evaluation indices",
1686  Kokkos::RangePolicy<device_execution_space>(0, _additional_evaluation_indices.extent(0)),
1687  KOKKOS_LAMBDA(const int i, int& t_max_evaluation_sites_per_target) {
1688  number_of_additional_evaluation_indices(i) = additional_evaluation_indices(i,0);
1689  t_max_evaluation_sites_per_target = (t_max_evaluation_sites_per_target > number_of_additional_evaluation_indices(i)+1)
1690  ? t_max_evaluation_sites_per_target : number_of_additional_evaluation_indices(i)+1;
1691  }, Kokkos::Max<int>(_max_evaluation_sites_per_target));
1692  Kokkos::fence();
1693  this->resetCoefficientData();
1694  }
1695 
1696 
1697  //! Type for weighting kernel for GMLS problem
1698  void setWeightingType( const std::string &wt) {
1699  std::string wt_to_lower = wt;
1700  transform(wt_to_lower.begin(), wt_to_lower.end(), wt_to_lower.begin(), ::tolower);
1701  if (wt_to_lower == "power") {
1703  } else if (wt_to_lower == "gaussian") {
1705  } else if (wt_to_lower == "cubicspline") {
1707  } else {
1708  // Power is default
1710  }
1711  this->resetCoefficientData();
1712  }
1713 
1714  //! Type for weighting kernel for GMLS problem
1716  _weighting_type = wt;
1717  this->resetCoefficientData();
1718  }
1719 
1720  //! Type for weighting kernel for curvature
1721  void setCurvatureWeightingType( const std::string &wt) {
1722  std::string wt_to_lower = wt;
1723  transform(wt_to_lower.begin(), wt_to_lower.end(), wt_to_lower.begin(), ::tolower);
1724  if (wt_to_lower == "power") {
1726  } else if (wt_to_lower == "gaussian") {
1728  } else if (wt_to_lower == "cubicspline") {
1730  } else {
1731  // Power is default
1733  }
1734  this->resetCoefficientData();
1735  }
1736 
1737  //! Type for weighting kernel for curvature
1740  this->resetCoefficientData();
1741  }
1742 
1743  //! Sets basis order to be used when reoncstructing any function
1744  void setPolynomialOrder(const int poly_order) {
1745  _poly_order = poly_order;
1747  this->resetCoefficientData();
1748  }
1749 
1750  //! Sets basis order to be used when reoncstructing curvature
1751  void setCurvaturePolynomialOrder(const int manifold_poly_order) {
1752  _curvature_poly_order = manifold_poly_order;
1753  this->resetCoefficientData();
1754  }
1755 
1756  //! Power for weighting kernel for GMLS problem
1757  void setWeightingPower(int wp) {
1758  _weighting_power = wp;
1759  this->resetCoefficientData();
1760  }
1761 
1762  //! Power for weighting kernel for curvature
1765  this->resetCoefficientData();
1766  }
1767 
1768  //! Number quadrature points to use
1769  void setOrderOfQuadraturePoints(int order) {
1771  this->resetCoefficientData();
1772  }
1773 
1774  //! Dimensions of quadrature points to use
1777  this->resetCoefficientData();
1778  }
1779 
1780  //! Type of quadrature points
1781  void setQuadratureType(std::string quadrature_type) {
1782  _quadrature_type = quadrature_type;
1783  this->resetCoefficientData();
1784  }
1785 
1786  //! Adds a target to the vector of target functional to be applied to the reconstruction
1788  std::vector<TargetOperation> temporary_lro_vector(1, lro);
1789  this->addTargets(temporary_lro_vector);
1790  this->resetCoefficientData();
1791  }
1792 
1793  //! Adds a vector of target functionals to the vector of target functionals already to be applied to the reconstruction
1794  void addTargets(std::vector<TargetOperation> lro) {
1795  // if called multiple times with different dimensions, only the last
1796  // dimension called with is used for all
1797 
1798  // loop over requested targets
1799  for (size_t i=0; i<lro.size(); ++i) {
1800 
1801  bool operation_found = false;
1802  // loop over existing targets registered
1803  for (size_t j=0; j<_lro.size(); ++j) {
1804 
1805  // if found
1806  if (_lro[j]==lro[i]) {
1807 
1808  operation_found = true;
1809 
1810  // the operation should now point to where the operation is stored
1811  _lro_lookup[(int)lro[i]] = j;
1812 
1813  break;
1814 
1815  }
1816  }
1817 
1818  if (!operation_found) {
1819  _lro_lookup[(int)lro[i]] = _lro.size();
1820  _lro.push_back(lro[i]);
1821  }
1822  }
1823 
1824  _lro_total_offsets = Kokkos::View<int*>("total offsets for alphas", _lro.size());
1825  _lro_output_tile_size = Kokkos::View<int*>("output tile size for each operation", _lro.size());
1826  _lro_input_tile_size = Kokkos::View<int*>("output tile size for each operation", _lro.size());
1827  _lro_output_tensor_rank = Kokkos::View<int*>("output tensor rank", _lro.size());
1828  _lro_input_tensor_rank = Kokkos::View<int*>("input tensor rank", _lro.size());
1829 
1830  _host_lro_total_offsets = create_mirror_view(_lro_total_offsets);
1831  _host_lro_output_tile_size = create_mirror_view(_lro_output_tile_size);
1832  _host_lro_input_tile_size = create_mirror_view(_lro_input_tile_size);
1833  _host_lro_output_tensor_rank = create_mirror_view(_lro_output_tensor_rank);
1834  _host_lro_input_tensor_rank = create_mirror_view(_lro_input_tensor_rank);
1835 
1836  int total_offset = 0; // need total offset
1837  int output_offset = 0;
1838  int input_offset = 0;
1839  for (size_t i=0; i<_lro.size(); ++i) {
1840  _host_lro_total_offsets(i) = total_offset;
1841 
1842  // allows for a tile of the product of dimension^input_tensor_rank * dimension^output_tensor_rank * the number of neighbors
1843  int output_tile_size = getOutputDimensionOfOperation(_lro[i], false /* uses _local_dimension */);
1844 
1845  // the target functional input indexing is sized based on the output rank of the sampling
1846  // functional used
1848  _host_lro_output_tile_size(i) = output_tile_size;
1849  _host_lro_input_tile_size(i) = input_tile_size;
1850 
1851  total_offset += input_tile_size * output_tile_size;
1852  output_offset += output_tile_size;
1853  input_offset += input_tile_size;
1854 
1855  // the target functional output rank is based on the output rank of the sampling
1856  // functional used
1859  }
1860 
1861  _total_alpha_values = total_offset;
1862 
1864  // if on a manifold, the total alphas values must be large enough to hold the gradient
1865  // of the geometry reconstruction
1867  _total_alpha_values : std::pow(_local_dimensions, 1);
1868  }
1869 
1870  Kokkos::deep_copy(_lro_total_offsets, _host_lro_total_offsets);
1871  Kokkos::deep_copy(_lro_output_tile_size, _host_lro_output_tile_size);
1872  Kokkos::deep_copy(_lro_input_tile_size, _host_lro_input_tile_size);
1873  Kokkos::deep_copy(_lro_output_tensor_rank, _host_lro_output_tensor_rank);
1874  Kokkos::deep_copy(_lro_input_tensor_rank, _host_lro_input_tensor_rank);
1875  this->resetCoefficientData();
1876  }
1877 
1878  //! Empties the vector of target functionals to apply to the reconstruction
1879  void clearTargets() {
1880  _lro.clear();
1881  for (int i=0; i<TargetOperation::COUNT; ++i) {
1882  _lro_lookup[i] = -1;
1883  }
1884  this->resetCoefficientData();
1885  }
1886 
1887  /*! \brief Generates polynomial coefficients by setting up and solving least squares problems
1888  //! Sets up the batch of GMLS problems to be solved for. Provides alpha values
1889  //! that can later be contracted against data or degrees of freedom to form a
1890  //! global linear system.
1891  //! \param number_of_batches [in] - how many batches to break up the total workload into (for storage)
1892  //! \param keep_coefficients [in] - whether to store (P^T W P)^-1 * P^T * W
1893  */
1894  void generatePolynomialCoefficients(const int number_of_batches = 1, const bool keep_coefficients = false);
1895 
1896  /*! \brief Meant to calculate target operations and apply the evaluations to the previously
1897  //! constructed polynomial coefficients. But now that is inside of generatePolynomialCoefficients because
1898  //! it must be to handle number_of_batches>1. Effectively, this just calls generatePolynomialCoefficients.
1899  //! \param number_of_batches [in] - how many batches to break up the total workload into (for storage)
1900  //! \param keep_coefficients [in] - whether to store (P^T W P)^-1 * P^T * W
1901  */
1902  void generateAlphas(const int number_of_batches = 1, const bool keep_coefficients = false);
1903 
1904 ///@}
1905 
1906 
1907 
1908 
1909 }; // GMLS Class
1910 } // Compadre
1911 
1912 #endif
1913 
1914 
Kokkos::View< double * > _manifold_metric_tensor_inverse
metric tensor inverse for all problems
Divergence-free vector polynomial basis.
Kokkos::View< int * > _lro_input_tile_size
dimensions ^ rank of tensor of output for each sampling functional (device)
Kokkos::View< double *, layout_right > _alphas
generated alpha coefficients (device)
double getAlpha2TensorTo0Tensor(TargetOperation lro, const int target_index, const int neighbor_index, const int input_component_axis_1, const int input_component_axis_2, const int additional_evaluation_site=0) const
Helper function for getting alphas for scalar reconstruction from matrix data.
SamplingFunctional getDataSamplingFunctional() const
Get the data sampling functional specified at instantiation (often the same as the polynomial samplin...
int calculateBasisMultiplier(const ReconstructionSpace rs) const
Calculate basis_multiplier.
ReconstructionSpace getReconstructionSpace() const
Get the reconstruction space specified at instantiation.
Standard GMLS problem type.
std::size_t global_index_type
Kokkos::View< const double *****, layout_right >::HostMirror _host_prestencil_weights
generated weights for nontraditional samples required to transform data into expected sampling functi...
Kokkos::View< TargetOperation * > _operations
vector containing target functionals to be applied for reconstruction problem (device) ...
KOKKOS_INLINE_FUNCTION int getMaxNNeighbors() const
Returns the maximum neighbor lists size over all target sites.
int getManifoldWeightingPower() const
Power for weighting kernel for curvature.
bool _entire_batch_computed_at_once
whether entire calculation was computed at once the alternative is that it was broken up over many sm...
int getWeightingPower() const
Power for weighting kernel for GMLS problem.
int _max_evaluation_sites_per_target
maximum number of evaluation sites for each target (includes target site)
ProblemType getProblemType()
Get problem type.
KOKKOS_INLINE_FUNCTION int getMaxNumNeighbors() const
Get the maximum number of neighbors of all targets&#39; neighborhoods (host/device)
Kokkos::View< double * > _manifold_curvature_coefficients
curvature polynomial coefficients for all problems
int _curvature_weighting_power
power to be used for weighting kernel for curvature
int output_rank
Rank of sampling functional output for each SamplingFunctional.
void generatePolynomialCoefficients(const int number_of_batches=1, const bool keep_coefficients=false)
Generates polynomial coefficients by setting up and solving least squares problems ! Sets up the batc...
static KOKKOS_INLINE_FUNCTION double EuclideanVectorLength(const XYZ &delta_vector, const int dimension)
Returns Euclidean norm of a vector.
Kokkos::View< int **, layout_right > _additional_evaluation_indices
(OPTIONAL) contains indices of entries in the _additional_evaluation_coordinates view (device) ...
Tag for functor to evaluate curvature targets and apply to coefficients of curvature reconstruction...
Kokkos::View< double * > _ref_N
Rank 2 tensor for high order approximation of tangent vectors for all problems.
KOKKOS_INLINE_FUNCTION int getSize(const int degree, const int dimension)
Returns size of basis.
double getAlpha1TensorTo0Tensor(TargetOperation lro, const int target_index, const int neighbor_index, const int input_component, const int additional_evaluation_site=0) const
Helper function for getting alphas for scalar reconstruction from vector data.
#define compadre_kernel_assert_release(condition)
compadre_kernel_assert_release is similar to compadre_assert_release, but is a call on the device...
constexpr SamplingFunctional ManifoldVectorPointSample
Point evaluations of the entire vector source function (but on a manifold, so it includes a transform...
decltype(_prestencil_weights) getPrestencilWeights() const
Get a view (device) of all rank 2 preprocessing tensors This is a rank 5 tensor that is able to provi...
GMLS(const int poly_order, const int dimensions=3, const std::string dense_solver_type=std::string("QR"), const std::string problem_type=std::string("STANDARD"), const std::string constraint_type=std::string("NO_CONSTRAINT"), const int manifold_curvature_poly_order=2)
Constructor for the case when the data sampling functional does not match the polynomial sampling fun...
bool _reference_outward_normal_direction_provided
whether or not the reference outward normal directions were provided by the user. ...
int getOutputDimensionOfSampling(SamplingFunctional sro) const
Dimensions ^ output rank for sampling operation (always in local chart if on a manifold, never ambient space)
team_policy::member_type member_type
Neumann Gradient Scalar Type.
int _NP
dimension of basis for polynomial reconstruction
KOKKOS_INLINE_FUNCTION void createWeightsAndP(const member_type &teamMember, scratch_vector_type delta, scratch_vector_type thread_workspace, scratch_matrix_right_type P, scratch_vector_type w, const int dimension, int polynomial_order, bool weight_p=false, scratch_matrix_right_type *V=NULL, const ReconstructionSpace reconstruction_space=ReconstructionSpace::ScalarTaylorPolynomial, const SamplingFunctional sampling_strategy=PointSample) const
Fills the _P matrix with either P or P*sqrt(w)
int _total_alpha_values
used for sizing P_target_row and the _alphas view
Kokkos::View< double * > _epsilons
h supports determined through neighbor search (device)
bool _orthonormal_tangent_space_provided
whether or not the orthonormal tangent directions were provided by the user.
KOKKOS_INLINE_FUNCTION int getTargetOffsetIndexDevice(const int lro_num, const int input_component, const int output_component, const int additional_evaluation_local_index=0) const
Handles offset from operation input/output + extra evaluation sites.
void setProblemData(view_type_1 cr_neighbor_lists, view_type_1 number_of_neighbors_list, view_type_2 source_coordinates, view_type_3 target_coordinates, view_type_4 epsilons)
Sets basic problem data (neighbor lists data, number of neighbors list, source coordinates, and target coordinates)
KOKKOS_INLINE_FUNCTION int getAdditionalEvaluationIndex(const int target_index, const int additional_list_num) const
(OPTIONAL) Mapping from [0,number of additional evaluation sites for a target] to the row that contai...
Kokkos::View< int *, host_memory_space > _host_number_of_neighbors_list
convenient copy on host of number of neighbors
void setQuadratureType(std::string quadrature_type)
Type of quadrature points.
static int getTargetOutputIndex(const int operation_num, const int output_component_axis_1, const int output_component_axis_2, const int dimensions)
Helper function for finding alpha coefficients.
std::string getQuadratureType() const
Type of quadrature points.
WeightingFunctionType getManifoldWeightingType() const
Type for weighting kernel for curvature.
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 * > _RHS
sqrt(w)*Identity matrix for all problems, later holds polynomial coefficients for all problems ...
KOKKOS_INLINE_FUNCTION void calcGradientPij(const member_type &teamMember, double *delta, double *thread_workspace, const int target_index, int neighbor_index, const double alpha, const int partial_direction, const int dimension, const int poly_order, bool specific_order_only, const scratch_matrix_right_type *V, const ReconstructionSpace reconstruction_space, const SamplingFunctional sampling_strategy, const int additional_evaluation_local_index=0) const
Evaluates the gradient of a polynomial basis under the Dirac Delta (pointwise) sampling function...
Kokkos::View< double * > _w
contains weights for all problems
void setWindowSizes(view_type epsilons)
Sets window sizes, also called the support of the kernel.
int _sampling_multiplier
actual dimension of the sampling functional e.g.
int _reconstruction_space_rank
actual rank of reconstruction basis
int _curvature_poly_order
order of basis for curvature reconstruction
decltype(_ref_N) getReferenceNormalDirections() const
Get a view (device) of all reference outward normal directions.
int getNumberOfNeighborsHost(int target_index) const
Get number of neighbors for a given target (host)
Kokkos::View< double **, layout_right > _target_coordinates
coordinates for target sites for reconstruction (device)
Each target applies a different data transform, but the same to each neighbor.
KOKKOS_INLINE_FUNCTION void calcPij(const member_type &teamMember, double *delta, double *thread_workspace, const int target_index, int neighbor_index, const double alpha, const int dimension, const int poly_order, bool specific_order_only=false, const scratch_matrix_right_type *V=NULL, const ReconstructionSpace reconstruction_space=ReconstructionSpace::ScalarTaylorPolynomial, const SamplingFunctional sampling_strategy=PointSample, const int additional_evaluation_local_index=0) const
Evaluates the polynomial basis under a particular sampling function. Generally used to fill a row of ...
std::enable_if< view_type::rank==2, void >::type setNeighborLists(view_type neighbor_lists)
Sets neighbor list information.
int _data_sampling_multiplier
effective dimension of the data sampling functional e.g.
std::vector< int > _lro_lookup
vector containing a mapping from a target functionals enum value to the its place in the list of targ...
KOKKOS_INLINE_FUNCTION global_index_type getAlphaIndexDevice(const int target_index, const int alpha_column_offset) const
Gives index into alphas given two axes, which when incremented by the neighbor number transforms acce...
Each target applies a different transform for each neighbor.
NeighborLists< Kokkos::View< int * > > _neighbor_lists
Accessor to get neighbor list data, offset data, and number of neighbors per target.
Quadrature _qm
manages and calculates quadrature
Kokkos::View< double * >::HostMirror _host_T
tangent vectors information (host)
int getInputDimensionOfOperation(TargetOperation lro) const
Dimensions ^ input rank for target operation (always in local chart if on a manifold, never ambient space)
double getAlpha0TensorTo1Tensor(TargetOperation lro, const int target_index, const int output_component, const int neighbor_index, const int additional_evaluation_site=0) const
Helper function for getting alphas for vector reconstruction from scalar data.
KOKKOS_INLINE_FUNCTION double convertGlobalToLocalCoordinate(const XYZ global_coord, const int dim, const scratch_matrix_right_type *V) const
Returns a component of the local coordinate after transformation from global to local under the ortho...
Kokkos::View< int * >::HostMirror _host_lro_input_tensor_rank
tensor rank of sampling functional (host)
void clearTargets()
Empties the vector of target functionals to apply to the reconstruction.
std::vector< TargetOperation > _lro
vector of user requested target operations
void setTargetExtraData(view_type extra_data)
(OPTIONAL) Sets extra data to be used by target operations in certain instances.
global_index_type getAlphaIndexHost(const int target_index, const int alpha_column_offset) const
Gives index into alphas given two axes, which when incremented by the neighbor number transforms acce...
void setReferenceOutwardNormalDirection(view_type outward_normal_directions, bool use_to_orient_surface=true)
(OPTIONAL) Sets outward normal direction.
int getOrderOfQuadraturePoints() const
Order of quadrature points.
void setAuxiliaryEvaluationIndicesLists(decltype(_additional_evaluation_indices) indices_lists)
(OPTIONAL) Sets the additional target evaluation coordinate indices list information.
void setDimensionOfQuadraturePoints(int dim)
Dimensions of quadrature points to use.
Scalar polynomial basis centered at the target site and scaled by sum of basis powers e...
Solve GMLS problem on a manifold (will use QR or SVD to solve the resultant GMLS problem dependent on...
int getAlphaColumnOffset(TargetOperation lro, const int output_component_axis_1, const int output_component_axis_2, const int input_component_axis_1, const int input_component_axis_2, const int additional_evaluation_local_index=0) const
Retrieves the offset for an operator based on input and output component, generic to row (but still m...
decltype(_T) getTangentDirections() const
Get a view (device) of all tangent direction bundles.
int _max_num_neighbors
maximum number of neighbors over all target sites
Kokkos::View< int * > _lro_input_tensor_rank
tensor rank of sampling functional (device)
Should be the total count of all available target functionals.
Kokkos::View< int * >::HostMirror _host_lro_output_tensor_rank
tensor rank of target functional (host)
WeightingFunctionType _curvature_weighting_type
weighting kernel type for curvature problem
WeightingFunctionType _weighting_type
weighting kernel type for GMLS
Kokkos::View< int * > _lro_output_tile_size
dimensions ^ rank of tensor of output for each target functional (device)
static KOKKOS_INLINE_FUNCTION int getNN(const int m, const int dimension=3, const ReconstructionSpace r_space=ReconstructionSpace::ScalarTaylorPolynomial)
Returns number of neighbors needed for unisolvency for a given basis order and dimension.
const SamplingFunctional _data_sampling_functional
generally the same as _polynomial_sampling_functional, but can differ if specified at GMLS class inst...
constexpr int TargetOutputTensorRank[]
Rank of target functional output for each TargetOperation Rank of target functional input for each Ta...
double getAlpha2TensorTo2Tensor(TargetOperation lro, const int target_index, const int output_component_axis_1, const int output_component_axis_2, const int neighbor_index, const int input_component_axis_1, const int input_component_axis_2, const int additional_evaluation_site=0) const
Helper function for getting alphas for matrix reconstruction from matrix data.
double getAlpha1TensorTo1Tensor(TargetOperation lro, const int target_index, const int output_component, const int neighbor_index, const int input_component, const int additional_evaluation_site=0) const
Helper function for getting alphas for vector reconstruction from vector data.
Tag for functor to evaluate targets, apply target evaluation to polynomial coefficients to store in _...
static ConstraintType parseConstraintType(const std::string &constraint_type)
Parses a string to determine constraint type.
KOKKOS_INLINE_FUNCTION int getNeighborDevice(int target_index, int neighbor_num) const
Offers N(i,j) indexing where N(i,j) is the index of the jth neighbor of i (device) ...
DenseSolverType _dense_solver_type
solver type for GMLS problem - can be QR, SVD or LU
static ProblemType parseProblemType(const std::string &problem_type)
Parses a string to determine problem type.
QR factorization performed on P*sqrt(w) matrix.
double getAlpha1TensorTo2Tensor(TargetOperation lro, const int target_index, const int output_component_axis_1, const int output_component_axis_2, const int neighbor_index, const int input_component, const int additional_evaluation_site=0) const
Helper function for getting alphas for matrix reconstruction from vector data.
void addTargets(TargetOperation lro)
Adds a target to the vector of target functional to be applied to the reconstruction.
Tag for functor to create a coarse tangent approximation from a given neighborhood of points...
pool_type _random_number_pool
Kokkos::View< int * > _lro_total_offsets
index for where this operation begins the for _alpha coefficients (device)
Kokkos::View< double * > _manifold_curvature_gradient
_dimension-1 gradient values for curvature for all problems
void setSourceExtraData(view_type extra_data)
(OPTIONAL) Sets extra data to be used by sampling functionals in certain instances.
double getAlpha(TargetOperation lro, const int target_index, const int output_component_axis_1, const int output_component_axis_2, const int neighbor_index, const int input_component_axis_1, const int input_component_axis_2, const int additional_evaluation_site=0) const
Underlying function all interface helper functions call to retrieve alpha values. ...
KOKKOS_INLINE_FUNCTION int getNEvaluationSitesPerTarget(const int target_index) const
(OPTIONAL) Returns number of additional evaluation sites for a particular target
KOKKOS_INLINE_FUNCTION int getNeighborIndex(const int target_index, const int neighbor_list_num) const
Mapping from [0,number of neighbors for a target] to the row that contains the source coordinates for...
ProblemType
Problem type, that optionally can handle manifolds.
ConstraintType getConstraintType()
Get constraint type.
Kokkos::View< int *, host_execution_space > host_managed_local_index_type
void setAuxiliaryEvaluationCoordinates(decltype(_additional_evaluation_coordinates) evaluation_coordinates)
(OPTIONAL) Sets additional points for evaluation of target operation on polynomial reconstruction...
void setAuxiliaryEvaluationIndicesLists(view_type indices_lists)
(OPTIONAL) Sets the additional target evaluation coordinate indices list information.
Kokkos::View< double *****, layout_right > _prestencil_weights
generated weights for nontraditional samples required to transform data into expected sampling functi...
void addTargets(std::vector< TargetOperation > lro)
Adds a vector of target functionals to the vector of target functionals already to be applied to the ...
#define TO_GLOBAL(variable)
KOKKOS_INLINE_FUNCTION int getSize(const int degree, const int dimension)
Returns size of basis.
KOKKOS_INLINE_FUNCTION int getNumberOfTargets() const
Get number of total targets having neighborhoods (host/device).
void setCurvatureWeightingType(const std::string &wt)
Type for weighting kernel for curvature.
std::enable_if< view_type::rank==1 &&std::is_same< decltype(_neighbor_lists)::internal_view_type, view_type >::value==1, void >::type setNeighborLists(view_type neighbor_lists, view_type number_of_neighbors_list)
Sets neighbor list information from compressed row neighborhood lists data (if same view_type)...
int _initial_index_for_batch
initial index for current batch
int input_rank
Rank of sampling functional input for each SamplingFunctional.
static KOKKOS_INLINE_FUNCTION int getNP(const int m, const int dimension=3, const ReconstructionSpace r_space=ReconstructionSpace::ScalarTaylorPolynomial)
Returns size of the basis for a given polynomial order and dimension General to dimension 1...
KOKKOS_INLINE_FUNCTION double getNeighborCoordinate(const int target_index, const int neighbor_list_num, const int dim, const scratch_matrix_right_type *V=NULL) const
Returns one component of the neighbor coordinate for a particular target.
KOKKOS_INLINE_FUNCTION double getTargetCoordinate(const int target_index, const int dim, const scratch_matrix_right_type *V=NULL) const
Returns one component of the target coordinate for a particular target.
void setSourceSites(decltype(_source_coordinates) source_coordinates)
Sets source coordinate information.
Kokkos::View< double **, layout_right > _source_extra_data
Extra data available to basis functions (optional)
KOKKOS_INLINE_FUNCTION void computeTargetFunctionalsOnManifold(const member_type &teamMember, scratch_vector_type t1, scratch_vector_type t2, scratch_matrix_right_type P_target_row, scratch_matrix_right_type V, scratch_matrix_right_type G_inv, scratch_vector_type curvature_coefficients, scratch_vector_type curvature_gradients) const
Evaluates a polynomial basis with a target functional applied, using information from the manifold cu...
void setTargetSites(decltype(_target_coordinates) target_coordinates)
Sets target coordinate information. Rows of this 2D-array should correspond to rows of the neighbor l...
Scalar basis reused as many times as there are components in the vector resulting in a much cheaper p...
Kokkos::View< int **, layout_right >::HostMirror _host_additional_evaluation_indices
(OPTIONAL) contains indices of entries in the _additional_evaluation_coordinates view (host) ...
SVD factorization performed on P*sqrt(w) matrix.
void setAdditionalEvaluationSitesData(view_type_1 additional_evaluation_indices, view_type_2 additional_evaluation_coordinates)
(OPTIONAL) Sets additional evaluation sites for each target site
int getPolynomialCoefficientsSize() const
Returns size of the basis used in instance&#39;s polynomial reconstruction.
ReconstructionSpace
Space in which to reconstruct polynomial.
KOKKOS_INLINE_FUNCTION int getNumberOfNeighborsDevice(int target_index) const
Get number of neighbors for a given target (device)
const SamplingFunctional _polynomial_sampling_functional
polynomial sampling functional used to construct P matrix, set at GMLS class instantiation ...
Tag for functor to assemble the P*sqrt(weights) matrix and construct sqrt(weights)*Identity.
std::enable_if< view_type::rank==1 &&std::is_same< decltype(_neighbor_lists)::internal_view_type, view_type >::value==0, void >::type setNeighborLists(view_type neighbor_lists, view_type number_of_neighbors_list)
Sets neighbor list information from compressed row neighborhood lists data (if different view_type)...
DenseSolverType getDenseSolverType()
Get dense solver type.
GMLS(ReconstructionSpace reconstruction_space, SamplingFunctional dual_sampling_strategy, const int poly_order, const int dimensions=3, const std::string dense_solver_type=std::string("QR"), const std::string problem_type=std::string("STANDARD"), const std::string constraint_type=std::string("NO_CONSTRAINT"), const int manifold_curvature_poly_order=2)
Constructor for the case when nonstandard sampling functionals or reconstruction spaces are to be use...
Tag for functor to calculate prestencil weights to apply to data to transform into a format expected ...
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)
Kokkos::View< double * >::HostMirror _host_epsilons
h supports determined through neighbor search (host)
Kokkos::View< double **, layout_right, Kokkos::MemoryTraits< Kokkos::Unmanaged > > scratch_matrix_right_type
Kokkos::View< double *, Kokkos::MemoryTraits< Kokkos::Unmanaged > > scratch_vector_type
KOKKOS_INLINE_FUNCTION int getMaxEvaluationSitesPerTarget() const
Returns the maximum number of evaluation sites over all target sites (target sites are included in to...
void setWeightingType(const WeightingFunctionType wt)
Type for weighting kernel for GMLS problem.
WeightingFunctionType
Available weighting kernel function types.
int getLocalDimensions() const
Local dimension of the GMLS problem (less than global dimension if on a manifold), set only at class instantiation.
NeighborLists assists in accessing entries of compressed row neighborhood lists.
Kokkos::View< double **, layout_right > _source_coordinates
all coordinates for the source for which _neighbor_lists refers (device)
Kokkos::View< int * > _lro_output_tensor_rank
tensor rank of target functional (device)
void setCurvaturePolynomialOrder(const int manifold_poly_order)
Sets basis order to be used when reoncstructing curvature.
void generateAlphas(const int number_of_batches=1, const bool keep_coefficients=false)
Meant to calculate target operations and apply the evaluations to the previously ! constructed polyno...
Kokkos::View< double **, layout_right > _target_extra_data
Extra data available to target operations (optional)
int _dimension_of_quadrature_points
dimension of quadrature rule
decltype(_alphas) getAlphas() const
Get a view (device) of all alphas.
KOKKOS_INLINE_FUNCTION void computeTargetFunctionals(const member_type &teamMember, scratch_vector_type t1, scratch_vector_type t2, scratch_matrix_right_type P_target_row) const
Evaluates a polynomial basis with a target functional applied to each member of the basis...
decltype(_RHS) getFullPolynomialCoefficientsBasis() const
Get a view (device) of all polynomial coefficients basis.
Kokkos::View< double * >::HostMirror _host_ref_N
reference outward normal vectors information (host)
Point evaluation of the gradient of a scalar.
GMLS(ReconstructionSpace reconstruction_space, const SamplingFunctional polynomial_sampling_strategy, const SamplingFunctional data_sampling_strategy, const int poly_order, const int dimensions=3, const std::string dense_solver_type=std::string("QR"), const std::string problem_type=std::string("STANDARD"), const std::string constraint_type=std::string("NO_CONSTRAINT"), const int manifold_curvature_poly_order=2)
Minimal constructor providing no data (neighbor lists, source sites, target sites) ...
int getDimensions() const
Dimension of the GMLS problem, set only at class instantiation.
KOKKOS_INLINE_FUNCTION void createWeightsAndPForCurvature(const member_type &teamMember, scratch_vector_type delta, scratch_vector_type thread_workspace, scratch_matrix_right_type P, scratch_vector_type w, const int dimension, bool only_specific_order, scratch_matrix_right_type *V=NULL) const
Fills the _P matrix with P*sqrt(w) for use in solving for curvature.
Kokkos::View< int * >::HostMirror _host_lro_input_tile_size
dimensions ^ rank of tensor of output for each sampling functional (host)
ParallelManager _pm
determines scratch level spaces and is used to call kernels
int getGlobalDimensions() const
Dimension of the GMLS problem&#39;s point data (spatial description of points in ambient space)...
void setWindowSizes(decltype(_epsilons) epsilons)
Sets window sizes, also called the support of the kernel (device)
KOKKOS_INLINE_FUNCTION void calcHessianPij(const member_type &teamMember, double *delta, double *thread_workspace, const int target_index, int neighbor_index, const double alpha, const int partial_direction_1, const int partial_direction_2, const int dimension, const int poly_order, bool specific_order_only, const scratch_matrix_right_type *V, const ReconstructionSpace reconstruction_space, const SamplingFunctional sampling_strategy, const int additional_evaluation_local_index=0) const
Evaluates the Hessian of a polynomial basis under the Dirac Delta (pointwise) sampling function...
Kokkos::View< TargetOperation * > _curvature_support_operations
vector containing target functionals to be applied for curvature
static int getInputRankOfSampling(SamplingFunctional sro)
Input rank for sampling operation.
KOKKOS_INLINE_FUNCTION void computeCurvatureFunctionals(const member_type &teamMember, scratch_vector_type t1, scratch_vector_type t2, scratch_matrix_right_type P_target_row, const scratch_matrix_right_type *V, const local_index_type local_neighbor_index=-1) const
Evaluates a polynomial basis for the curvature with a gradient target functional applied.
Generalized Moving Least Squares (GMLS)
global_index_type getRowOffsetHost(int target_index) const
Get offset into compressed row neighbor lists (host)
~GMLS()
Destructor.
void setTargetExtraData(decltype(_target_extra_data) extra_data)
(OPTIONAL) Sets extra data to be used by target operations in certain instances.
int _added_alpha_size
additional alpha coefficients due to constraints
ProblemType _problem_type
problem type for GMLS problem, can also be set to STANDARD for normal or MANIFOLD for manifold proble...
int _basis_multiplier
dimension of the reconstructed function e.g.
int _global_dimensions
spatial dimension of the points, set at class instantiation only
Kokkos::View< double **, layout_right > _additional_evaluation_coordinates
(OPTIONAL) user provided additional coordinates for target operation evaluation (device) ...
double getAlpha0TensorTo2Tensor(TargetOperation lro, const int target_index, const int output_component_axis_1, const int output_component_axis_2, const int neighbor_index, const int additional_evaluation_site=0) const
Helper function for getting alphas for matrix reconstruction from scalar data.
DenseSolverType
Dense solver type.
Kokkos::View< double * > _T
Rank 3 tensor for high order approximation of tangent vectors for all problems.
void resetCoefficientData()
double getAlpha0TensorTo0Tensor(TargetOperation lro, const int target_index, const int neighbor_index, const int additional_evaluation_site=0) const
Helper function for getting alphas for scalar reconstruction from scalar data.
int getDimensionOfQuadraturePoints() const
Dimensions of quadrature points.
KOKKOS_INLINE_FUNCTION global_index_type getRowOffsetDevice(int target_index) const
Get offset into compressed row neighbor lists (device)
void setSourceSites(view_type source_coordinates)
Sets source coordinate information.
int getInputDimensionOfSampling(SamplingFunctional sro) const
Dimensions ^ output rank for sampling operation (always in ambient space, never local chart on a mani...
LU factorization performed on P^T*W*P matrix.
bool _store_PTWP_inv_PTW
whether polynomial coefficients were requested to be stored (in a state not yet applied to data) ...
static int getOutputRankOfSampling(SamplingFunctional sro)
Output rank for sampling operation.
int transform_type
Describes the SamplingFunction relationship to targets, neighbors.
Kokkos::View< int * > _number_of_additional_evaluation_indices
(OPTIONAL) contains the # of additional coordinate indices for each target
KOKKOS_INLINE_FUNCTION int getNumberOfQuadraturePoints() const
void setPolynomialOrder(const int poly_order)
Sets basis order to be used when reoncstructing any function.
constexpr int ActualReconstructionSpaceRank[]
Number of actual components in the ReconstructionSpace.
void setTargetSites(view_type target_coordinates)
Sets target coordinate information. Rows of this 2D-array should correspond to rows of the neighbor l...
ReconstructionSpace _reconstruction_space
reconstruction space for GMLS problems, set at GMLS class instantiation
void setAuxiliaryEvaluationCoordinates(view_type evaluation_coordinates)
(OPTIONAL) Sets additional points for evaluation of target operation on polynomial reconstruction...
Kokkos::View< const double *, layout_right >::HostMirror _host_alphas
generated alpha coefficients (host)
Kokkos::Random_XorShift64_Pool pool_type
void setCurvatureWeightingPower(int wp)
Power for weighting kernel for curvature.
int _weighting_power
power to be used for weighting kernel
Kokkos::View< double * > _P
P*sqrt(w) matrix for all problems.
Tag for functor to evaluate targets, apply target evaluation to polynomial coefficients to store in _...
Tag for functor to assemble the P*sqrt(weights) matrix and construct sqrt(weights)*Identity.
void setWeightingType(const std::string &wt)
Type for weighting kernel for GMLS problem.
KOKKOS_INLINE_FUNCTION double getTargetAuxiliaryCoordinate(const int target_index, const int additional_list_num, const int dim, const scratch_matrix_right_type *V=NULL) const
(OPTIONAL) Returns one component of the additional evaluation coordinates.
void setProblemData(view_type_1 neighbor_lists, view_type_2 source_coordinates, view_type_3 target_coordinates, view_type_4 epsilons)
Sets basic problem data (neighbor lists, source coordinates, and target coordinates) ...
constexpr SamplingFunctional PointSample
Available sampling functionals.
int _dimensions
dimension of the problem, set at class instantiation only
int calculateSamplingMultiplier(const ReconstructionSpace rs, const SamplingFunctional sro) const
Calculate sampling_multiplier.
host_managed_local_index_type getPolynomialCoefficientsDomainRangeSize() const
Returns (size of the basis used in instance&#39;s polynomial reconstruction) x (data input dimension) ...
decltype(_neighbor_lists)* getNeighborLists()
Get neighbor list accessor.
std::string _quadrature_type
quadrature rule type
Kokkos::View< TargetOperation * >::HostMirror _host_operations
vector containing target functionals to be applied for reconstruction problem (host) ...
static KOKKOS_INLINE_FUNCTION double Wab(const double r, const double h, const WeightingFunctionType &weighting_type, const int power)
Evaluates the weighting kernel.
bool _nontrivial_nullspace
whether or not operator to be inverted for GMLS problem has a nontrivial nullspace (requiring SVD) ...
struct SubviewND< T, T2, enable_if_t<(T::rank< 2)> >{T _data_in;T2 _data_original_view;bool _scalar_as_vector_if_needed;SubviewND(T data_in, T2 data_original_view, bool scalar_as_vector_if_needed){_data_in=data_in;_data_original_view=data_original_view;_scalar_as_vector_if_needed=scalar_as_vector_if_needed;}auto get1DView(const int column_num) -> decltype(Kokkos::subview(_data_in, Kokkos::ALL))
Creates 1D subviews of data from a 1D view, generally constructed with CreateNDSliceOnDeviceView.
int getTargetOperationLocalIndex(TargetOperation lro) const
Get the local index (internal) to GMLS for a particular TargetOperation Every TargetOperation has a g...
int getNumberOfQuadraturePoints() const
Number of quadrature points.
Tag for functor to assemble the P*sqrt(weights) matrix and construct sqrt(weights)*Identity for curva...
double getPreStencilWeight(SamplingFunctional sro, const int target_index, const int neighbor_index, bool for_target, const int output_component=0, const int input_component=0) const
Returns a stencil to transform data from its existing state into the input expected for some sampling...
KOKKOS_INLINE_FUNCTION void operator()(const AssembleStandardPsqrtW &, const member_type &teamMember) const
Functor to assemble the P*sqrt(weights) matrix and construct sqrt(weights)*Identity.
#define compadre_assert_debug(condition)
compadre_assert_debug is used for assertions that are checked in loops, as these significantly impact...
Kokkos::View< int * >::HostMirror _host_lro_total_offsets
index for where this operation begins the for _alpha coefficients (host)
KOKKOS_INLINE_FUNCTION XYZ getRelativeCoord(const int target_index, const int neighbor_list_num, const int dimension, const scratch_matrix_right_type *V=NULL) const
Returns the relative coordinate as a vector between the target site and the neighbor site...
void setWeightingPower(int wp)
Power for weighting kernel for GMLS problem.
double getAlpha2TensorTo1Tensor(TargetOperation lro, const int target_index, const int output_component, const int neighbor_index, const int input_component_axis_1, const int input_component_axis_2, const int additional_evaluation_site=0) const
Helper function for getting alphas for vector reconstruction from matrix data.
SamplingFunctional getPolynomialSamplingFunctional() const
Get the polynomial sampling functional specified at instantiation.
void setCurvatureWeightingType(const WeightingFunctionType wt)
Type for weighting kernel for curvature.
int local_index_type
ConstraintType _constraint_type
constraint type for GMLS problem
int _local_dimensions
dimension of the problem, set at class instantiation only. For manifolds, generally _global_dimension...
Kokkos::View< int * >::HostMirror _host_lro_output_tile_size
dimensions ^ rank of tensor of output for each target functional (host)
KOKKOS_INLINE_FUNCTION int getRHSSquareDim(DenseSolverType dense_solver_type, ConstraintType constraint_type, ReconstructionSpace reconstruction_space, const int dimension, const int M, const int N)
int _order_of_quadrature_points
order of exact polynomial integration for quadrature rule
int getOutputDimensionOfOperation(TargetOperation lro, bool ambient=false) const
Dimensions ^ output rank for target operation.
#define compadre_assert_release(condition)
compadre_assert_release is used for assertions that should always be checked, but generally are not e...
Tag for functor to determine if tangent directions need reordered, and to reorder them if needed...
host_managed_local_index_type getPolynomialCoefficientsMemorySize() const
Returns 2D array size in memory on which coefficients are stored.
Tag for functor to evaluate curvature targets and construct accurate tangent direction approximation ...
WeightingFunctionType getWeightingType() const
Type for weighting kernel for GMLS problem.
constexpr SamplingFunctional VectorPointSample
Point evaluations of the entire vector source function.
double getReferenceNormalDirection(const int target_index, const int component) const
Get component of tangent or normal directions for manifold problems.
KOKKOS_INLINE_FUNCTION int getNNeighbors(const int target_index) const
Returns number of neighbors for a particular target.
void setOrderOfQuadraturePoints(int order)
Number quadrature points to use.
double getTangentBundle(const int target_index, const int direction, const int component) const
Get component of tangent or normal directions for manifold problems.
static DenseSolverType parseSolverType(const std::string &dense_solver_type)
Parses a string to determine solver type.
KOKKOS_INLINE_FUNCTION void applyTargetsToCoefficients(const member_type &teamMember, scratch_vector_type t1, scratch_vector_type t2, scratch_matrix_right_type Q, scratch_vector_type w, scratch_matrix_right_type P_target_row, const int target_NP) const
Helper function for applying the evaluations from a target functional to the polynomial coefficients...
int getTargetOffsetIndexHost(const int lro_num, const int input_component, const int output_component, const int additional_evaluation_local_index=0) const
Handles offset from operation input/output + extra evaluation sites.
int _poly_order
order of basis for polynomial reconstruction
TargetOperation
Available target functionals.
void setSourceExtraData(decltype(_source_extra_data) extra_data)
(OPTIONAL) Sets extra data to be used by sampling functionals in certain instances.
void setTangentBundle(view_type tangent_directions)
(OPTIONAL) Sets orthonormal tangent directions for reconstruction on a manifold.
#define compadre_kernel_assert_debug(condition)
KOKKOS_INLINE_FUNCTION double convertLocalToGlobalCoordinate(const XYZ local_coord, const int dim, const scratch_matrix_right_type *V) const
Returns a component of the global coordinate after transformation from local to global under the orth...
ConstraintType
Constraint type.
static int getSamplingOutputIndex(const SamplingFunctional sf, const int output_component_axis_1, const int output_component_axis_2)
Helper function for finding alpha coefficients.