@@ -765,16 +765,37 @@ void CFlowOutput::SetCustomOutputs(const CSolver* const* solver, const CGeometry
765765 } else {
766766 SU2_MPI::Error (" Unknown flow solver type." , CURRENT_FUNCTION);
767767 }
768- /* --- Convert marker names to their index (if any) in this rank. ---*/
769-
770- output.markerIndices .clear ();
771- for (const auto & marker : output.markers ) {
772- for (auto iMarker = 0u ; iMarker < config->GetnMarker_All (); ++iMarker) {
773- if (config->GetMarker_All_TagBound (iMarker) == marker) {
774- output.markerIndices .push_back (iMarker);
775- continue ;
768+ /* --- Convert marker names to their index (if any) in this rank. Or probe locations to nearest points. ---*/
769+
770+ if (output.type != OperationType::PROBE) {
771+ output.markerIndices .clear ();
772+ for (const auto & marker : output.markers ) {
773+ for (auto iMarker = 0u ; iMarker < config->GetnMarker_All (); ++iMarker) {
774+ if (config->GetMarker_All_TagBound (iMarker) == marker) {
775+ output.markerIndices .push_back (iMarker);
776+ continue ;
777+ }
778+ }
779+ }
780+ } else {
781+ if (output.markers .size () != nDim) {
782+ SU2_MPI::Error (" Wrong number of coordinates to specify probe " + output.name , CURRENT_FUNCTION);
783+ }
784+ su2double coord[3 ] = {};
785+ for (auto iDim = 0u ; iDim < nDim; ++iDim) coord[iDim] = std::stod (output.markers [iDim]);
786+ su2double minDist = std::numeric_limits<su2double>::max ();
787+ unsigned long minPoint = 0 ;
788+ for (auto iPoint = 0ul ; iPoint < geometry->GetnPointDomain (); ++iPoint) {
789+ const su2double dist = GeometryToolbox::SquaredDistance (nDim, coord, geometry->nodes ->GetCoord (iPoint));
790+ if (dist < minDist) {
791+ minDist = dist;
792+ minPoint = iPoint;
776793 }
777794 }
795+ /* --- Decide which rank owns the probe. ---*/
796+ su2double globMinDist;
797+ SU2_MPI::Allreduce (&minDist, &globMinDist, 1 , MPI_DOUBLE, MPI_MIN, SU2_MPI::GetComm ());
798+ output.iPoint = (minDist == globMinDist) ? minPoint : CustomOutput::PROBE_NOT_OWNED;
778799 }
779800 }
780801
@@ -787,6 +808,36 @@ void CFlowOutput::SetCustomOutputs(const CSolver* const* solver, const CGeometry
787808 continue ;
788809 }
789810
811+ /* --- Prepares the functor that maps symbol indices to values at a given point
812+ * (see ConvertVariableSymbolsToIndices). ---*/
813+
814+ auto MakeFunctor = [&](unsigned long iPoint) {
815+ return [&, iPoint](unsigned long i) {
816+ if (i < CustomOutput::NOT_A_VARIABLE) {
817+ const auto solIdx = i / CustomOutput::MAX_VARS_PER_SOLVER;
818+ const auto varIdx = i % CustomOutput::MAX_VARS_PER_SOLVER;
819+ if (solIdx == FLOW_SOL) {
820+ return flowNodes->GetPrimitive (iPoint, varIdx);
821+ } else {
822+ return solver[solIdx]->GetNodes ()->GetSolution (iPoint, varIdx);
823+ }
824+ } else {
825+ return *output.otherOutputs [i - CustomOutput::NOT_A_VARIABLE];
826+ }
827+ };
828+ };
829+
830+ if (output.type == OperationType::PROBE) {
831+ su2double value = std::numeric_limits<su2double>::max ();
832+ if (output.iPoint != CustomOutput::PROBE_NOT_OWNED) {
833+ value = output.eval (MakeFunctor (output.iPoint ));
834+ }
835+ su2double tmp = value;
836+ SU2_MPI::Allreduce (&tmp, &value, 1 , MPI_DOUBLE, MPI_MIN, SU2_MPI::GetComm ());
837+ SetHistoryOutputValue (output.name , value);
838+ continue ;
839+ }
840+
790841 /* --- Surface integral of the expression. ---*/
791842
792843 std::array<su2double, 2 > integral = {0.0 , 0.0 };
@@ -812,23 +863,7 @@ void CFlowOutput::SetCustomOutputs(const CSolver* const* solver, const CGeometry
812863 }
813864 weight *= GetAxiFactor (axisymmetric, *geometry->nodes , iPoint, iMarker);
814865 local_integral[1 ] += weight;
815-
816- /* --- Prepare the functor that maps symbol indices to values (see ConvertVariableSymbolsToIndices). ---*/
817-
818- auto Functor = [&](unsigned long i) {
819- if (i < CustomOutput::NOT_A_VARIABLE) {
820- const auto solIdx = i / CustomOutput::MAX_VARS_PER_SOLVER;
821- const auto varIdx = i % CustomOutput::MAX_VARS_PER_SOLVER;
822- if (solIdx == FLOW_SOL) {
823- return flowNodes->GetPrimitive (iPoint, varIdx);
824- } else {
825- return solver[solIdx]->GetNodes ()->GetSolution (iPoint, varIdx);
826- }
827- } else {
828- return *output.otherOutputs [i - CustomOutput::NOT_A_VARIABLE];
829- }
830- };
831- local_integral[0 ] += weight * output.eval (Functor);
866+ local_integral[0 ] += weight * output.eval (MakeFunctor (iPoint));
832867 }
833868 END_SU2_OMP_FOR
834869 }
0 commit comments