PICurv 0.1.0
A Parallel Particle-In-Cell Solver for Curvilinear LES
 
Loading...
Searching...
No Matches
Data Structures | Macros | Enumerations | Functions
statistics_target.h File Reference

Spatial target resolution for the field-statistics pipeline. More...

#include "variables.h"
#include "field_catalog.h"
Include dependency graph for statistics_target.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  SpatialTargetPlan
 Resolved iteration domain for one field on one block. More...
 

Macros

#define PICURV_STATISTICS_FLUID_THRESHOLD   0.1
 Threshold below which a cell counts as fluid for the default mask.
 
#define PICURV_SPATIAL_AVERAGE_MAX_BUFFER   4000000
 Largest reduction buffer a directional average will allocate, in entries.
 

Enumerations

enum  PicurvTargetKind { PICURV_TARGET_POINTWISE = 0 }
 Spatial mapping kind. More...
 
enum  PicurvStatisticsMask { PICURV_STATISTICS_MASK_FLUID = 0 }
 Point-eligibility mask. More...
 

Functions

PetscErrorCode PicurvLayoutDimensionIsNodeLike (FieldLayout layout, PetscInt dim, PetscBool *node_like)
 Reports whether a layout is node-like in one dimension.
 
PetscErrorCode SpatialTargetPlanCreate (UserCtx *user, FieldId field_id, PicurvStatisticsMask mask, SpatialTargetPlan *plan)
 Resolves the iteration domain for one field on one block.
 
PetscErrorCode SpatialTargetPlanLocalPointCount (const SpatialTargetPlan *plan, PetscInt *count)
 Counts the points this rank contributes.
 
PetscErrorCode SpatialTargetPlanGlobalPointCount (const SpatialTargetPlan *plan, MPI_Comm comm, PetscInt *count)
 Counts the points contributed across a communicator.
 
PetscBool SpatialTargetPlanMaskAllows (const SpatialTargetPlan *plan, PetscReal nvert_value)
 Reports whether a point passes the plan's mask.
 
PetscErrorCode PicurvSpatialRatioAverage (UserCtx *user, const SpatialTargetPlan *plan, Vec numerator, Vec denominator, Vec inclusion, const PetscBool average_direction[3], MPI_Comm comm, Vec ratio, PetscReal *scalar)
 Averages two fields over a target domain and divides the results.
 

Detailed Description

Spatial target resolution for the field-statistics pipeline.

Implements the pointwise identity mapping described in 5. Spatial Target, Layout, and Mask. The abstraction exists with only that one mapping so later spatial bins, profiles, regions, and surfaces extend it rather than retrofit it; see Field Statistics Planned Extensions.

The central responsibility is producing an iteration domain that excludes two distinct categories which Field Identity and Layout Catalog section 4 warns must not be conflated:

  1. PETSc/MPI halo entries created by DMDA decomposition, and
  2. solver-layout boundary, dummy, or duplicate-periodic indices, which exist even on a single MPI rank.

Nothing here resolves field identity or layout metadata itself; that comes from the typed catalog through FieldGetDescriptor.

Definition in file statistics_target.h.


Data Structure Documentation

◆ SpatialTargetPlan

struct SpatialTargetPlan

Resolved iteration domain for one field on one block.

Bounds are half-open [start, end) in DMDA index order (i, j, k) and are already intersected with this rank's owned range, so iterating them touches neither halo storage nor layout boundary/dummy/duplicate-periodic indices. An empty domain on a rank is represented by end[d] <= start[d].

Definition at line 49 of file statistics_target.h.

Collaboration diagram for SpatialTargetPlan:
[legend]
Data Fields
PicurvTargetKind kind Spatial mapping; always pointwise.
PicurvStatisticsMask mask Point-eligibility mask.
const FieldDescriptor * descriptor Catalog metadata for the targeted field.
PetscInt start[3] Inclusive start per dimension (i, j, k).
PetscInt end[3] Exclusive end per dimension (i, j, k).

Macro Definition Documentation

◆ PICURV_STATISTICS_FLUID_THRESHOLD

#define PICURV_STATISTICS_FLUID_THRESHOLD   0.1

Threshold below which a cell counts as fluid for the default mask.

Definition at line 29 of file statistics_target.h.

◆ PICURV_SPATIAL_AVERAGE_MAX_BUFFER

