Compadre  1.5.9
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Compadre_SolutionSet.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Compadre: COMpatible PArticle Discretization and REmap Toolkit
4 //
5 // Copyright 2018 NTESS and the Compadre contributors.
6 // SPDX-License-Identifier: BSD-2-Clause
7 // *****************************************************************************
8 // @HEADER
9 #ifndef _COMPADRE_SOLUTIONSET_HPP_
10 #define _COMPADRE_SOLUTIONSET_HPP_
11 
12 #include "Compadre_Typedefs.hpp"
14 #include <Kokkos_Core.hpp>
15 
16 namespace Compadre {
17 
18 //! All vairables and functionality related to the layout and storage of GMLS
19 //! solutions (alpha values)
20 template <typename memory_space = device_memory_space>
21 struct SolutionSet {
22 
23  //! vector of user requested target operations
24  Kokkos::View<TargetOperation*, memory_space> _lro;
25 
26  //! vector containing a mapping from a target functionals enum value to the its place in the list
27  //! of target functionals to be applied
28  Kokkos::View<int*, memory_space> _lro_lookup;
29 
30  //! index for where this operation begins the for _alpha coefficients
31  Kokkos::View<int*, memory_space> _lro_total_offsets;
32 
33  //! dimensions ^ rank of tensor of output for each target functional
34  Kokkos::View<int*, memory_space> _lro_output_tile_size;
35 
36  //! dimensions ^ rank of tensor of output for each sampling functional
37  Kokkos::View<int*, memory_space> _lro_input_tile_size;
38 
39  //! tensor rank of target functional (device)
40  Kokkos::View<int*, memory_space> _lro_output_tensor_rank;
41 
42  //! tensor rank of sampling functional (device)
43  Kokkos::View<int*, memory_space> _lro_input_tensor_rank;
44 
45  //! generated alpha coefficients (device)
46  Kokkos::View<double*, layout_right, memory_space> _alphas;
47 
48  //! additional alpha coefficients due to constraints
50 
51  //! maximum number of evaluation sites for each target (includes target site)
53 
54  //! used for sizing P_target_row and the _alphas view
56 
57  //! whether internal alpha values are valid (set externally on a solve)
59 
60  //
61  // Redundant variables (already exist in GMLS class)
62  //
63 
64  //! Accessor to get neighbor list data, offset data, and number of neighbors per target
66 
67  //! generally the same as _polynomial_sampling_functional, but can differ if specified at
68  //! GMLS class instantiation
70 
71  //! dimension of the problem, set at class instantiation only
73 
74  //! dimension of the problem, set at class instantiation only. For manifolds, generally _global_dimensions-1
76 
77  //! problem type for GMLS problem, can also be set to STANDARD for normal or MANIFOLD for manifold problems
79 
80 /** @name Constructors
81  */
82 ///@{
83 
84  //! \brief Constructor for SolutionSet
85  SolutionSet(SamplingFunctional data_sampling_functional,
86  int dimensions,
87  int local_dimensions,
88  const ProblemType problem_type) :
93  _data_sampling_functional(data_sampling_functional),
94  _dimensions(dimensions),
95  _local_dimensions(local_dimensions),
96  _problem_type(problem_type) {}
97 
99 
100  //! \brief Copy constructor (can be used to move data from device to host or vice-versa)
101  template <typename other_memory_space>
104  _dimensions(other._dimensions),
107 
111  _contains_valid_alphas = false; // false until copyAlphas() is called
113 
114  // copy from other_memory_space to memory_space (if needed)
115  if (_lro.extent(0) != other._lro.extent(0)) {
116  Kokkos::resize(_lro, other._lro.extent(0));
117  }
118  if (_lro_lookup.extent(0) != other._lro_lookup.extent(0)) {
119  Kokkos::resize(_lro_lookup, other._lro_lookup.extent(0));
120  }
121  if (_lro_total_offsets.extent(0) != other._lro_total_offsets.extent(0)) {
122  Kokkos::resize(_lro_total_offsets, other._lro_total_offsets.extent(0));
123  }
124  if (_lro_output_tile_size.extent(0) != other._lro_output_tile_size.extent(0)) {
125  Kokkos::resize(_lro_output_tile_size, other._lro_output_tile_size.extent(0));
126  }
127  if (_lro_input_tile_size.extent(0) != other._lro_input_tile_size.extent(0)) {
128  Kokkos::resize(_lro_input_tile_size, other._lro_input_tile_size.extent(0));
129  }
130  if (_lro_output_tensor_rank.extent(0) != other._lro_output_tensor_rank.extent(0)) {
131  Kokkos::resize(_lro_output_tensor_rank, other._lro_output_tensor_rank.extent(0));
132  }
133  if (_lro_input_tensor_rank.extent(0) != other._lro_input_tensor_rank.extent(0)) {
134  Kokkos::resize(_lro_input_tensor_rank, other._lro_input_tensor_rank.extent(0));
135  }
136  Kokkos::deep_copy(_lro, other._lro);
137  Kokkos::deep_copy(_lro_lookup, other._lro_lookup);
138  Kokkos::deep_copy(_lro_total_offsets, other._lro_total_offsets);
139  Kokkos::deep_copy(_lro_output_tile_size, other._lro_output_tile_size);
140  Kokkos::deep_copy(_lro_input_tile_size, other._lro_input_tile_size);
141  Kokkos::deep_copy(_lro_output_tensor_rank, other._lro_output_tensor_rank);
142  Kokkos::deep_copy(_lro_input_tensor_rank, other._lro_input_tensor_rank);
143 
144  // don't copy _alphas (expensive)
145  // _alphas only copied using copyAlphas
146  }
147 
148 ///@}
149 
150 /** @name Public Accessors
151  */
152 ///@{
153 
154  // ON DEVICE
155 
156  //! Handles offset from operation input/output + extra evaluation sites
157  template<typename ms=memory_space, enable_if_t<!std::is_same<host_memory_space, ms>::value, int> = 0>
158  KOKKOS_INLINE_FUNCTION
159  int getTargetOffsetIndex(const int lro_num, const int input_component, const int output_component, const int evaluation_site_local_index = 0) const {
160  return ( _total_alpha_values*evaluation_site_local_index
161  + _lro_total_offsets[lro_num]
162  + input_component*_lro_output_tile_size[lro_num]
163  + output_component );
164  }
165 
166  //! Helper function for getting alphas for scalar reconstruction from scalar data
167  template<typename ms=memory_space, enable_if_t<!std::is_same<host_memory_space, ms>::value, int> = 0>
168  KOKKOS_INLINE_FUNCTION
169  double getAlpha0TensorTo0Tensor(TargetOperation lro, const int target_index, const int neighbor_index, const int evaluation_site_local_index = 0) const {
170  // e.g. Dirac Delta target of a scalar field
171  return getAlpha(lro, target_index, 0, 0, neighbor_index, 0, 0, evaluation_site_local_index);
172  }
173 
174  //! Helper function for getting alphas for vector reconstruction from scalar data
175  template<typename ms=memory_space, enable_if_t<!std::is_same<host_memory_space, ms>::value, int> = 0>
176  KOKKOS_INLINE_FUNCTION
177  double getAlpha0TensorTo1Tensor(TargetOperation lro, const int target_index, const int output_component, const int neighbor_index, const int evaluation_site_local_index = 0) const {
178  // e.g. gradient of a scalar field
179  return getAlpha(lro, target_index, output_component, 0, neighbor_index, 0, 0, evaluation_site_local_index);
180  }
181 
182  //! Helper function for getting alphas for matrix reconstruction from scalar data
183  template<typename ms=memory_space, enable_if_t<!std::is_same<host_memory_space, ms>::value, int> = 0>
184  KOKKOS_INLINE_FUNCTION
185  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 evaluation_site_local_index = 0) const {
186  return getAlpha(lro, target_index, output_component_axis_1, output_component_axis_2, neighbor_index, 0, 0, evaluation_site_local_index);
187  }
188 
189  //! Helper function for getting alphas for scalar reconstruction from vector data
190  template<typename ms=memory_space, enable_if_t<!std::is_same<host_memory_space, ms>::value, int> = 0>
191  KOKKOS_INLINE_FUNCTION
192  double getAlpha1TensorTo0Tensor(TargetOperation lro, const int target_index, const int neighbor_index, const int input_component, const int evaluation_site_local_index = 0) const {
193  // e.g. divergence of a vector field
194  return getAlpha(lro, target_index, 0, 0, neighbor_index, input_component, 0, evaluation_site_local_index);
195  }
196 
197  //! Helper function for getting alphas for vector reconstruction from vector data
198  template<typename ms=memory_space, enable_if_t<!std::is_same<host_memory_space, ms>::value, int> = 0>
199  KOKKOS_INLINE_FUNCTION
200  double getAlpha1TensorTo1Tensor(TargetOperation lro, const int target_index, const int output_component, const int neighbor_index, const int input_component, const int evaluation_site_local_index = 0) const {
201  // e.g. curl of a vector field
202  return getAlpha(lro, target_index, output_component, 0, neighbor_index, input_component, 0, evaluation_site_local_index);
203  }
204 
205  //! Helper function for getting alphas for matrix reconstruction from vector data
206  template<typename ms=memory_space, enable_if_t<!std::is_same<host_memory_space, ms>::value, int> = 0>
207  KOKKOS_INLINE_FUNCTION
208  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 evaluation_site_local_index = 0) const {
209  // e.g. gradient of a vector field
210  return getAlpha(lro, target_index, output_component_axis_1, output_component_axis_2, neighbor_index, input_component, 0, evaluation_site_local_index);
211  }
212 
213  //! Helper function for getting alphas for scalar reconstruction from matrix data
214  template<typename ms=memory_space, enable_if_t<!std::is_same<host_memory_space, ms>::value, int> = 0>
215  KOKKOS_INLINE_FUNCTION
216  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 evaluation_site_local_index = 0) const {
217  return getAlpha(lro, target_index, 0, 0, neighbor_index, input_component_axis_1, input_component_axis_2, evaluation_site_local_index);
218  }
219 
220  //! Helper function for getting alphas for vector reconstruction from matrix data
221  template<typename ms=memory_space, enable_if_t<!std::is_same<host_memory_space, ms>::value, int> = 0>
222  KOKKOS_INLINE_FUNCTION
223  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 evaluation_site_local_index = 0) const {
224  return getAlpha(lro, target_index, output_component, 0, neighbor_index, input_component_axis_1, input_component_axis_2, evaluation_site_local_index);
225  }
226 
227  //! Helper function for getting alphas for matrix reconstruction from matrix data
228  template<typename ms=memory_space, enable_if_t<!std::is_same<host_memory_space, ms>::value, int> = 0>
229  KOKKOS_INLINE_FUNCTION
230  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 evaluation_site_local_index = 0) const {
231  return getAlpha(lro, target_index, output_component_axis_1, output_component_axis_2, neighbor_index, input_component_axis_1, input_component_axis_2, evaluation_site_local_index);
232  }
233 
234  //! Gives index into alphas given two axes, which when incremented by the neighbor number transforms access into
235  //! alphas from a rank 1 view into a rank 3 view.
236  template<typename ms=memory_space, enable_if_t<!std::is_same<host_memory_space, ms>::value, int> = 0>
237  KOKKOS_INLINE_FUNCTION
238  global_index_type getAlphaIndex(const int target_index, const int alpha_column_offset) const {
239 
240  global_index_type total_neighbors_before_target = _neighbor_lists.getRowOffsetDevice(target_index);
241  int total_added_alphas_before_target = target_index*_added_alpha_size;
242 
243  int alphas_per_tile_per_target = _neighbor_lists.getNumberOfNeighborsDevice(target_index) + _added_alpha_size;
244 
245  return (total_neighbors_before_target+TO_GLOBAL(total_added_alphas_before_target))
247  + TO_GLOBAL(alpha_column_offset*alphas_per_tile_per_target);
248 
249  }
250 
251  //! Retrieves the offset for an operator based on input and output component, generic to row
252  //! (but still multiplied by the number of neighbors for each row and then needs a neighbor number added
253  //! to this returned value to be meaningful)
254  template<typename ms=memory_space, enable_if_t<!std::is_same<host_memory_space, ms>::value, int> = 0>
255  KOKKOS_INLINE_FUNCTION
256  int getAlphaColumnOffset(TargetOperation lro, const int output_component_axis_1,
257  const int output_component_axis_2, const int input_component_axis_1,
258  const int input_component_axis_2, const int evaluation_site_local_index = 0) const {
259 
260  const int lro_number = _lro_lookup[(int)lro];
261  compadre_kernel_assert_debug((lro_number >= 0) && "getAlphaColumnOffset called for a TargetOperation that was not registered.");
262 
263  // the target functional input indexing is sized based on the output rank of the sampling
264  // functional used, which can not be inferred unless a specification of target functional,
265  // reconstruction space, and sampling functional are all known (as was the case at the
266  // construction of this class)
267  const int input_index = getSamplingOutputIndex(_data_sampling_functional, input_component_axis_1, input_component_axis_2);
268  const int output_index = getTargetOutputIndex((int)lro, output_component_axis_1, output_component_axis_2, _dimensions);
269 
270  return getTargetOffsetIndex(lro_number, input_index, output_index, evaluation_site_local_index);
271  }
272 
273  //! Underlying function all interface helper functions call to retrieve alpha values
274  template<typename ms=memory_space, enable_if_t<!std::is_same<host_memory_space, ms>::value, int> = 0>
275  KOKKOS_INLINE_FUNCTION
276  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 evaluation_site_local_index = 0) const {
277  // lro - the operator from TargetOperations
278  // target_index - the # for the target site where information is required
279  // neighbor_index - the # for the neighbor of the target
280  //
281  // This code support up to rank 2 tensors for inputs and outputs
282  //
283  // scalar reconstruction from scalar data: rank 0 to rank 0
284  // provides 1 piece of information for each neighbor
285  // scalar reconstruction from vector data (e.g. divergence): rank 1 to rank 0
286  // provides 'd' pieces of information for each neighbor
287  // vector reconstruction from scalar data (e.g. gradient): rank 0 to rank 1
288  // provides 'd' piece of information for each neighbor
289  // vector reconstruction from vector data (e.g. curl): rank 1 to rank 1
290  // provides 'd'x'd' pieces of information for each neighbor
291  //
292  // This function would more reasonably be called from one of the getAlphaNTensorFromNTensor
293  // which is much easier to understand with respect to indexing and only requesting indices
294  // that are relavent to the operator in question.
295  //
296 
298  "getAlpha called on SolutionSet with _contains_valid_alphas=false");
299 
300  const int alpha_column_offset = this->getAlphaColumnOffset( lro, output_component_axis_1,
301  output_component_axis_2, input_component_axis_1, input_component_axis_2, evaluation_site_local_index);
302 
303  auto alphas_index = this->getAlphaIndex(target_index, alpha_column_offset);
304  return _alphas(alphas_index + neighbor_index);
305  }
306 
307  //! Get the local index (internal) to GMLS for a particular TargetOperation
308  //! Every TargetOperation has a global index which can be readily found in Compadre::TargetOperation
309  //! but this function returns the index used inside of the GMLS class
310  template<typename ms=memory_space, enable_if_t<!std::is_same<host_memory_space, ms>::value, int> = 0>
311  KOKKOS_INLINE_FUNCTION
313  return _lro_lookup[(int)lro];
314  }
315 
316  //! Handles offset from operation input/output + extra evaluation sites
317  template<typename ms=memory_space, enable_if_t<std::is_same<host_memory_space, ms>::value, int> = 0>
318  int getTargetOffsetIndex(const int lro_num, const int input_component, const int output_component, const int evaluation_site_local_index = 0) const {
319  return ( _total_alpha_values*evaluation_site_local_index
320  + _lro_total_offsets[lro_num]
321  + input_component*_lro_output_tile_size[lro_num]
322  + output_component );
323  }
324 
325  //! Helper function for getting alphas for scalar reconstruction from scalar data
326  template<typename ms=memory_space, enable_if_t<std::is_same<host_memory_space, ms>::value, int> = 0>
327  double getAlpha0TensorTo0Tensor(TargetOperation lro, const int target_index, const int neighbor_index, const int evaluation_site_local_index = 0) const {
328  // e.g. Dirac Delta target of a scalar field
329  return getAlpha(lro, target_index, 0, 0, neighbor_index, 0, 0, evaluation_site_local_index);
330  }
331 
332  //! Helper function for getting alphas for vector reconstruction from scalar data
333  template<typename ms=memory_space, enable_if_t<std::is_same<host_memory_space, ms>::value, int> = 0>
334  double getAlpha0TensorTo1Tensor(TargetOperation lro, const int target_index, const int output_component, const int neighbor_index, const int evaluation_site_local_index = 0) const {
335  // e.g. gradient of a scalar field
336  return getAlpha(lro, target_index, output_component, 0, neighbor_index, 0, 0, evaluation_site_local_index);
337  }
338 
339  //! Helper function for getting alphas for matrix reconstruction from scalar data
340  template<typename ms=memory_space, enable_if_t<std::is_same<host_memory_space, ms>::value, int> = 0>
341  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 evaluation_site_local_index = 0) const {
342  return getAlpha(lro, target_index, output_component_axis_1, output_component_axis_2, neighbor_index, 0, 0, evaluation_site_local_index);
343  }
344 
345  //! Helper function for getting alphas for scalar reconstruction from vector data
346  template<typename ms=memory_space, enable_if_t<std::is_same<host_memory_space, ms>::value, int> = 0>
347  double getAlpha1TensorTo0Tensor(TargetOperation lro, const int target_index, const int neighbor_index, const int input_component, const int evaluation_site_local_index = 0) const {
348  // e.g. divergence of a vector field
349  return getAlpha(lro, target_index, 0, 0, neighbor_index, input_component, 0, evaluation_site_local_index);
350  }
351 
352  //! Helper function for getting alphas for vector reconstruction from vector data
353  template<typename ms=memory_space, enable_if_t<std::is_same<host_memory_space, ms>::value, int> = 0>
354  double getAlpha1TensorTo1Tensor(TargetOperation lro, const int target_index, const int output_component, const int neighbor_index, const int input_component, const int evaluation_site_local_index = 0) const {
355  // e.g. curl of a vector field
356  return getAlpha(lro, target_index, output_component, 0, neighbor_index, input_component, 0, evaluation_site_local_index);
357  }
358 
359  //! Helper function for getting alphas for matrix reconstruction from vector data
360  template<typename ms=memory_space, enable_if_t<std::is_same<host_memory_space, ms>::value, int> = 0>
361  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 evaluation_site_local_index = 0) const {
362  // e.g. gradient of a vector field
363  return getAlpha(lro, target_index, output_component_axis_1, output_component_axis_2, neighbor_index, input_component, 0, evaluation_site_local_index);
364  }
365 
366  //! Helper function for getting alphas for scalar reconstruction from matrix data
367  template<typename ms=memory_space, enable_if_t<std::is_same<host_memory_space, ms>::value, int> = 0>
368  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 evaluation_site_local_index = 0) const {
369  return getAlpha(lro, target_index, 0, 0, neighbor_index, input_component_axis_1, input_component_axis_2, evaluation_site_local_index);
370  }
371 
372  //! Helper function for getting alphas for vector reconstruction from matrix data
373  template<typename ms=memory_space, enable_if_t<std::is_same<host_memory_space, ms>::value, int> = 0>
374  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 evaluation_site_local_index = 0) const {
375  return getAlpha(lro, target_index, output_component, 0, neighbor_index, input_component_axis_1, input_component_axis_2, evaluation_site_local_index);
376  }
377 
378  //! Helper function for getting alphas for matrix reconstruction from matrix data
379  template<typename ms=memory_space, enable_if_t<std::is_same<host_memory_space, ms>::value, int> = 0>
380  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 evaluation_site_local_index = 0) const {
381  return getAlpha(lro, target_index, output_component_axis_1, output_component_axis_2, neighbor_index, input_component_axis_1, input_component_axis_2, evaluation_site_local_index);
382  }
383 
384  //! Gives index into alphas given two axes, which when incremented by the neighbor number transforms access into
385  //! alphas from a rank 1 view into a rank 3 view.
386  template<typename ms=memory_space, enable_if_t<std::is_same<host_memory_space, ms>::value, int> = 0>
387  global_index_type getAlphaIndex(const int target_index, const int alpha_column_offset) const {
388 
389  global_index_type total_neighbors_before_target = _neighbor_lists.getRowOffsetHost(target_index);
390  int total_added_alphas_before_target = target_index*_added_alpha_size;
391 
392  int alphas_per_tile_per_target = _neighbor_lists.getNumberOfNeighborsHost(target_index) + _added_alpha_size;
393 
394  return (total_neighbors_before_target+TO_GLOBAL(total_added_alphas_before_target))
396  + TO_GLOBAL(alpha_column_offset*alphas_per_tile_per_target);
397 
398  }
399 
400  //! Retrieves the offset for an operator based on input and output component, generic to row
401  //! (but still multiplied by the number of neighbors for each row and then needs a neighbor number added
402  //! to this returned value to be meaningful)
403  template<typename ms=memory_space, enable_if_t<std::is_same<host_memory_space, ms>::value, int> = 0>
404  int getAlphaColumnOffset(TargetOperation lro, const int output_component_axis_1,
405  const int output_component_axis_2, const int input_component_axis_1,
406  const int input_component_axis_2, const int evaluation_site_local_index = 0) const {
407 
408  const int lro_number = _lro_lookup[(int)lro];
409  compadre_kernel_assert_debug((lro_number >= 0) && "getAlphaColumnOffset called for a TargetOperation that was not registered.");
410 
411  // the target functional input indexing is sized based on the output rank of the sampling
412  // functional used, which can not be inferred unless a specification of target functional,
413  // reconstruction space, and sampling functional are all known (as was the case at the
414  // construction of this class)
415  const int input_index = getSamplingOutputIndex(_data_sampling_functional, input_component_axis_1, input_component_axis_2);
416  const int output_index = getTargetOutputIndex((int)lro, output_component_axis_1, output_component_axis_2, _dimensions);
417 
418  return getTargetOffsetIndex(lro_number, input_index, output_index, evaluation_site_local_index);
419  }
420 
421  //! Underlying function all interface helper functions call to retrieve alpha values
422  template<typename ms=memory_space, enable_if_t<std::is_same<host_memory_space, ms>::value, int> = 0>
423  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 evaluation_site_local_index = 0) const {
424  // lro - the operator from TargetOperations
425  // target_index - the # for the target site where information is required
426  // neighbor_index - the # for the neighbor of the target
427  //
428  // This code support up to rank 2 tensors for inputs and outputs
429  //
430  // scalar reconstruction from scalar data: rank 0 to rank 0
431  // provides 1 piece of information for each neighbor
432  // scalar reconstruction from vector data (e.g. divergence): rank 1 to rank 0
433  // provides 'd' pieces of information for each neighbor
434  // vector reconstruction from scalar data (e.g. gradient): rank 0 to rank 1
435  // provides 'd' piece of information for each neighbor
436  // vector reconstruction from vector data (e.g. curl): rank 1 to rank 1
437  // provides 'd'x'd' pieces of information for each neighbor
438  //
439  // This function would more reasonably be called from one of the getAlphaNTensorFromNTensor
440  // which is much easier to understand with respect to indexing and only requesting indices
441  // that are relavent to the operator in question.
442  //
443 
445  "getAlpha called on SolutionSet with _contains_valid_alphas=false");
446 
447  const int alpha_column_offset = this->getAlphaColumnOffset( lro, output_component_axis_1,
448  output_component_axis_2, input_component_axis_1, input_component_axis_2, evaluation_site_local_index);
449 
450  auto alphas_index = this->getAlphaIndex(target_index, alpha_column_offset);
451  return _alphas(alphas_index + neighbor_index);
452  }
453 
454  //! Get the local index (internal) to GMLS for a particular TargetOperation
455  //! Every TargetOperation has a global index which can be readily found in Compadre::TargetOperation
456  //! but this function returns the index used inside of the GMLS class
457  template<typename ms=memory_space, enable_if_t<std::is_same<host_memory_space, ms>::value, int> = 0>
459  return _lro_lookup[(int)lro];
460  }
461 
462 
463 ///@}
464 
465 /** @name Public Modifiers (can only call from host)
466  */
467 ///@{
468 
469  //! Copies alphas between two instances of SolutionSet
470  //! Copying of alphas is intentionally omitted in copy constructor
471  template <typename other_memory_space>
473  if ((void*)this != (void*)&other) {
474  if (_alphas.extent(0) != other._alphas.extent(0)) {
475  Kokkos::resize(_alphas, other._alphas.extent(0));
476  }
477  Kokkos::deep_copy(_alphas, other._alphas);
479  }
480  }
481 
482 
483  //! Empties the vector of target functionals to apply to the reconstruction
484  template<typename ms=memory_space, enable_if_t<std::is_same<host_memory_space, ms>::value, int> = 0>
485  void clearTargets() {
486  _lro = decltype(_lro)();
487  for (int i=0; i<TargetOperation::COUNT; ++i) {
488  _lro_lookup[i] = -1;
489  }
490  }
491 
492  //! Adds a target to the vector of target functional to be applied to the reconstruction
493  template<typename ms=memory_space, enable_if_t<std::is_same<host_memory_space, ms>::value, int> = 0>
495  std::vector<TargetOperation> temporary_lro_vector(1, lro);
496  this->addTargets(temporary_lro_vector);
497  }
498 
499  //! Adds a vector of target functionals to the vector of target functionals already to be applied to the reconstruction
500  template<typename ms=memory_space, enable_if_t<std::is_same<host_memory_space, ms>::value, int> = 0>
501  void addTargets(std::vector<TargetOperation> lro) {
502 
503  std::vector<TargetOperation> unique_new_lro;
504 
505  auto host_lro_lookup = create_mirror_view(_lro_lookup);
506  if (_lro_lookup.extent(0) == 0) {
508  host_lro_lookup = create_mirror_view(_lro_lookup);
509  Kokkos::deep_copy(host_lro_lookup, -1);
510  } else {
511  Kokkos::deep_copy(host_lro_lookup, _lro_lookup);
512  }
513 
514  // loop over requested targets
515  for (size_t i=0; i<lro.size(); ++i) {
516 
517  bool operation_found = false;
518  // loop over existing targets registered
519  for (size_t j=0; j<_lro.size(); ++j) {
520 
521  // if found
522  if (_lro(j)==lro[i]) {
523 
524  operation_found = true;
525 
526  // the operation should now point to where the operation is stored
527  host_lro_lookup[(int)lro[i]] = j;
528 
529  break;
530 
531  }
532  }
533 
534  if (!operation_found) {
535  host_lro_lookup[(int)lro[i]] = _lro.size() + unique_new_lro.size();
536  unique_new_lro.push_back(lro[i]);
537  }
538  }
539 
540  // move unique_new_lro into _lro
541  auto new_lro = decltype(_lro)("LRO", _lro.size() + unique_new_lro.size());
542  for (size_t i=0; i<_lro.size(); ++i) {
543  new_lro(i) = _lro(i);
544  }
545  for (size_t i=0; i<unique_new_lro.size(); ++i) {
546  new_lro(i+_lro.size()) = unique_new_lro[i];
547  }
548  _lro = new_lro;
549 
550  _lro_total_offsets = decltype(_lro_total_offsets)("total offsets for alphas", _lro.size());
551  _lro_output_tile_size = decltype(_lro_output_tile_size)("output tile size for each operation", _lro.size());
552  _lro_input_tile_size = decltype(_lro_input_tile_size)("output tile size for each operation", _lro.size());
553  _lro_output_tensor_rank = decltype(_lro_output_tensor_rank)("output tensor rank", _lro.size());
554  _lro_input_tensor_rank = decltype(_lro_input_tensor_rank)("input tensor rank", _lro.size());
555 
556  auto host_lro_total_offsets = create_mirror_view(_lro_total_offsets);
557  auto host_lro_output_tile_size = create_mirror_view(_lro_output_tile_size);
558  auto host_lro_input_tile_size = create_mirror_view(_lro_input_tile_size);
559  auto host_lro_output_tensor_rank = create_mirror_view(_lro_output_tensor_rank);
560  auto host_lro_input_tensor_rank = create_mirror_view(_lro_input_tensor_rank);
561 
562  int total_offset = 0; // need total offset
563 
564  for (size_t i=0; i<_lro.size(); ++i) {
565  host_lro_total_offsets(i) = total_offset;
566 
567  // allows for a tile of the product of dimension^input_tensor_rank * dimension^output_tensor_rank * the number of neighbors
568  int output_tile_size = getOutputDimensionOfOperation(_lro(i), _local_dimensions);
569 
570  // the target functional input indexing is sized based on the output rank of the sampling
571  // functional used
573  host_lro_output_tile_size(i) = output_tile_size;
574  host_lro_input_tile_size(i) = input_tile_size;
575 
576  total_offset += input_tile_size * output_tile_size;
577 
578  // the target functional output rank is based on the output rank of the sampling
579  // functional used
580  host_lro_input_tensor_rank(i) = _data_sampling_functional.output_rank;
581  host_lro_output_tensor_rank(i) = getTargetOutputTensorRank((int)_lro(i));
582  }
583 
584  _total_alpha_values = total_offset;
585 
587  // if on a manifold, the total alphas values must be large enough to hold the gradient
588  // of the geometry reconstruction
591  }
592 
593  Kokkos::deep_copy(_lro_lookup, host_lro_lookup);
594  Kokkos::deep_copy(_lro_total_offsets, host_lro_total_offsets);
595  Kokkos::deep_copy(_lro_output_tile_size, host_lro_output_tile_size);
596  Kokkos::deep_copy(_lro_input_tile_size, host_lro_input_tile_size);
597  Kokkos::deep_copy(_lro_output_tensor_rank, host_lro_output_tensor_rank);
598  Kokkos::deep_copy(_lro_input_tensor_rank, host_lro_input_tensor_rank);
599  }
600 
601  //! Get a view (device) of all alphas
604  "getAlpha called on SolutionSet with _contains_valid_alphas=false");
605  return _alphas;
606  }
607 
608 ///@}
609 
610 }; // SolutionSet
611 
612 } // Compadre namespace
613 
614 #endif
615 
KOKKOS_INLINE_FUNCTION 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 evaluation_site_local_index=0) const
Helper function for getting alphas for matrix reconstruction from matrix data.
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 evaluation_site_local_index=0) const
Helper function for getting alphas for matrix reconstruction from vector data.
Kokkos::View< int *, memory_space > _lro_output_tile_size
dimensions ^ rank of tensor of output for each target functional
KOKKOS_INLINE_FUNCTION int getOutputDimensionOfSampling(SamplingFunctional sro, const int local_dimensions)
Dimensions ^ output rank for sampling operation (always in local chart if on a manifold, never ambient space)
int getNumberOfNeighborsHost(int target_index) const
Get number of neighbors for a given target (host)
std::size_t global_index_type
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 evaluation_site_local_index=0) const
Helper function for getting alphas for vector reconstruction from matrix data.
KOKKOS_INLINE_FUNCTION int getTargetOperationLocalIndex(TargetOperation lro) const
Get the local index (internal) to GMLS for a particular TargetOperation Every TargetOperation has a g...
int getTargetOperationLocalIndex(TargetOperation lro) const
Get the local index (internal) to GMLS for a particular TargetOperation Every TargetOperation has a g...
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 evaluation_site_local_index=0) const
Helper function for getting alphas for matrix reconstruction from matrix data.
int output_rank
Rank of sampling functional output for each SamplingFunctional.
KOKKOS_INLINE_FUNCTION int getNumberOfNeighborsDevice(int target_index) const
Get number of neighbors for a given target (device)
global_index_type getRowOffsetHost(int target_index) const
Get offset into compressed row neighbor lists (host)
double getAlpha0TensorTo0Tensor(TargetOperation lro, const int target_index, const int neighbor_index, const int evaluation_site_local_index=0) const
Helper function for getting alphas for scalar reconstruction from scalar data.
KOKKOS_INLINE_FUNCTION double getAlpha0TensorTo0Tensor(TargetOperation lro, const int target_index, const int neighbor_index, const int evaluation_site_local_index=0) const
Helper function for getting alphas for scalar reconstruction from scalar data.
All vairables and functionality related to the layout and storage of GMLS solutions (alpha values) ...
void addTargets(TargetOperation lro)
Adds a target to the vector of target functional to be applied to the reconstruction.
Kokkos::View< TargetOperation *, memory_space > _lro
vector of user requested target operations
KOKKOS_INLINE_FUNCTION global_index_type getAlphaIndex(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...
SamplingFunctional _data_sampling_functional
generally the same as _polynomial_sampling_functional, but can differ if specified at GMLS class inst...
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 evaluation_site_local_index=0) const
Underlying function all interface helper functions call to retrieve alpha values. ...
void clearTargets()
Empties the vector of target functionals to apply to the reconstruction.
KOKKOS_INLINE_FUNCTION 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 evaluation_site_local_index=0) const
Underlying function all interface helper functions call to retrieve alpha values. ...
bool _contains_valid_alphas
whether internal alpha values are valid (set externally on a solve)
KOKKOS_INLINE_FUNCTION 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 evaluation_site_local_index=0) const
Helper function for getting alphas for vector reconstruction from matrix data.
Kokkos::View< int *, memory_space > _lro_input_tensor_rank
tensor rank of sampling functional (device)
Should be the total count of all available target functionals.
Kokkos::View< double *, layout_right, memory_space > _alphas
generated alpha coefficients (device)
KOKKOS_INLINE_FUNCTION 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.
TargetOperation
Available target functionals.
Solve GMLS problem on a manifold (will use QR or SVD to solve the resultant GMLS problem dependent on...
#define TO_GLOBAL(variable)
KOKKOS_INLINE_FUNCTION int pown(int n, unsigned p)
n^p (n^0 returns 1, regardless of n)
Kokkos::View< int *, memory_space > _lro_output_tensor_rank
tensor rank of target functional (device)
Kokkos::View< int *, memory_space > _lro_total_offsets
index for where this operation begins the for _alpha coefficients
KOKKOS_INLINE_FUNCTION int getSamplingOutputIndex(const SamplingFunctional sf, const int output_component_axis_1, const int output_component_axis_2)
Helper function for finding alpha coefficients.
void copyAlphas(SolutionSet< other_memory_space > &other)
Copies alphas between two instances of SolutionSet Copying of alphas is intentionally omitted in copy...
KOKKOS_INLINE_FUNCTION 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 evaluation_site_local_index=0) const
Retrieves the offset for an operator based on input and output component, generic to row (but still m...
KOKKOS_INLINE_FUNCTION 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 evaluation_site_local_index=0) const
Helper function for getting alphas for scalar reconstruction from matrix data.
int _added_alpha_size
additional alpha coefficients due to constraints
int getTargetOffsetIndex(const int lro_num, const int input_component, const int output_component, const int evaluation_site_local_index=0) const
Handles offset from operation input/output + extra evaluation sites.
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 evaluation_site_local_index=0) const
Retrieves the offset for an operator based on input and output component, generic to row (but still m...
KOKKOS_INLINE_FUNCTION double getAlpha1TensorTo0Tensor(TargetOperation lro, const int target_index, const int neighbor_index, const int input_component, const int evaluation_site_local_index=0) const
Helper function for getting alphas for scalar reconstruction from vector data.
void addTargets(std::vector< TargetOperation > lro)
Adds a vector of target functionals to the vector of target functionals already to be applied to the ...
ProblemType
Problem type, that optionally can handle manifolds.
KOKKOS_INLINE_FUNCTION 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 evaluation_site_local_index=0) const
Helper function for getting alphas for matrix reconstruction from scalar data.
double getAlpha1TensorTo1Tensor(TargetOperation lro, const int target_index, const int output_component, const int neighbor_index, const int input_component, const int evaluation_site_local_index=0) const
Helper function for getting alphas for vector reconstruction from vector data.
global_index_type getAlphaIndex(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...
Kokkos::View< int *, memory_space > _lro_lookup
vector containing a mapping from a target functionals enum value to the its place in the list of targ...
SolutionSet(SamplingFunctional data_sampling_functional, int dimensions, int local_dimensions, const ProblemType problem_type)
Constructor for SolutionSet.
int _dimensions
dimension of the problem, set at class instantiation only
double getAlpha0TensorTo1Tensor(TargetOperation lro, const int target_index, const int output_component, const int neighbor_index, const int evaluation_site_local_index=0) const
Helper function for getting alphas for vector reconstruction from scalar data.
KOKKOS_INLINE_FUNCTION int getTargetOutputTensorRank(const int &index)
Rank of target functional output for each TargetOperation Rank of target functional input for each Ta...
SolutionSet(const SolutionSet< other_memory_space > &other)
Copy constructor (can be used to move data from device to host or vice-versa)
KOKKOS_INLINE_FUNCTION 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 evaluation_site_local_index=0) const
Helper function for getting alphas for matrix reconstruction from vector data.
int _local_dimensions
dimension of the problem, set at class instantiation only. For manifolds, generally _global_dimension...
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 evaluation_site_local_index=0) const
Helper function for getting alphas for matrix reconstruction from scalar data.
constexpr SamplingFunctional PointSample
Available sampling functionals.
decltype(_alphas) getAlphas() const
Get a view (device) of all alphas.
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.
KOKKOS_INLINE_FUNCTION int getTargetOffsetIndex(const int lro_num, const int input_component, const int output_component, const int evaluation_site_local_index=0) const
Handles offset from operation input/output + extra evaluation sites.
#define compadre_assert_debug(condition)
compadre_assert_debug is used for assertions that are checked in loops, as these significantly impact...
KOKKOS_INLINE_FUNCTION double getAlpha1TensorTo1Tensor(TargetOperation lro, const int target_index, const int output_component, const int neighbor_index, const int input_component, const int evaluation_site_local_index=0) const
Helper function for getting alphas for vector reconstruction from vector data.
Kokkos::View< int *, memory_space > _lro_input_tile_size
dimensions ^ rank of tensor of output for each sampling functional
KOKKOS_INLINE_FUNCTION double getAlpha0TensorTo1Tensor(TargetOperation lro, const int target_index, const int output_component, const int neighbor_index, const int evaluation_site_local_index=0) const
Helper function for getting alphas for vector reconstruction from scalar data.
NeighborLists assists in accessing entries of compressed row neighborhood lists.
double getAlpha1TensorTo0Tensor(TargetOperation lro, const int target_index, const int neighbor_index, const int input_component, const int evaluation_site_local_index=0) const
Helper function for getting alphas for scalar reconstruction from vector data.
int _max_evaluation_sites_per_target
maximum number of evaluation sites for each target (includes target site)
KOKKOS_INLINE_FUNCTION global_index_type getRowOffsetDevice(int target_index) const
Get offset into compressed row neighbor lists (device)
KOKKOS_INLINE_FUNCTION int getOutputDimensionOfOperation(TargetOperation lro, const int local_dimensions)
Dimensions ^ output rank for target operation.
NeighborLists< Kokkos::View< int * > > _neighbor_lists
Accessor to get neighbor list data, offset data, and number of neighbors per target.
int _total_alpha_values
used for sizing P_target_row and the _alphas view
ProblemType _problem_type
problem type for GMLS problem, can also be set to STANDARD for normal or MANIFOLD for manifold proble...
#define compadre_kernel_assert_debug(condition)
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 evaluation_site_local_index=0) const
Helper function for getting alphas for scalar reconstruction from matrix data.