PICurv 0.1.0
A Parallel Particle-In-Cell Solver for Curvilinear LES
Loading...
Searching...
No Matches
field_catalog.c
Go to the documentation of this file.
1/**
2 * @file field_catalog.c
3 * @brief Authoritative persistent-Eulerian-field catalog and runtime view resolver.
4 */
5
6#include "field_catalog.h"
7
8#define FIELD_NO_VEC_OFFSET ((size_t)-1)
9
10#define FIELD_ENTRY(field_id_, name_, alias1_, alias2_, dof_, dm_, layout_, sync_, availability_, capabilities_, global_member_, local_member_) \
11 [field_id_] = { \
12 field_id_, name_, alias1_, alias2_, dof_, dm_, layout_, sync_, availability_, capabilities_, \
13 offsetof(UserCtx, global_member_), offsetof(UserCtx, local_member_) \
14 }
15
16#define FIELD_COORDINATE_ENTRY(field_id_, name_, dof_, layout_, capabilities_) \
17 [field_id_] = { \
18 field_id_, name_, NULL, NULL, dof_, FIELD_DM_COORDINATES, layout_, \
19 FIELD_SYNC_STANDARD, FIELD_AVAILABILITY_ALWAYS, capabilities_, \
20 FIELD_NO_VEC_OFFSET, FIELD_NO_VEC_OFFSET \
21 }
22
34 FIELD_CAPABILITY_GHOST_UPDATE, Ucont_o, lUcont_o),
37 FIELD_CAPABILITY_GHOST_UPDATE, Ucont_rm1, lUcont_rm1),
41 FIELD_ENTRY(FIELD_ID_NU_T, "Nu_t", "Eddy Viscosity", NULL, 1, FIELD_DM_DA, FIELD_LAYOUT_CELL_CENTERED,
50 FIELD_ENTRY(FIELD_ID_DIFFUSIVITY_GRADIENT, "DiffusivityGradient", NULL, NULL, 3, FIELD_DM_FDA,
52 FIELD_CAPABILITY_GHOST_UPDATE, DiffusivityGradient, lDiffusivityGradient),
68 FIELD_ENTRY(FIELD_ID_CENT, "Cent", "Center-Coordinates", NULL, 3, FIELD_DM_FDA, FIELD_LAYOUT_CELL_CENTERED,
72 FIELD_ENTRY(FIELD_ID_CENTX, "Centx", "X-Face-Centers", NULL, 3, FIELD_DM_FDA, FIELD_LAYOUT_I_FACE,
76 FIELD_ENTRY(FIELD_ID_CENTY, "Centy", "Y-Face-Centers", NULL, 3, FIELD_DM_FDA, FIELD_LAYOUT_J_FACE,
80 FIELD_ENTRY(FIELD_ID_CENTZ, "Centz", "Z-Face-Centers", NULL, 3, FIELD_DM_FDA, FIELD_LAYOUT_K_FACE,
128 FIELD_CAPABILITY_GHOST_UPDATE, Nvert_o, lNvert_o),
131 FIELD_CAPABILITY_GHOST_UPDATE, ParticleCount, lParticleCount),
134 FIELD_CAPABILITY_GHOST_UPDATE, K_Omega, lK_Omega),
137 FIELD_CAPABILITY_GHOST_UPDATE, K_Omega_o, lK_Omega_o)
138};
139
140_Static_assert(sizeof(gFieldCatalog) / sizeof(gFieldCatalog[0]) == FIELD_ID_COUNT,
141 "Field catalog must contain one entry per FieldId.");
142
143/**
144 * @brief Returns the immutable catalog descriptor for one typed field identity.
145 * @details Validates the enum range and the table's ID/index invariant before
146 * exposing the catalog-owned descriptor.
147 * @see FieldGetDescriptor()
148 */
149PetscErrorCode FieldGetDescriptor(FieldId field_id, const FieldDescriptor **descriptor)
150{
151 PetscFunctionBeginUser;
152 PetscCheck(descriptor != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
153 "Field descriptor output cannot be NULL.");
154 PetscCheck(field_id >= 0 && field_id < FIELD_ID_COUNT, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE,
155 "Invalid FieldId value %d.", (int)field_id);
156 PetscCheck(gFieldCatalog[field_id].id == field_id, PETSC_COMM_SELF, PETSC_ERR_PLIB,
157 "Field catalog entry %d is not initialized consistently.", (int)field_id);
158
159 *descriptor = &gFieldCatalog[field_id];
160 PetscFunctionReturn(0);
161}
162
163/**
164 * @brief Resolves a canonical field name or registered alias to a typed identity.
165 * @details Name comparison is intentionally confined to ingress; numerical
166 * consumers receive the resolved @ref FieldId.
167 * @see FieldIdFromName()
168 */
169PetscErrorCode FieldIdFromName(const char *field_name, FieldId *field_id)
170{
171 PetscFunctionBeginUser;
172 PetscCheck(field_name != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
173 "Field name cannot be NULL.");
174 PetscCheck(field_id != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
175 "FieldId output cannot be NULL.");
176
177 for (PetscInt index = 0; index < FIELD_ID_COUNT; ++index) {
178 const FieldDescriptor *descriptor = &gFieldCatalog[index];
179 PetscBool match = PETSC_FALSE;
180
181 PetscCall(PetscStrcasecmp(field_name, descriptor->canonical_name, &match));
182 if (!match && descriptor->alias_1) PetscCall(PetscStrcasecmp(field_name, descriptor->alias_1, &match));
183 if (!match && descriptor->alias_2) PetscCall(PetscStrcasecmp(field_name, descriptor->alias_2, &match));
184 if (match) {
185 *field_id = descriptor->id;
186 PetscFunctionReturn(0);
187 }
188 }
189
190 *field_id = FIELD_ID_INVALID;
191 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE,
192 "Field name '%s' is not registered in the Eulerian field catalog.", field_name);
193}
194
195/**
196 * @brief Returns catalog-owned printable text for a field identity.
197 * @details Invalid enum values return a non-null diagnostic sentinel string.
198 * @see FieldCanonicalName()
199 */
200const char *FieldCanonicalName(FieldId field_id)
201{
202 if (field_id < 0 || field_id >= FIELD_ID_COUNT) return "InvalidField";
203 if (gFieldCatalog[field_id].id != field_id) return "InvalidField";
204 return gFieldCatalog[field_id].canonical_name;
205}
206
207/**
208 * @brief Converts layout metadata to the stable diagnostic label used by field loggers.
209 * @see FieldLayoutName()
210 */
211const char *FieldLayoutName(FieldLayout layout)
212{
213 switch (layout) {
214 case FIELD_LAYOUT_NODE_CENTERED: return "Node-Centered";
215 case FIELD_LAYOUT_CELL_CENTERED: return "Cell-Centered";
216 case FIELD_LAYOUT_I_FACE: return "I-Face";
217 case FIELD_LAYOUT_J_FACE: return "J-Face";
218 case FIELD_LAYOUT_K_FACE: return "K-Face";
219 case FIELD_LAYOUT_COMPONENT_STAGGERED: return "Component-Staggered";
220 default: return "Invalid-Layout";
221 }
222}
223
224/**
225 * @brief Binds one descriptor to the PETSc objects already owned by a UserCtx.
226 * @details Resolves DM and Vec handles without allocating, referencing, or
227 * destroying PETSc storage.
228 * @see FieldGetView()
229 */
230PetscErrorCode FieldGetView(UserCtx *user, FieldId field_id, FieldView *view)
231{
232 const FieldDescriptor *descriptor = NULL;
233
234 PetscFunctionBeginUser;
235 PetscCheck(user != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
236 "UserCtx cannot be NULL when resolving a field view.");
237 PetscCheck(view != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
238 "Field view output cannot be NULL.");
239 PetscCall(FieldGetDescriptor(field_id, &descriptor));
240
241 view->descriptor = descriptor;
242 view->dm = NULL;
243 view->global_vec = NULL;
244 view->local_vec = NULL;
245
246 switch (descriptor->dm_kind) {
247 case FIELD_DM_DA:
248 view->dm = user->da;
249 break;
250 case FIELD_DM_FDA:
251 view->dm = user->fda;
252 break;
253 case FIELD_DM_FDA2:
254 view->dm = user->fda2;
255 break;
257 view->dm = user->fda;
258 PetscCheck(user->da != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
259 "Coordinate DM is unavailable for field '%s'.", descriptor->canonical_name);
260 PetscCall(DMGetCoordinates(user->da, &view->global_vec));
261 PetscCall(DMGetCoordinatesLocal(user->da, &view->local_vec));
262 break;
263 default:
264 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB,
265 "Field '%s' has an invalid DM selector.", descriptor->canonical_name);
266 }
267
268 if (descriptor->dm_kind != FIELD_DM_COORDINATES) {
269 view->global_vec = *(Vec *)((char *)user + descriptor->global_vec_offset);
270 view->local_vec = *(Vec *)((char *)user + descriptor->local_vec_offset);
271 }
272
273 PetscCheck(view->dm != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
274 "DM for field '%s' is unavailable in this UserCtx.", descriptor->canonical_name);
275 PetscCheck(view->global_vec != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
276 "Global vector for field '%s' is unavailable in this UserCtx.", descriptor->canonical_name);
277 PetscCheck(view->local_vec != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
278 "Local vector for field '%s' is unavailable in this UserCtx.", descriptor->canonical_name);
279
280 PetscFunctionReturn(0);
281}
282
283#undef FIELD_COORDINATE_ENTRY
284#undef FIELD_ENTRY
285#undef FIELD_NO_VEC_OFFSET
PetscErrorCode FieldIdFromName(const char *field_name, FieldId *field_id)
Resolves a canonical field name or registered alias to a typed identity.
#define FIELD_ENTRY(field_id_, name_, alias1_, alias2_, dof_, dm_, layout_, sync_, availability_, capabilities_, global_member_, local_member_)
static const FieldDescriptor gFieldCatalog[FIELD_ID_COUNT]
const char * FieldCanonicalName(FieldId field_id)
Returns catalog-owned printable text for a field identity.
PetscErrorCode FieldGetView(UserCtx *user, FieldId field_id, FieldView *view)
Binds one descriptor to the PETSc objects already owned by a UserCtx.
const char * FieldLayoutName(FieldLayout layout)
Converts layout metadata to the stable diagnostic label used by field loggers.
#define FIELD_COORDINATE_ENTRY(field_id_, name_, dof_, layout_, capabilities_)
PetscErrorCode FieldGetDescriptor(FieldId field_id, const FieldDescriptor **descriptor)
Returns the immutable catalog descriptor for one typed field identity.
Authoritative identities and storage metadata for persistent Eulerian fields.
const char * alias_1
@ FIELD_CAPABILITY_GHOST_UPDATE
@ FIELD_CAPABILITY_PERIODIC_GEOMETRY_SHIFT
@ FIELD_CAPABILITY_PERIODIC_CELL_SYNC
@ FIELD_CAPABILITY_PERIODIC_FACE_SYNC
@ FIELD_CAPABILITY_PERIODIC_STAGGERED_SYNC
@ FIELD_AVAILABILITY_RANS
@ FIELD_AVAILABILITY_FINEST_LEVEL
@ FIELD_AVAILABILITY_LES
@ FIELD_AVAILABILITY_PARTICLES
@ FIELD_AVAILABILITY_TURBULENCE
@ FIELD_AVAILABILITY_ALWAYS
@ FIELD_SYNC_STANDARD
@ FIELD_SYNC_K_FACE
@ FIELD_SYNC_J_FACE
@ FIELD_SYNC_COMPONENT_STAGGERED
@ FIELD_SYNC_I_FACE
const FieldDescriptor * descriptor
FieldDMKind dm_kind
FieldLayout
Logical storage topology of a field.
@ FIELD_LAYOUT_K_FACE
@ FIELD_LAYOUT_I_FACE
@ FIELD_LAYOUT_CELL_CENTERED
@ FIELD_LAYOUT_COMPONENT_STAGGERED
@ FIELD_LAYOUT_NODE_CENTERED
@ FIELD_LAYOUT_J_FACE
const char * canonical_name
const char * alias_2
@ FIELD_DM_FDA2
@ FIELD_DM_FDA
@ FIELD_DM_COORDINATES
@ FIELD_DM_DA
FieldId
Compile-time identity for a catalogued Eulerian field.
@ FIELD_ID_PSI
@ FIELD_ID_JETA
@ FIELD_ID_CENTZ
@ FIELD_ID_CSI
@ FIELD_ID_IAJ
@ FIELD_ID_NVERT
@ FIELD_ID_UCAT
@ FIELD_ID_NVERT_O
@ FIELD_ID_KETA
@ FIELD_ID_JAJ
@ FIELD_ID_COORDINATES
@ FIELD_ID_UCONT_O
@ FIELD_ID_K_OMEGA
@ FIELD_ID_KAJ
@ FIELD_ID_AJ
@ FIELD_ID_NU_T
@ FIELD_ID_CENTY
@ FIELD_ID_GRID_SPACE
@ FIELD_ID_KZET
@ FIELD_ID_IETA
@ FIELD_ID_DIFFUSIVITY_GRADIENT
@ FIELD_ID_UCONT
@ FIELD_ID_ICSI
@ FIELD_ID_ETA
@ FIELD_ID_PHI
@ FIELD_ID_CS
@ FIELD_ID_CENT
@ FIELD_ID_JCSI
@ FIELD_ID_JZET
@ FIELD_ID_K_OMEGA_O
@ FIELD_ID_INVALID
@ FIELD_ID_P
@ FIELD_ID_IZET
@ FIELD_ID_UCONT_RM1
@ FIELD_ID_ZET
@ FIELD_ID_KCSI
@ FIELD_ID_CENTX
@ FIELD_ID_PARTICLE_COUNT
@ FIELD_ID_COUNT
@ FIELD_ID_DIFFUSIVITY
Immutable metadata for one field identity.
Non-owning runtime objects resolved for one field and UserCtx.
User-defined context containing data specific to a single computational grid level.
Definition variables.h:876