#define PICURV_SPATIAL_AVERAGE_MAX_BUFFER   4000000

Largest reduction buffer a directional average will allocate, in entries.

Definition at line 127 of file statistics_target.h.

Enumeration Type Documentation

◆ PicurvTargetKind

Spatial mapping kind.

Only the pointwise identity is implemented.

Enumerator
PICURV_TARGET_POINTWISE 

Definition at line 32 of file statistics_target.h.

32 {
PicurvTargetKind
Spatial mapping kind.
@ PICURV_TARGET_POINTWISE

◆ PicurvStatisticsMask

Point-eligibility mask.

Only the fluid mask is implemented.

Enumerator
PICURV_STATISTICS_MASK_FLUID 

Definition at line 37 of file statistics_target.h.

37 {
PicurvStatisticsMask
Point-eligibility mask.
@ PICURV_STATISTICS_MASK_FLUID

Function Documentation

◆ PicurvLayoutDimensionIsNodeLike()

PetscErrorCode PicurvLayoutDimensionIsNodeLike ( FieldLayout  layout,
PetscInt  dim,
PetscBool *  node_like 
)

Reports whether a layout is node-like in one dimension.

Node-like dimensions carry one more physical entry than cell-like dimensions, because they sit on grid lines rather than between them. I_FACE is node-like in i and cell-like in j and k, and correspondingly for the other face families.

Parameters
[in]layoutCatalog layout.
[in]dimDimension index: 0 for i, 1 for j, 2 for k.
[out]node_likeResolved classification.
Returns
Zero on success, or PETSC_ERR_ARG_OUTOFRANGE for an invalid dimension, or PETSC_ERR_ARG_WRONGSTATE for a component-staggered layout, whose components do not share one classification.

Reports whether a layout is node-like in one dimension.

See also
PicurvLayoutDimensionIsNodeLike()

Definition at line 16 of file statistics_target.c.

17{
18 PetscFunctionBeginUser;
19 PetscCheck(node_like != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
20 "Classification output is required.");
21 PetscCheck(dim >= 0 && dim < 3, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE,
22 "Dimension must be 0, 1, or 2; got %" PetscInt_FMT ".", dim);
23
24 switch (layout) {
26 *node_like = PETSC_TRUE;
27 break;
29 *node_like = PETSC_FALSE;
30 break;
32 *node_like = (PetscBool)(dim == 0);
33 break;
35 *node_like = (PetscBool)(dim == 1);
36 break;
38 *node_like = (PetscBool)(dim == 2);
39 break;
41 /* x, y, and z live on I-, J-, and K-faces respectively, so no single
42 * classification describes the packed vector. */
43 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
44 "Component-staggered layout has no single per-dimension classification.");
45 default:
46 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE,
47 "Unknown field layout %d.", (int)layout);
48 }
49 PetscFunctionReturn(0);
50}
@ FIELD_LAYOUT_K_FACE
@ FIELD_LAYOUT_I_FACE
@ FIELD_LAYOUT_CELL_CENTERED
@ FIELD_LAYOUT_COMPONENT_STAGGERED
@ FIELD_LAYOUT_NODE_CENTERED
@ FIELD_LAYOUT_J_FACE
Here is the caller graph for this function:

◆ SpatialTargetPlanCreate()

PetscErrorCode SpatialTargetPlanCreate ( UserCtx *  user,
FieldId  field_id,
PicurvStatisticsMask  mask,
SpatialTargetPlan *  plan 
)

Resolves the iteration domain for one field on one block.

Rejects component-staggered fields, whose x, y, and z components live on different face families and therefore cannot share a single pointwise domain. Configured statistics request only cell-centered fields, but the plan resolves node and face layouts correctly so later phases inherit a verified contract.

Parameters
[in]userBlock context supplying the DMDA layout and periodicity.
[in]field_idCatalogued field to target.
[in]maskPoint-eligibility mask.
[out]planResolved plan.
Returns
Zero on success, or a PETSc error for a null argument, an unknown field, or an unsupported layout.

Resolves the iteration domain for one field on one block.

See also
SpatialTargetPlanCreate()

Definition at line 79 of file statistics_target.c.

