Line data Source code
1 : /********************************************************************/ 2 : /* SOFTWARE COPYRIGHT NOTIFICATION */ 3 : /* Cardinal */ 4 : /* */ 5 : /* (c) 2021 UChicago Argonne, LLC */ 6 : /* ALL RIGHTS RESERVED */ 7 : /* */ 8 : /* Prepared by UChicago Argonne, LLC */ 9 : /* Under Contract No. DE-AC02-06CH11357 */ 10 : /* With the U. S. Department of Energy */ 11 : /* */ 12 : /* Prepared by Battelle Energy Alliance, LLC */ 13 : /* Under Contract No. DE-AC07-05ID14517 */ 14 : /* With the U. S. Department of Energy */ 15 : /* */ 16 : /* See LICENSE for full restrictions */ 17 : /********************************************************************/ 18 : 19 : #pragma once 20 : 21 : #include "GeneralUserObject.h" 22 : #include "NekFieldInterface.h" 23 : #include "NekBase.h" 24 : #include "SpatialBinUserObject.h" 25 : 26 : /** 27 : * Class that performs various postprocessing operations on the 28 : * NekRS solution with a spatial binning formed as the product 29 : * of an arbitrary number of combined single-set bins. 30 : */ 31 : class NekSpatialBinUserObject : public GeneralUserObject, public NekBase, public NekFieldInterface 32 : { 33 : public: 34 : static InputParameters validParams(); 35 : 36 : NekSpatialBinUserObject(const InputParameters & parameters); 37 : 38 : virtual ~NekSpatialBinUserObject(); 39 : 40 1964 : virtual void initialize() {} 41 1964 : virtual void finalize() {} 42 : virtual void execute() override; 43 : 44 : /** 45 : * Execute the user object; separating this call from execute() allows 46 : * all derived classes to leverage this base class's 'interval' parameter 47 : * to decide when to call the user object 48 : */ 49 : virtual void executeUserObject() = 0; 50 : 51 : virtual Real spatialValue(const Point & p) const override final; 52 : 53 : /** 54 : * When using 'field = velocity_component', get the spatial value for a 55 : * particular component 56 : * @param[in] p point 57 : * @param[in] component component 58 : * @return value along direction of component 59 : */ 60 : virtual Real spatialValue(const Point & p, const unsigned int & component) const = 0; 61 : 62 : virtual const unsigned int bin(const Point & p) const; 63 : 64 : virtual const unsigned int num_bins() const; 65 : 66 80 : virtual const std::vector<Point> spatialPoints() const override { return _points; } 67 : 68 : /// Compute the volume of each bin and check for zero contributions 69 : virtual void computeBinVolumes() final; 70 : 71 : /// Get the volume of each bin, used for normalizing in derived classes 72 : virtual void getBinVolumes() = 0; 73 : 74 : /** 75 : * Get the individual bin indices given a total combined bin 76 : * @param[in] total_bin_index total combined bin index 77 : * @return indices into each of the individual bin distributions 78 : */ 79 : const std::vector<unsigned int> unrolledBin(const unsigned int & total_bin_index) const; 80 : 81 : /** 82 : * Get the point at which to evaluate the user object 83 : * @param[in] local_elem_id local element ID on the Nek rank 84 : * @param[in] local_node_id local node ID on the element 85 : * @return point, in dimensional form 86 : */ 87 : Point nekPoint(const int & local_elem_id, const int & local_node_id) const; 88 : 89 : protected: 90 : /// Get the output points for a single bin 91 : void computePoints1D(); 92 : 93 : /// Get the output points for two combined bins 94 : void computePoints2D(); 95 : 96 : /// Get the output points for three combined bins 97 : void computePoints3D(); 98 : 99 : /// Reset the scratch space storage to zero values 100 : void resetPartialStorage(); 101 : 102 : /** 103 : * Get the coordinates for a point at the given indices for the bins 104 : * @param[in] indices indices of the bin distributions to combine 105 : * @param[out] p point at the (i, j, k) indices of the combined bins 106 : */ 107 : void fillCoordinates(const std::vector<unsigned int> & indices, Point & p) const; 108 : 109 : /// Interval with which to evaluate the user object 110 : const unsigned int & _interval; 111 : 112 : /// Whether the mesh this userobject operates on is fixed, allowing caching of volumes and areas 113 : bool _fixed_mesh; 114 : 115 : /// Names of the userobjects providing the bins 116 : const std::vector<UserObjectName> & _bin_names; 117 : 118 : /** 119 : * Whether to map the NekRS space to bins by element centroid (false) 120 : * or quadrature point (true). 121 : */ 122 : const bool & _map_space_by_qp; 123 : 124 : /** 125 : * Whether to throw an error if no GLL points or elements map to each bin 126 : * (which would indicate that the binning is probably way too fine relative 127 : * to the NekRS solution) 128 : */ 129 : const bool & _check_zero_contributions; 130 : 131 : /// Userobjects providing the bins 132 : std::vector<const SpatialBinUserObject *> _bins; 133 : 134 : /// For each x, y, z direction, whether the combined distribution covers that direction 135 : std::vector<bool> _has_direction; 136 : 137 : /// For each x, y, z direction, which bin provides that direction 138 : std::vector<unsigned int> _bin_providing_direction; 139 : 140 : /// total number of bins 141 : unsigned int _n_bins; 142 : 143 : /// points at which to output the user object to give unique values 144 : std::vector<Point> _points; 145 : 146 : /// velocity direction to use for each bin 147 : std::vector<Point> _velocity_bin_directions; 148 : 149 : /// values of the userobject in each bin 150 : double * _bin_values; 151 : 152 : /// temporary storage space to hold the results of component-wise evaluations 153 : double * _bin_values_x; 154 : double * _bin_values_y; 155 : double * _bin_values_z; 156 : 157 : /// Volumes of each bin 158 : double * _bin_volumes; 159 : 160 : /** 161 : * Number of GLL points (for 'map_space_by_qp = true') or elements (for 162 : * 'map_space_by_qp = false') that contribute to each bin, for error checking 163 : */ 164 : int * _bin_counts; 165 : 166 : /// Partial-sum of bin value per Nek rank 167 : double * _bin_partial_values; 168 : 169 : /// Partial-sum of bin count per Nek rank 170 : int * _bin_partial_counts; 171 : };