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