81{
82 const FieldDescriptor *descriptor = NULL;
83 const DMDALocalInfo *info = NULL;
84 SimCtx *simCtx = NULL;
85 PetscInt owned_start[3];
86 PetscInt owned_end[3];
87 PetscInt global_size[3];
88 PetscBool periodic[3];
89
90 PetscFunctionBeginUser;
92 PetscCheck(user != NULL && plan != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
93 "Block context and plan output are required.");
94 PetscCheck(mask == PICURV_STATISTICS_MASK_FLUID, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE,
95 "Only the fluid mask is implemented.");
96 simCtx = user->simCtx;
97 PetscCheck(simCtx != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
98 "Block context must carry a simulation context.");
99
100 PetscCall(FieldGetDescriptor(field_id, &descriptor));
101 PetscCheck(descriptor->layout != FIELD_LAYOUT_COMPONENT_STAGGERED,
102 PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
103 "Field '%s' is component-staggered; its components live on different face "
104 "families and cannot share one pointwise target domain.",
105 descriptor->canonical_name);
106
107 info = &user->info;
108 owned_start[0] = info->xs; owned_end[0] = info->xs + info->xm; global_size[0] = info->mx;
109 owned_start[1] = info->ys; owned_end[1] = info->ys + info->ym; global_size[1] = info->my;
110 owned_start[2] = info->zs; owned_end[2] = info->zs + info->zm; global_size[2] = info->mz;
111 /* The simCtx flags are authoritative here because they are what selects
112 * DM_BOUNDARY_PERIODIC when the DMDA is built, and therefore what decides
113 * whether the end planes are wrapped duplicates. */
114 periodic[0] = (PetscBool)(simCtx->i_periodic != 0);
115 periodic[1] = (PetscBool)(simCtx->j_periodic != 0);
116 periodic[2] = (PetscBool)(simCtx->k_periodic != 0);
117
119 plan->mask = mask;
120 plan->descriptor = descriptor;
121
122 for (PetscInt dim = 0; dim < 3; ++dim) {
123 PetscBool node_like = PETSC_FALSE;
124 PetscInt layout_lo = 0;
125 PetscInt layout_hi = 0;
126
127 PetscCall(PicurvLayoutDimensionIsNodeLike(descriptor->layout, dim, &node_like));
128 ResolveLayoutSpan(node_like, periodic[dim], global_size[dim], &layout_lo, &layout_hi);
129
130 /* Intersect the layout-valid span with this rank's owned range: the
131 * first exclusion removes solver-layout indices, the second removes
132 * PETSc halo storage. */
133 plan->start[dim] = PetscMax(owned_start[dim], layout_lo);
134 plan->end[dim] = PetscMin(owned_end[dim], layout_hi);
135 if (plan->end[dim] < plan->start[dim]) plan->end[dim] = plan->start[dim];
136 }
138 PetscFunctionReturn(0);
139}
FieldLayout layout
const char * canonical_name
PetscErrorCode FieldGetDescriptor(FieldId field_id, const FieldDescriptor **descriptor)
Return immutable metadata for a valid field identifier.
Immutable metadata for one field identity.
#define PROFILE_FUNCTION_END
Marks the end of a profiled code block.
Definition logging.h:894
#define PROFILE_FUNCTION_BEGIN
Marks the beginning of a profiled code block (typically a function).
Definition logging.h:885
static void ResolveLayoutSpan(PetscBool node_like, PetscBool periodic, PetscInt size, PetscInt *lo, PetscInt *hi_exclusive)
Internal helper: resolves the layout-valid index span for one dimension.
PetscErrorCode PicurvLayoutDimensionIsNodeLike(FieldLayout layout, PetscInt dim, PetscBool *node_like)
Implementation of PicurvLayoutDimensionIsNodeLike().
PicurvTargetKind kind
Spatial mapping; always pointwise.
PetscInt end[3]
Exclusive end per dimension (i, j, k).
PetscInt start[3]
Inclusive start per dimension (i, j, k).
const FieldDescriptor * descriptor
Catalog metadata for the targeted field.
PicurvStatisticsMask mask
Point-eligibility mask.
SimCtx * simCtx
Back-pointer to the master simulation context.
Definition variables.h:1076
PetscInt k_periodic
Definition variables.h:961
PetscInt i_periodic
Definition variables.h:961
DMDALocalInfo info
Definition variables.h:1085
PetscInt j_periodic
Definition variables.h:961
The master context for the entire simulation.
Definition variables.h:866
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SpatialTargetPlanLocalPointCount()

