diff --git a/framework/include/vectorpostprocessors/SamplerBase.h b/framework/include/vectorpostprocessors/SamplerBase.h index 82af2f8834ac..0f5aaf602ced 100644 --- a/framework/include/vectorpostprocessors/SamplerBase.h +++ b/framework/include/vectorpostprocessors/SamplerBase.h @@ -116,7 +116,7 @@ class SamplerBase std::vector _variable_names; /// What to sort by - const unsigned int _sort_by; + const std::string _sort_by; /// x coordinate of the points VectorPostprocessorValue & _x; diff --git a/framework/src/vectorpostprocessors/LineValueSampler.C b/framework/src/vectorpostprocessors/LineValueSampler.C index 2c28a51146ec..81c8118f6ade 100644 --- a/framework/src/vectorpostprocessors/LineValueSampler.C +++ b/framework/src/vectorpostprocessors/LineValueSampler.C @@ -82,7 +82,7 @@ LineValueSampler::getValue(const Point & p) const "only one variable can be provided as input to LineValueSampler."); // Check if vectors are sorted by id - if (_sort_by != 3) + if (_sort_by != "id") mooseError("LineValueSampler: When calling getValue() on LineValueSampler, " "`sort_by` should be set to `id`."); diff --git a/framework/src/vectorpostprocessors/SamplerBase.C b/framework/src/vectorpostprocessors/SamplerBase.C index 7143777e4f13..54ae3d3831d2 100644 --- a/framework/src/vectorpostprocessors/SamplerBase.C +++ b/framework/src/vectorpostprocessors/SamplerBase.C @@ -25,8 +25,10 @@ SamplerBase::validParams() { InputParameters params = emptyInputParameters(); - MooseEnum sort_options("x y z id"); - params.addRequiredParam("sort_by", sort_options, "What to sort the samples by"); + params.addRequiredParam( + "sort_by", + "What to sort the samples by. Options are 'x y z id' and the name of any of the sampled " + "quantities (= name of the vector created by the vectorpostprocessor)."); // The value from this VPP is naturally already on every processor // TODO: Make this not the case! See #11415 @@ -45,7 +47,7 @@ SamplerBase::SamplerBase(const InputParameters & parameters, parameters.getCheckedPointerParam("_fe_problem_base") ->getMooseApp() .getExecutioner())), - _sort_by(parameters.get("sort_by")), + _sort_by(parameters.get("sort_by")), _x(vpp->declareVector("x")), _y(vpp->declareVector("y")), _z(vpp->declareVector("z")), @@ -173,9 +175,31 @@ SamplerBase::finalize() for (auto vec_ptr : vec_ptrs) _comm.allgather(*vec_ptr, /* identical buffer lengths = */ false); + // Find the index of the column to sort by + unsigned int sort_by_i = 0; + if (_sort_by == "x") + sort_by_i = 0; + else if (_sort_by == "y") + sort_by_i = 1; + else if (_sort_by == "z") + sort_by_i = 2; + else if (_sort_by == "id") + sort_by_i = 3; + else + { + // Find in 'variable_names' + const auto & it = std::find(_variable_names.begin(), _variable_names.end(), _sort_by); + if (it != _variable_names.end()) + sort_by_i = it - _variable_names.begin(); + else + mooseError("Sorting index '" + _sort_by + + "' was not found in x/y/z/id or sampled variable names: " + + Moose::stringify(_variable_names)); + } + // Now create an index vector by using an indirect sort std::vector sorted_indices; - Moose::indirectSort(vec_ptrs[_sort_by]->begin(), vec_ptrs[_sort_by]->end(), sorted_indices); + Moose::indirectSort(vec_ptrs[sort_by_i]->begin(), vec_ptrs[sort_by_i]->end(), sorted_indices); /** * We now have one sorted vector. The remaining vectors need to be sorted according to that diff --git a/test/tests/vectorpostprocessors/element_value_sampler/gold/sort_var_element_value_sampler_0000.csv b/test/tests/vectorpostprocessors/element_value_sampler/gold/sort_var_element_value_sampler_0000.csv new file mode 100644 index 000000000000..5c784f8ea57e --- /dev/null +++ b/test/tests/vectorpostprocessors/element_value_sampler/gold/sort_var_element_value_sampler_0000.csv @@ -0,0 +1,5 @@ +id,u,v,x,y,z +0,1.25,0.5,0.25,0.25,0 +2,2.75,1,0.25,0.75,0 +1,2.25,1,0.75,0.25,0 +3,3.75,1.5,0.75,0.75,0 diff --git a/test/tests/vectorpostprocessors/element_value_sampler/tests b/test/tests/vectorpostprocessors/element_value_sampler/tests index 7fd6457a4938..3629b38249ce 100644 --- a/test/tests/vectorpostprocessors/element_value_sampler/tests +++ b/test/tests/vectorpostprocessors/element_value_sampler/tests @@ -1,8 +1,8 @@ [Tests] - issues = '#11594 #31240' design = 'ElementValueSampler.md' [element_value_sampler] + issues = '#11594 #31240' requirement = 'The system shall support sampling of a field variable at the centroid of every element in the domain' [monomial] type = 'CSVDiff' @@ -31,7 +31,19 @@ max_threads = 1 # see libmesh issue #3808 (due to the linear fv variable here) [] [] + [sorting] + issues = '#31913' + requirement = "The system shall be able to sort sampled output" + [by_variable] + type = CSVDiff + input = 'element_value_sampler.i' + cli_args = "Outputs/file_base=sort_var VectorPostprocessors/element_value_sampler/sort_by='u'" + csvdiff = 'sort_var_element_value_sampler_0000.csv' + detail = "using the variables as a sorting index," + [] + [] [exceptions] + issues = '#11594 #31240' requirement = 'The system shall throw an error if the variables specified for elemental sampling are' [nodal] type = 'RunException'