Compadre  1.6.0
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 
297  compadre_kernel_assert_debug(this->_contains_valid_alphas &&
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 
444  compadre_assert_debug(this->_contains_valid_alphas &&
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);
478  this->_contains_valid_alphas = other._contains_valid_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) {
507  _lro_lookup = decltype(_lro_lookup)("LRO Lookup", TargetOperation::COUNT);
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
602  decltype(_alphas) getAlphas() const {
603  compadre_assert_debug(this->_contains_valid_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 
#define compadre_kernel_assert_debug(condition)
std::size_t global_index_type
#define compadre_assert_debug(condition)
compadre_assert_debug is used for assertions that are checked in loops, as these significantly impact...
#define TO_GLOBAL(variable)
KOKKOS_INLINE_FUNCTION int pown(int n, unsigned p)
n^p (n^0 returns 1, regardless of n)
KOKKOS_INLINE_FUNCTION int getTargetOutputTensorRank(const int &index)
Rank of target functional output for each TargetOperation Rank of target functional input for each Ta...
constexpr SamplingFunctional PointSample
Available sampling functionals.
ProblemType
Problem type, that optionally can handle manifolds.
@ MANIFOLD
Solve GMLS problem on a manifold (will use QR or SVD to solve the resultant GMLS problem dependent on...
KOKKOS_INLINE_FUNCTION int getOutputDimensionOfOperation(TargetOperation lro, const int local_dimensions)
Dimensions ^ output rank for target operation.
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.
@ COUNT
Should be the total count of all available target functionals.
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,...
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.
NeighborLists assists in accessing entries of compressed row neighborhood lists.
global_index_type getRowOffsetHost(int target_index) const
Get offset into compressed row neighbor lists (host)
KOKKOS_INLINE_FUNCTION global_index_type getRowOffsetDevice(int target_index) const
Get offset into compressed row neighbor lists (device)
KOKKOS_INLINE_FUNCTION int getNumberOfNeighborsDevice(int target_index) const
Get number of neighbors for a given target (device)
int getNumberOfNeighborsHost(int target_index) const
Get number of neighbors for a given target (host)
int output_rank
Rank of sampling functional output for each SamplingFunctional.
All vairables and functionality related to the layout and storage of GMLS solutions (alpha values)
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 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 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.
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.
void addTargets(TargetOperation lro)
Adds a target to the vector of target functional to be applied to the reconstruction.
Kokkos::View< int *, memory_space > _lro_output_tile_size
dimensions ^ rank of tensor of output for each target functional
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_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...
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.
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_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.
SolutionSet(SamplingFunctional data_sampling_functional, int dimensions, int local_dimensions, const ProblemType problem_type)
Constructor for SolutionSet.
Kokkos::View< int *, memory_space > _lro_input_tensor_rank
tensor rank of sampling functional (device)
void clearTargets()
Empties the vector of target functionals to apply to the reconstruction.
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.
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::View< int *, memory_space > _lro_input_tile_size
dimensions ^ rank of tensor of output for each sampling functional
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_INLINE_FUNCTION int getTargetOperationLocalIndex(TargetOperation lro) const
Get the local index (internal) to GMLS for a particular TargetOperation Every TargetOperation has a g...
Kokkos::View< TargetOperation *, memory_space > _lro
vector of user requested target operations
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.
int _dimensions
dimension of the problem, set at class instantiation only
int getTargetOperationLocalIndex(TargetOperation lro) const
Get the local index (internal) to GMLS for a particular TargetOperation Every TargetOperation has a g...
NeighborLists< Kokkos::View< int * > > _neighbor_lists
Accessor to get neighbor list data, offset data, and number of neighbors per target.
int _max_evaluation_sites_per_target
maximum number of evaluation sites for each target (includes target site)
SamplingFunctional _data_sampling_functional
generally the same as _polynomial_sampling_functional, but can differ if specified at GMLS class inst...
Kokkos::View< double *, layout_right, memory_space > _alphas
generated alpha coefficients (device)
int _added_alpha_size
additional alpha coefficients due to constraints
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::View< int *, memory_space > _lro_output_tensor_rank
tensor rank of target functional (device)
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.
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.
decltype(_alphas) getAlphas() const
Get a view (device) of all alphas.
bool _contains_valid_alphas
whether internal alpha values are valid (set externally on a solve)
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::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...
void addTargets(std::vector< TargetOperation > lro)
Adds a vector of target functionals to the vector of target functionals already to be applied to the ...
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.
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.
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.
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 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_total_offsets
index for where this operation begins the for _alpha coefficients
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...
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.
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.
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...
SolutionSet(const SolutionSet< other_memory_space > &other)
Copy constructor (can be used to move data from device to host or vice-versa)
int _local_dimensions
dimension of the problem, set at class instantiation only. For manifolds, generally _global_dimension...
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 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.