PetscErrorCode SpatialTargetPlanLocalPointCount ( const SpatialTargetPlan *  plan,
PetscInt *  count 
)

Counts the points this rank contributes.

Parameters
[in]planResolved plan.
[out]countLocal point count; zero for an empty domain.
Returns
Zero on success, or PETSC_ERR_ARG_NULL for a null argument.

Counts the points this rank contributes.

See also
SpatialTargetPlanLocalPointCount()

Definition at line 145 of file statistics_target.c.

146{
147 PetscInt total = 1;
148
149 PetscFunctionBeginUser;
150 PetscCheck(plan != NULL && count != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
151 "Plan and count output are required.");
152 for (PetscInt dim = 0; dim < 3; ++dim) {
153 const PetscInt extent = plan->end[dim] - plan->start[dim];
154 if (extent <= 0) { *count = 0; PetscFunctionReturn(0); }
155 total *= extent;
156 }
157 *count = total;
158 PetscFunctionReturn(0);
159}
Here is the caller graph for this function:

◆ SpatialTargetPlanGlobalPointCount()

PetscErrorCode SpatialTargetPlanGlobalPointCount ( const SpatialTargetPlan *  plan,
MPI_Comm  comm,
PetscInt *  count 
)

Counts the points contributed across a communicator.

The result is decomposition independent: it depends only on the layout, global dimensions, and periodicity, never on how ranks divide the domain.

Parameters
[in]planResolved plan.
[in]commCommunicator to reduce over.
[out]countGlobal point count.
Returns
Zero on success, or PETSC_ERR_ARG_NULL for a null argument.

Counts the points contributed across a communicator.

See also
SpatialTargetPlanGlobalPointCount()

Definition at line 167 of file statistics_target.c.

168{
169 PetscInt local = 0;
170
171 PetscFunctionBeginUser;
173 PetscCheck(plan != NULL && count != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
174 "Plan and count output are required.");
175 PetscCall(SpatialTargetPlanLocalPointCount(plan, &local));
176 PetscCallMPI(MPI_Allreduce(&local, count, 1, MPIU_INT, MPI_SUM, comm));
178 PetscFunctionReturn(0);
179}
PetscErrorCode SpatialTargetPlanLocalPointCount(const SpatialTargetPlan *plan, PetscInt *count)
Implementation of SpatialTargetPlanLocalPointCount().
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SpatialTargetPlanMaskAllows()

PetscBool SpatialTargetPlanMaskAllows ( const SpatialTargetPlan *  plan,
PetscReal  nvert_value 
)

Reports whether a point passes the plan's mask.

Because Nvert changes when immersed bodies move, the mask is treated as potentially moving: callers accumulate a per-point valid count and weight rather than assuming a point contributes to every accepted state.

Parameters
[in]planResolved plan.
[in]nvert_valueNode-blanking value at the point.
Returns
PETSC_TRUE when the point is eligible.

Reports whether a point passes the plan's mask.

See also
SpatialTargetPlanMaskAllows()

Definition at line 185 of file statistics_target.c.

186{
187 if (plan == NULL) return PETSC_FALSE;
188 return (PetscBool)(nvert_value < PICURV_STATISTICS_FLUID_THRESHOLD);
189}
#define PICURV_STATISTICS_FLUID_THRESHOLD
Threshold below which a cell counts as fluid for the default mask.
Here is the caller graph for this function:

◆ PicurvSpatialRatioAverage()

PetscErrorCode PicurvSpatialRatioAverage ( UserCtx *  user,
const SpatialTargetPlan *  plan,
Vec  numerator,
Vec  denominator,
Vec  inclusion,
const PetscBool  average_direction[3],
MPI_Comm  comm,
Vec  ratio,
PetscReal *  scalar 
)

Averages two fields over a target domain and divides the results.

Computes ratio = <numerator> / <denominator>, where each average is taken separately over the points the plan admits, and then divides. The order matters: the mean of the pointwise quotients is a different number from the quotient of the means, and several callers need the second one. The LES dynamic procedure is one, because Lilly's least-squares closure is defined that way.

