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 : #ifdef ENABLE_NEK_COUPLING 20 : 21 : #include "NekBinnedVolumeIntegral.h" 22 : #include "CardinalUtils.h" 23 : #include "NekInterface.h" 24 : 25 : registerMooseObject("CardinalApp", NekBinnedVolumeIntegral); 26 : 27 : InputParameters 28 277 : NekBinnedVolumeIntegral::validParams() 29 : { 30 277 : InputParameters params = NekVolumeSpatialBinUserObject::validParams(); 31 277 : params.addClassDescription( 32 : "Compute the spatially-binned volume integral of a field over the NekRS mesh"); 33 277 : return params; 34 0 : } 35 : 36 141 : NekBinnedVolumeIntegral::NekBinnedVolumeIntegral(const InputParameters & parameters) 37 141 : : NekVolumeSpatialBinUserObject(parameters) 38 : { 39 134 : if (_fixed_mesh) 40 134 : computeBinVolumes(); 41 133 : } 42 : 43 : void 44 134 : NekBinnedVolumeIntegral::getBinVolumes() 45 : { 46 134 : resetPartialStorage(); 47 : 48 134 : mesh_t * mesh = nekrs::entireMesh(); 49 134 : const auto & vgeo = nekrs::getVgeo(); 50 168054 : for (int k = 0; k < mesh->Nelements; ++k) 51 : { 52 167920 : int offset = k * mesh->Np; 53 25094000 : for (int v = 0; v < mesh->Np; ++v) 54 : { 55 24926080 : Point p = nekPoint(k, v); 56 24926080 : unsigned int b = bin(p); 57 24926080 : _bin_partial_values[b] += vgeo[mesh->Nvgeo * offset + v + mesh->Np * JWID]; 58 24926080 : _bin_partial_counts[b]++; 59 : } 60 : } 61 : 62 : // sum across all processes 63 134 : MPI_Allreduce( 64 : _bin_partial_values, _bin_volumes, _n_bins, MPI_DOUBLE, MPI_SUM, platform->comm.mpiComm); 65 134 : MPI_Allreduce( 66 : _bin_partial_counts, _bin_counts, _n_bins, MPI_INT, MPI_SUM, platform->comm.mpiComm); 67 : 68 : // dimensionalize 69 19825 : for (unsigned int i = 0; i < _n_bins; ++i) 70 19691 : nekrs::dimensionalizeVolume(_bin_volumes[i]); 71 134 : } 72 : 73 : Real 74 20952 : NekBinnedVolumeIntegral::spatialValue(const Point & p, const unsigned int & component) const 75 : { 76 20952 : const auto & i = bin(p); 77 20952 : return _bin_values[i] * _velocity_bin_directions[i](component); 78 : } 79 : 80 : void 81 236 : NekBinnedVolumeIntegral::binnedVolumeIntegral(const field::NekFieldEnum & integrand, 82 : double * total_integral) 83 : { 84 236 : resetPartialStorage(); 85 : 86 236 : mesh_t * mesh = nekrs::entireMesh(); 87 236 : double (*f)(int) = nekrs::solutionPointer(integrand); 88 236 : const auto & vgeo = nekrs::getVgeo(); 89 : 90 340132 : for (int k = 0; k < mesh->Nelements; ++k) 91 : { 92 339896 : int offset = k * mesh->Np; 93 100236088 : for (int v = 0; v < mesh->Np; ++v) 94 : { 95 99896192 : Point p = nekPoint(k, v); 96 99896192 : unsigned int b = bin(p); 97 99896192 : _bin_partial_values[b] += f(offset + v) * vgeo[mesh->Nvgeo * offset + v + mesh->Np * JWID]; 98 : } 99 : } 100 : 101 : // sum across all processes 102 236 : MPI_Allreduce( 103 : _bin_partial_values, total_integral, _n_bins, MPI_DOUBLE, MPI_SUM, platform->comm.mpiComm); 104 : 105 29172 : for (unsigned int i = 0; i < _n_bins; ++i) 106 28936 : nekrs::dimensionalizeVolumeIntegral(integrand, _bin_volumes[i], total_integral[i]); 107 236 : } 108 : 109 : void 110 228 : NekBinnedVolumeIntegral::executeUserObject() 111 : { 112 : // if the mesh is changing, re-compute the volumes of the bins and check the counts 113 228 : if (!_fixed_mesh) 114 0 : computeBinVolumes(); 115 : 116 228 : if (_field == field::velocity_component) 117 : { 118 4 : binnedVolumeIntegral(field::velocity_x, _bin_values_x); 119 4 : binnedVolumeIntegral(field::velocity_y, _bin_values_y); 120 4 : binnedVolumeIntegral(field::velocity_z, _bin_values_z); 121 : 122 436 : for (unsigned int i = 0; i < num_bins(); ++i) 123 : { 124 432 : Point velocity(_bin_values_x[i], _bin_values_y[i], _bin_values_z[i]); 125 432 : _bin_values[i] = _velocity_bin_directions[i] * velocity; 126 : } 127 : } 128 : else 129 224 : binnedVolumeIntegral(_field, _bin_values); 130 228 : } 131 : 132 : #endif