average_direction selects which logical directions collapse into the average. Selecting none makes the operation pointwise, which lets a caller express a local and an averaged formulation through one code path rather than two. Selecting all three yields one number for the whole domain. Selecting a subset retains a profile along the directions left out — averaging over xi and zeta on a plane channel, for example, leaves a wall-normal profile.

Weighting is the caller's, not this function's: scale numerator and denominator by whatever weight the average should carry before calling. A caller wanting a volume-weighted average multiplies both by the cell volume; a caller wanting each admitted point to count once passes them unscaled.

The reduction runs over comm, so a result is independent of how the domain is decomposed across ranks. The plan already excludes PETSc halo storage and the solver's boundary, dummy, and duplicate-periodic indices, so no physical point is counted twice.

Parameters
[in]userBlock context supplying the DMDA and the solid mask.
[in]planResolved iteration domain, from SpatialTargetPlanCreate().
[in]numeratorGhosted local field to average in the numerator.
[in]denominatorGhosted local field to average in the denominator, or NULL to divide by the number of admitted points.
[in]inclusionOptional second mask: points where this field is not positive are skipped. Use it to exclude points that hold a zero meaning "never measured" rather than a measurement. NULL applies the plan's mask alone.
[in]average_directionDirections to average over, in (xi, eta, zeta) order.
[in]commCommunicator to reduce over.
[out]ratioGhosted local field receiving the quotient, or NULL when only the scalar is wanted. Zero wherever the averaged denominator underflows.
[out]scalarReceives the single averaged value, or NULL. Valid only when every direction is averaged, since otherwise there is no single value to report.
Returns
Zero on success, PETSC_ERR_ARG_OUTOFRANGE when the retained directions would need an unreasonably large reduction buffer, or PETSC_ERR_ARG_WRONGSTATE when a scalar is requested from a result that still varies in space.

Averages two fields over a target domain and divides the results.

See also
PicurvSpatialRatioAverage()

Definition at line 210 of file statistics_target.c.

214{
215 DM da = NULL;
216 DMDALocalInfo info;
217 PetscInt retained_extent[3];
218 PetscInt buffer_size = 1;
219 PetscInt averaged_count = 0;
220 PetscReal ***num = NULL, ***den = NULL, ***inc = NULL, ***out = NULL, ***nvert = NULL;
221 PetscReal *num_sum = NULL, *den_sum = NULL;
222
223 PetscFunctionBeginUser;
225 PetscCheck(user != NULL && plan != NULL && numerator != NULL && average_direction != NULL,
226 PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
227 "Context, plan, numerator, and direction selector are required.");
228
229 da = user->da;
230 PetscCall(DMDAGetLocalInfo(da, &info));
231
232 retained_extent[0] = average_direction[0] ? 1 : info.mx;
233 retained_extent[1] = average_direction[1] ? 1 : info.my;
234 retained_extent[2] = average_direction[2] ? 1 : info.mz;
235 for (PetscInt axis = 0; axis < 3; axis++) {
236 if (average_direction[axis]) averaged_count++;
237 buffer_size *= retained_extent[axis];
238 }
239 PetscCheck(scalar == NULL || averaged_count == 3, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
240 "A single averaged value exists only when every direction is averaged over; "
241 "%" PetscInt_FMT " of 3 were selected.", averaged_count);
242
243 PetscCall(DMDAVecGetArrayRead(da, numerator, &num));
244 if (denominator) PetscCall(DMDAVecGetArrayRead(da, denominator, &den));
245 if (inclusion) PetscCall(DMDAVecGetArrayRead(da, inclusion, &inc));
246 if (ratio) PetscCall(DMDAVecGetArray(da, ratio, &out));
247 PetscCall(DMDAVecGetArrayRead(da, user->lNvert, &nvert));
248
249 if (averaged_count == 0) {
250 /* Pointwise: the empty averaging set, which is a legitimate request rather
251 * than a degenerate one. It is what a local formulation asks for. The masks
252 * mean the same thing here as they do for an averaged set - a point they
253 * exclude contributes nothing and receives nothing - so that a caller can
254 * switch between the two without its exclusions quietly changing meaning. */
255 for (PetscInt k = plan->start[2]; k < plan->end[2]; k++)
256 for (PetscInt j = plan->start[1]; j < plan->end[1]; j++)
257 for (PetscInt i = plan->start[0]; i < plan->end[0]; i++) {
258 const PetscReal divisor = denominator ? den[k][j][i] : 1.0;
259
260 if (!SpatialTargetPlanMaskAllows(plan, nvert[k][j][i]) ||
261 (inc && inc[k][j][i] <= 0.0)) {
262 out[k][j][i] = 0.0;
263 continue;
264 }
265 out[k][j][i] = (PetscAbsReal(divisor) > 0.0) ? (num[k][j][i] / divisor) : 0.0;
266 }
267 } else {
268 PetscCheck(buffer_size <= PICURV_SPATIAL_AVERAGE_MAX_BUFFER, PETSC_COMM_SELF,
269 PETSC_ERR_ARG_OUTOFRANGE,
270 "Averaging over %" PetscInt_FMT " direction(s) would need a reduction buffer "
271 "of %" PetscInt_FMT " entries, above the %d entry limit. Average over more "
272 "directions.", averaged_count, buffer_size, PICURV_SPATIAL_AVERAGE_MAX_BUFFER);
273
274 PetscCall(PetscCalloc2(buffer_size, &num_sum, buffer_size, &den_sum));
275
276 for (PetscInt k = plan->start[2]; k < plan->end[2]; k++)
277 for (PetscInt j = plan->start[1]; j < plan->end[1]; j++)
278 for (PetscInt i = plan->start[0]; i < plan->end[0]; i++) {
279 PetscInt slot;
280
281 if (!SpatialTargetPlanMaskAllows(plan, nvert[k][j][i])) continue;
282 /* A point the caller marks unmeasured holds a zero that means absence, not
283 * a measurement; counting it would scale the answer toward zero. */
284 if (inc && inc[k][j][i] <= 0.0) continue;
285
286 slot = SpatialAverageSlot(average_direction, retained_extent, i, j, k);
287 num_sum[slot] += num[k][j][i];
288 den_sum[slot] += denominator ? den[k][j][i] : 1.0;
289 }
290
291 PetscCallMPI(MPI_Allreduce(MPI_IN_PLACE, num_sum, (PetscMPIInt)buffer_size,
292 MPIU_REAL, MPI_SUM, comm));
293 PetscCallMPI(MPI_Allreduce(MPI_IN_PLACE, den_sum, (PetscMPIInt)buffer_size,
294 MPIU_REAL, MPI_SUM, comm));
295
296 if (out) {
297 for (PetscInt k = plan->start[2]; k < plan->end[2]; k++)
298 for (PetscInt j = plan->start[1]; j < plan->end[1]; j++)
299 for (PetscInt i = plan->start[0]; i < plan->end[0]; i++) {
300 const PetscInt slot = SpatialAverageSlot(average_direction, retained_extent, i, j, k);
301
302 out[k][j][i] = (PetscAbsReal(den_sum[slot]) > 0.0)
303 ? (num_sum[slot] / den_sum[slot]) : 0.0;
304 }
305 }
306 if (scalar) {
307 *scalar = (PetscAbsReal(den_sum[0]) > 0.0) ? (num_sum[0] / den_sum[0]) : 0.0;
308 }
309
310 PetscCall(PetscFree2(num_sum, den_sum));
311 }
312
313 PetscCall(DMDAVecRestoreArrayRead(da, numerator, &num));
314 if (denominator) PetscCall(DMDAVecRestoreArrayRead(da, denominator, &den));
315 if (inclusion) PetscCall(DMDAVecRestoreArrayRead(da, inclusion, &inc));
316 if (ratio) PetscCall(DMDAVecRestoreArray(da, ratio, &out));
317 PetscCall(DMDAVecRestoreArrayRead(da, user->lNvert, &nvert));
318
320 PetscFunctionReturn(0);
321}
PetscBool SpatialTargetPlanMaskAllows(const SpatialTargetPlan *plan, PetscReal nvert_value)
Implementation of SpatialTargetPlanMaskAllows().
static PetscInt SpatialAverageSlot(const PetscBool average_direction[3], const PetscInt retained_extent[3], PetscInt i, PetscInt j, PetscInt k)
Flattens the retained global indices of one point into a reduction slot.
#define PICURV_SPATIAL_AVERAGE_MAX_BUFFER
Largest reduction buffer a directional average will allocate, in entries.
Vec lNvert
Definition variables.h:1113
Here is the call graph for this function:
Here is the caller graph for this function: