Bug Summary

File:fun3dAIM.c
Warning:line 2873, column 15
1st function call argument is an uninitialized value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name fun3dAIM.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -D REVISION=7.6 -D HAVE_PYTHON -I /home/jenkins/workspace/ESP_Stanalizer/LINUX64/CAPS/scan-build/ESP/LINUX64/include -I ../utils -I ../meshWriter/ugridWriter -I . -I /home/jenkins/util/ESP/Python/ESP_Python-3.8.9/include/python3.8 -I /home/jenkins/util/ESP/Python/ESP_Python-3.8.9/include/python3.8 -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-dangling-else -Wno-parentheses -Wno-unused-result -Wno-format-truncation -fdebug-compilation-dir /home/jenkins/workspace/ESP_Stanalizer/LINUX64/CAPS/scan-build/CAPS/aim/fun3d -ferror-limit 19 -fmessage-length 0 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/jenkins/workspace/ESP_Stanalizer/LINUX64/CAPS/scan-build/scanCAPS/2022-02-23-104636-127338-1 -x c fun3dAIM.c
1/*
2 * CAPS: Computational Aircraft Prototype Syntheses
3 *
4 * FUN3D AIM
5 *
6 * Written by Dr. Ryan Durscher AFRL/RQVC
7 *
8 * This software has been cleared for public release on 05 Nov 2020, case number 88ABW-2020-3462.
9 */
10
11
12/*!\mainpage Introduction
13 * \tableofcontents
14 * \section overviewFUN3D FUN3D AIM Overview
15 * A module in the Computational Aircraft Prototype Syntheses (CAPS) has been developed to interact (primarily
16 * through input files) with NASA LaRC's unstructured flow solver FUN3D \cite FUN3D. FUN3D is a parallelized flow analysis
17 * and design suite capable of addressing a wide variety of complex aerodynamic configurations by utilizing a
18 * mixed-element, node-based, finite volume discretization.
19 * The suite can simulate perfect gas (both incompressible and compressible), as well as multi-species
20 * equilibrium and non-equilibrium flows. Turbulence effects may be represented through a wide variety
21 * of models. Currently only a subset of FUN3D's input options have been exposed in the analysis interface
22 * module (AIM), but features can easily be included as future needs arise.
23 *
24 * Current issues include:
25 * - Not all parameters/variables in fun3d.nml are currently available.
26 *
27 * An outline of the AIM's inputs and outputs are provided in \ref aimInputsFUN3D and \ref aimOutputsFUN3D, respectively.
28 *
29 * Details on the use of units are outlined in \ref aimUnitsFUN3D.
30 *
31 * Details of the AIM's automated data transfer capabilities are outlined in \ref dataTransferFUN3D
32 *
33 *
34 * \section fun3dNML Generating fun3d.nml
35 * FUN3D's primarily input file is a master FORTRAN namelist, fun3d.nml. To generate a bare-bones fun3d.nml
36 * file based on the variables set in \ref aimInputsFUN3D, nothing else besides the AIM needs to be provided. Since
37 * this will create a new fun3d.nml file every time the AIM is executed it is essential to set
38 * the Overwrite\_NML input variable to "True". This gives the user ample warning that their fun3d.nml (if it exists)
39 * will be over written.
40 *
41 * Conversely, to read and append an existing namelist file the user needs Python installed so that the AIM may
42 * be complied against the Python API library (and header file - Python.h). The AIM interacts with Python through
43 * a Cython linked script that utilizes the "f90nml" Python module; note, having Cython installed is not
44 * required. On systems with "pip" installed typing "pip install f90nml", will download and install the "f90nml" module.
45 *
46 * The Cython script will first try to read an existing fun3d.nml file in the specified
47 * analysis directory; if the file does not exist one will be created. Only modified input variables that have been
48 * specified as AIM inputs (currently supported variables are outlined in \ref aimInputsFUN3D) are
49 * updated in the namelist file.
50 *
51 * \section fun3dExample Examples
52 * An example problem using the FUN3D AIM (coupled with a meshing AIM - TetGen) may be found at
53 * \ref fun3dTetgenExample.
54 *
55 * \section clearanceFUN3D Clearance Statement
56 * This software has been cleared for public release on 05 Nov 2020, case number 88ABW-2020-3462.
57 */
58
59#ifdef HAVE_PYTHON1
60
61#include "Python.h" // Bring in Python API
62
63#include "fun3dNamelist.h" // Bring in Cython generated header file
64// for namelist generation wiht Python
65
66#ifndef CYTHON_PEP489_MULTI_PHASE_INIT(((3 << 24) | (8 << 16) | (9 << 8) | (0xF <<
4) | (0 << 0)) >= 0x03050000)
67#define CYTHON_PEP489_MULTI_PHASE_INIT(((3 << 24) | (8 << 16) | (9 << 8) | (0xF <<
4) | (0 << 0)) >= 0x03050000)
(PY_VERSION_HEX((3 << 24) | (8 << 16) | (9 << 8) | (0xF <<
4) | (0 << 0))
>= 0x03050000)
68#endif
69
70#if CYTHON_PEP489_MULTI_PHASE_INIT(((3 << 24) | (8 << 16) | (9 << 8) | (0xF <<
4) | (0 << 0)) >= 0x03050000)
71static int fun3dNamelist_Initialized = (int)false0;
72#endif
73
74#endif
75
76#include <string.h>
77#include <math.h>
78#include "capsTypes.h"
79#include "aimUtil.h"
80#include "aimMesh.h"
81
82#include "meshUtils.h"
83#include "cfdUtils.h"
84#include "miscUtils.h"
85#include "fun3dUtils.h"
86#include "fun3dInputs.h"
87
88#include "ugridWriter.h"
89
90#ifdef WIN32
91#define snprintf _snprintf
92#define strcasecmp stricmp
93#endif
94
95/*
96#define CROSS(a,b,c) a[0] = (b[1]*c[2]) - (b[2]*c[1]);\
97 a[1] = (b[2]*c[0]) - (b[0]*c[2]);\
98 a[2] = (b[0]*c[1]) - (b[1]*c[0])
99#define DOT(a,b) (a[0]*b[0] + a[1]*b[1] + a[2]*b[2])
100 */
101
102enum aimOutputs
103{
104 // Total forces
105 CLtot = 1, /* index is 1-based */
106 CDtot ,
107 CMXtot,
108 CMYtot,
109 CMZtot,
110 CXtot ,
111 CYtot ,
112 CZtot ,
113 // Pressure Forces
114 CLtot_p ,
115 CDtot_p ,
116 CMXtot_p,
117 CMYtot_p,
118 CMZtot_p,
119 CXtot_p ,
120 CYtot_p ,
121 CZtot_p ,
122 // Viscous Forces
123 CLtot_v ,
124 CDtot_v ,
125 CMXtot_v,
126 CMYtot_v,
127 CMZtot_v,
128 CXtot_v ,
129 CYtot_v ,
130 CZtot_v ,
131 // Other
132 Forces,
133 NUMOUTPUT = Forces /* Total number of outputs */
134};
135
136//#define DEBUG
137
138
139typedef struct {
140
141 // Attribute to index map
142 mapAttrToIndexStruct groupMap;
143
144 // Pointer to CAPS input value for scaling pressure during data transfer
145 capsValue *pressureScaleFactor;
146
147 // Pointer to CAPS input value for offset pressure during data transfer
148 capsValue *pressureScaleOffset;
149
150 // Design information
151 cfdDesignStruct design;
152
153 // Units structure
154 cfdUnitsStruct units;
155
156} aimStorage;
157
158
159// ********************** Exposed AIM Functions *****************************
160
161int aimInitialize(int inst, /*@null@*/ /*@unused@*/ const char *unitSys, void *aimInfo,
162 void **instStore, /*@unused@*/ int *major,
163 /*@unused@*/ int *minor, int *nIn, int *nOut,
164 int *nFields, char ***fnames, int **franks, int **fInOut)
165{
166
167 int status = CAPS_SUCCESS0; // Function status return
168
169 int *ints=NULL((void*)0), i;
170 char **strs=NULL((void*)0);
171
172 const char *keyWord;
173 char *keyValue = NULL((void*)0);
174 double real = 1;
175 cfdUnitsStruct *units=NULL((void*)0);
176
177 aimStorage *fun3dInstance=NULL((void*)0);
178
179#ifdef DEBUG
180 printf("\n fun3dAIM/aimInitialize inst = %d!\n", inst);
181#endif
182
183 // Specify the number of analysis input and out "parameters"
184 *nIn = NUMINPUT;
185 *nOut = NUMOUTPUT;
186 if (inst == -1) return CAPS_SUCCESS0;
187
188 /* specify the field variables this analysis can generate and consume */
189 *nFields = 7;
190
191 /* specify the name of each field variable */
192 AIM_ALLOC(strs, *nFields, char *, aimInfo, status){ if (strs != ((void*)0)) { status = -4; aim_status(aimInfo, status
, "fun3dAIM.c", 192, __func__, 1, "AIM_ALLOC: %s != NULL", "strs"
); goto cleanup; } size_t memorysize = *nFields; strs = (char
* *) EG_alloc(memorysize*sizeof(char *)); if (strs == ((void
*)0)) { status = -4; aim_status(aimInfo, status, "fun3dAIM.c"
, 192, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "strs",
memorysize, "char *"); goto cleanup; } }
;
193 strs[0] = EG_strdup("Pressure");
194 strs[1] = EG_strdup("P");
195 strs[2] = EG_strdup("Cp");
196 strs[3] = EG_strdup("CoefficientOfPressure");
197 strs[4] = EG_strdup("Displacement");
198 strs[5] = EG_strdup("EigenVector");
199 strs[6] = EG_strdup("EigenVector_#");
200 for (i = 0; i < *nFields; i++)
201 if (strs[i] == NULL((void*)0)) {
202 status = EGADS_MALLOC-4;
203 goto cleanup;
204 }
205 *fnames = strs;
206
207 /* specify the dimension of each field variable */
208 AIM_ALLOC(ints, *nFields, int, aimInfo, status){ if (ints != ((void*)0)) { status = -4; aim_status(aimInfo, status
, "fun3dAIM.c", 208, __func__, 1, "AIM_ALLOC: %s != NULL", "ints"
); goto cleanup; } size_t memorysize = *nFields; ints = (int *
) EG_alloc(memorysize*sizeof(int)); if (ints == ((void*)0)) {
status = -4; aim_status(aimInfo, status, "fun3dAIM.c", 208, __func__
, 3, "AIM_ALLOC: %s size %zu type %s", "ints", memorysize, "int"
); goto cleanup; } }
;
209
210 ints[0] = 1;
211 ints[1] = 1;
212 ints[2] = 1;
213 ints[3] = 1;
214 ints[4] = 3;
215 ints[5] = 3;
216 ints[6] = 3;
217 *franks = ints;
218 ints = NULL((void*)0);
219
220 /* specify if a field is an input field or output field */
221 AIM_ALLOC(ints, *nFields, int, aimInfo, status){ if (ints != ((void*)0)) { status = -4; aim_status(aimInfo, status
, "fun3dAIM.c", 221, __func__, 1, "AIM_ALLOC: %s != NULL", "ints"
); goto cleanup; } size_t memorysize = *nFields; ints = (int *
) EG_alloc(memorysize*sizeof(int)); if (ints == ((void*)0)) {
status = -4; aim_status(aimInfo, status, "fun3dAIM.c", 221, __func__
, 3, "AIM_ALLOC: %s size %zu type %s", "ints", memorysize, "int"
); goto cleanup; } }
;
222
223 ints[0] = FieldOut;
224 ints[1] = FieldOut;
225 ints[2] = FieldOut;
226 ints[3] = FieldOut;
227 ints[4] = FieldIn;
228 ints[5] = FieldIn;
229 ints[6] = FieldIn;
230 *fInOut = ints;
231 ints = NULL((void*)0);
232
233
234 // Allocate fun3dInstance
235 AIM_ALLOC(fun3dInstance, 1, aimStorage, aimInfo, status){ if (fun3dInstance != ((void*)0)) { status = -4; aim_status(
aimInfo, status, "fun3dAIM.c", 235, __func__, 1, "AIM_ALLOC: %s != NULL"
, "fun3dInstance"); goto cleanup; } size_t memorysize = 1; fun3dInstance
= (aimStorage *) EG_alloc(memorysize*sizeof(aimStorage)); if
(fun3dInstance == ((void*)0)) { status = -4; aim_status(aimInfo
, status, "fun3dAIM.c", 235, __func__, 3, "AIM_ALLOC: %s size %zu type %s"
, "fun3dInstance", memorysize, "aimStorage"); goto cleanup; }
}
;
236 *instStore = fun3dInstance;
237
238 // Container for attribute to index map
239 status = initiate_mapAttrToIndexStruct(&fun3dInstance->groupMap);
240 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 240
, __func__, 0); goto cleanup; }
;
241
242 // Pointer to caps input value for scaling pressure during data transfer
243 fun3dInstance->pressureScaleFactor = NULL((void*)0);
244
245 // Pointer to caps input value for off setting pressure during data transfer
246 fun3dInstance->pressureScaleOffset = NULL((void*)0);
247
248 // Design information
249 status = initiate_cfdDesignStruct(&fun3dInstance->design);
250 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 250
, __func__, 0); goto cleanup; }
;
251
252 initiate_cfdUnitsStruct(&fun3dInstance->units);
253
254 /*! \page aimUnitsFUN3D AIM Units
255 * A unit system may be optionally specified during AIM instance initiation. If
256 * a unit system is provided, all AIM input values which have associated units must be specified as well.
257 * If no unit system is used, AIM inputs, which otherwise would require units, will be assumed
258 * unit consistent. A unit system may be specified via a JSON string dictionary for example:
259 * unitSys = "{"temperature": "Kelvin"}"
260 */
261 if (unitSys != NULL((void*)0)) {
262 units = &fun3dInstance->units;
263
264 // Do we have a json string?
265 if (strncmp( unitSys, "{", 1) != 0) {
266 AIM_ERROR(aimInfo, "unitSys ('%s') is expected to be a JSON string dictionary", unitSys){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 266, __func__
, "unitSys ('%s') is expected to be a JSON string dictionary"
, unitSys); }
;
267 return CAPS_BADVALUE-311;
268 }
269
270 /*! \page aimUnitsFUN3D
271 * <ul>
272 * <li> <B>temperature = "None"</B> </li> <br>
273 * Temperature units - e.g. "Kelvin", "Rankin" ...
274 * </ul>
275 */
276 keyWord = "temperature";
277 status = search_jsonDictionary(unitSys, keyWord, &keyValue);
278 if (status == CAPS_SUCCESS0) {
279 units->temperature = string_removeQuotation(keyValue);
280 AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); };
281 real = 1;
282 status = aim_convert(aimInfo, 1, units->temperature, &real, "Kelvin", &real);
283 AIM_STATUS(aimInfo, status, "unitSys ('%s'): %s is not a %s unit", unitSys, units->temperature, keyWord)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 283
, __func__, 4, "unitSys ('%s'): %s is not a %s unit", unitSys
, units->temperature, keyWord); goto cleanup; }
;
284 } else {
285 AIM_ERROR(aimInfo, "unitSys ('%s') does not contain '%s'", unitSys, keyWord){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 285, __func__
, "unitSys ('%s') does not contain '%s'", unitSys, keyWord); }
;
286 status = CAPS_BADVALUE-311;
287 goto cleanup;
288 }
289
290// status = cfd_cfdDerivedUnits(aimInfo, units);
291// AIM_STATUS(aimInfo, status);
292 }
293
294cleanup:
295 if (status != CAPS_SUCCESS0) {
296 /* release all possibly allocated memory on error */
297 if (*fnames != NULL((void*)0))
298 for (i = 0; i < *nFields; i++) AIM_FREE((*fnames)[i]){ EG_free((*fnames)[i]); (*fnames)[i] = ((void*)0); };
299 AIM_FREE(*franks){ EG_free(*franks); *franks = ((void*)0); };
300 AIM_FREE(*fInOut){ EG_free(*fInOut); *fInOut = ((void*)0); };
301 AIM_FREE(*fnames){ EG_free(*fnames); *fnames = ((void*)0); };
302 AIM_FREE(*instStore){ EG_free(*instStore); *instStore = ((void*)0); };
303 *nFields = 0;
304 }
305
306 return status;
307}
308
309
310int aimInputs(void *instStore, /*@unused@*/ void *aimInfo, int index,
311 char **ainame, capsValue *defval)
312{
313 /*! \page aimInputsFUN3D AIM Inputs
314 * The following list outlines the FUN3D inputs along with their default values available
315 * through the AIM interface. One will note most of the FUN3D parameters have a NULL value as their default.
316 * This is done since a parameter in the FUN3D input deck (fun3d.nml) is only changed if the value has
317 * been changed in CAPS (i.e. set to something other than NULL).
318 */
319
320 int status = CAPS_SUCCESS0;
321 aimStorage *fun3dInstance;
322 cfdUnitsStruct *units=NULL((void*)0);
323
324#ifdef DEBUG
325 printf(" fun3dAIM/aimInputs index = %d!\n", index);
326#endif
327 fun3dInstance = (aimStorage *) instStore;
328 if (fun3dInstance == NULL((void*)0)) return CAPS_NULLVALUE-307;
329
330 units = &fun3dInstance->units;
331
332 *ainame = NULL((void*)0);
333
334 // FUN3D Inputs
335 if (index == Proj_Name) {
336 *ainame = EG_strdup("Proj_Name");
337 defval->type = String;
338 defval->nullVal = NotNull;
339 defval->vals.string = EG_strdup("fun3d_CAPS");
340 defval->lfixed = Change;
341
342 /*! \page aimInputsFUN3D
343 * - <B> Proj_Name = "fun3d_CAPS"</B> <br>
344 * This corresponds to the project\_rootname variable in the \&project namelist of fun3d.nml.
345 */
346 } else if (index == Mach) {
347 *ainame = EG_strdup("Mach"); // Mach number
348 defval->type = Double;
349 defval->nullVal = IsNull;
350 defval->units = NULL((void*)0);
351 defval->lfixed = Change;
352 defval->dim = Scalar;
353
354 /*! \page aimInputsFUN3D
355 * - <B> Mach = NULL </B> <br>
356 * This corresponds to the mach\_number variable in the \&reference\_physical\_properties
357 * namelist of fun3d.nml.
358 */
359 } else if (index == Re) {
360 *ainame = EG_strdup("Re"); // Reynolds number
361 defval->type = Double;
362 defval->nullVal = IsNull;
363 defval->units = NULL((void*)0);
364 defval->lfixed = Change;
365 defval->dim = Scalar;
366
367 /*! \page aimInputsFUN3D
368 * - <B> Re = NULL </B> <br>
369 * This corresponds to the reynolds\_number variable in the \&reference\_physical\_properties
370 * namelist of fun3d.nml.
371 */
372 } else if (index == Reference_Temperature) {
373 *ainame = EG_strdup("Temperature"); //
374 defval->type = Double;
375 defval->nullVal = IsNull;
376 defval->units = NULL((void*)0);
377 defval->lfixed = Change;
378 defval->dim = Scalar;
379 if (units != NULL((void*)0) && units->temperature != NULL((void*)0)) {
380 AIM_STRDUP(defval->units, units->temperature, aimInfo, status){ if (defval->units != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "fun3dAIM.c", 380, __func__, 1, "AIM_STRDUP: %s != NULL!"
, "defval->units"); goto cleanup; } defval->units = EG_strdup
(units->temperature); if (defval->units == ((void*)0)) {
status = -4; aim_status(aimInfo, status, "fun3dAIM.c", 380, __func__
, 2, "AIM_STRDUP: %s %s", "defval->units", units->temperature
); goto cleanup; } }
;
381 }
382
383
384 /*! \page aimInputsFUN3D
385 * - <B> Temperature = NULL </B> <br>
386 * This corresponds to the temperature variable in the \&reference\_physical\_properties
387 * namelist of fun3d.nml. Note if no temperature units are set, units of Kelvin are assumed (see \ref aimUnitsFUN3D)
388 */
389 } else if (index == Viscoux) {
390 *ainame = EG_strdup("Viscous"); // Viscous term
391 defval->type = String;
392 defval->vals.string = NULL((void*)0);
393 defval->nullVal = IsNull;
394 defval->units = NULL((void*)0);
395 defval->lfixed = Change;
396 defval->dim = Scalar;
397
398 /*! \page aimInputsFUN3D
399 * - <B> Viscous = NULL </B> <br>
400 * This corresponds to the viscous\_terms variable in the \&governing\_equation namelist
401 * of fun3d.nml.
402 */
403 } else if (index == Equation_Type) {
404 *ainame = EG_strdup("Equation_Type"); // Equation type
405 defval->type = String;
406 defval->vals.string = NULL((void*)0);
407 defval->nullVal = IsNull;
408 defval->units = NULL((void*)0);
409 defval->lfixed = Change;
410
411 /*! \page aimInputsFUN3D
412 * - <B> Equation_Type = NULL </B> <br>
413 * This corresponds to the eqn\_type variable in the \&governing\_equation namelist of
414 * fun3d.nml.
415 */
416 } else if (index == Alpha) {
417 *ainame = EG_strdup("Alpha");
418 defval->type = Double;
419 defval->nullVal = IsNull;
420 defval->units = NULL((void*)0);
421 defval->lfixed = Change;
422 defval->dim = Scalar;
423 //defval->units = EG_strdup("degree");
424
425 /*! \page aimInputsFUN3D
426 * - <B> Alpha = NULL </B> <br>
427 * This corresponds to the angle\_of\_attack variable in the \&reference\_physical\_properties
428 * namelist of fun3d.nml [degree].
429 */
430 } else if (index == Beta) {
431 *ainame = EG_strdup("Beta");
432 defval->type = Double;
433 defval->nullVal = IsNull;
434 defval->units = NULL((void*)0);
435 defval->lfixed = Change;
436 defval->dim = Scalar;
437 //defval->units = EG_strdup("degree");
438
439 /*! \page aimInputsFUN3D
440 * - <B> Beta = NULL </B> <br>
441 * This corresponds to the angle\_of\_yaw variable in the \&reference\_physical\_properties
442 * namelist of fun3d.nml [degree].
443 */
444 } else if (index == Overwrite_NML) {
445 *ainame = EG_strdup("Overwrite_NML");
446 defval->type = Boolean;
447 defval->vals.integer = false0;
448 defval->nullVal = NotNull;
449
450 /*! \page aimInputsFUN3D
451 * - <B> Overwrite_NML = NULL</B> <br>
452 * - If Python is NOT linked with the FUN3D AIM at compile time or Use_Python_NML is set to False
453 * this flag gives the AIM permission to overwrite fun3d.nml if present.
454 * The namelist produced will solely consist of input variables present and set in the AIM.
455 *
456 * - If Python IS linked with the FUN3D AIM at compile time and Use_Python_NML is set to True the
457 * namelist file will be overwritten, as opposed to being appended.
458 *
459 */
460 } else if (index == Mesh_Format) {
461 *ainame = EG_strdup("Mesh_Format");
462 defval->type = String;
463 defval->vals.string = EG_strdup("AFLR3");
464 defval->lfixed = Change;
465
466 /*! \page aimInputsFUN3D
467 * - <B>Mesh_Format = "AFLR3"</B> <br>
468 * Mesh output format. By default, an AFLR3 mesh will be used.
469 */
470 } else if (index == Mesh_ASCII_Flag) {
471 *ainame = EG_strdup("Mesh_ASCII_Flag");
472 defval->type = Boolean;
473 defval->vals.integer = true1;
474
475 /*! \page aimInputsFUN3D
476 * - <B>Mesh_ASCII_Flag = True</B> <br>
477 * Output mesh in ASCII format, otherwise write a binary file if applicable.
478 */
479 } else if (index == Num_Iter) {
480 *ainame = EG_strdup("Num_Iter");
481 defval->type = Integer;
482 defval->nullVal = IsNull;
483 defval->units = NULL((void*)0);
484 defval->lfixed = Change;
485 defval->dim = Scalar;
486
487 /*! \page aimInputsFUN3D
488 * - <B>Num_Iter = NULL</B> <br>
489 * This corresponds to the steps variable in the \&code\_run\_control
490 * namelist of fun3d.nml.
491 */
492 } else if (index == CFL_Schedule) {
493 *ainame = EG_strdup("CFL_Schedule");
494 defval->type = Double;
495 defval->dim = Vector;
496 defval->nrow = 2;
497 defval->ncol = 1;
498 defval->units = NULL((void*)0);
499 defval->nullVal = IsNull;
500 defval->lfixed = Fixed;
501
502 AIM_ALLOC(defval->vals.reals, defval->nrow, double, aimInfo, status){ if (defval->vals.reals != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "fun3dAIM.c", 502, __func__, 1, "AIM_ALLOC: %s != NULL"
, "defval->vals.reals"); goto cleanup; } size_t memorysize
= defval->nrow; defval->vals.reals = (double *) EG_alloc
(memorysize*sizeof(double)); if (defval->vals.reals == ((void
*)0)) { status = -4; aim_status(aimInfo, status, "fun3dAIM.c"
, 502, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "defval->vals.reals"
, memorysize, "double"); goto cleanup; } }
;
503 defval->vals.reals[0] = defval->vals.reals[1] = 0.0;
504
505 /*! \page aimInputsFUN3D
506 * - <B>CFL_Schedule = NULL</B> <br>
507 * This corresponds to the schedule\_cfl variable in the \&nonlinear\_solver\_parameters
508 * namelist of fun3d.nml.
509 */
510 } else if (index == CFL_Schedule_Iter) {
511 *ainame = EG_strdup("CFL_Schedule_Iter");
512 defval->type = Integer;
513 defval->dim = Vector;
514 defval->nrow = 2;
515 defval->ncol = 1;
516 defval->units = NULL((void*)0);
517 defval->nullVal = IsNull;
518 defval->lfixed = Fixed;
519
520 AIM_ALLOC(defval->vals.integers, defval->nrow, int, aimInfo, status){ if (defval->vals.integers != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "fun3dAIM.c", 520, __func__, 1, "AIM_ALLOC: %s != NULL"
, "defval->vals.integers"); goto cleanup; } size_t memorysize
= defval->nrow; defval->vals.integers = (int *) EG_alloc
(memorysize*sizeof(int)); if (defval->vals.integers == ((void
*)0)) { status = -4; aim_status(aimInfo, status, "fun3dAIM.c"
, 520, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "defval->vals.integers"
, memorysize, "int"); goto cleanup; } }
;
521 defval->vals.integers[0] = defval->vals.integers[1] = 0;
522
523 /*! \page aimInputsFUN3D
524 * - <B>CFL_Schedule_Inter = NULL</B> <br>
525 * This corresponds to the schedule\_iteration variable in the \&nonlinear\_solver\_parameters
526 * namelist of fun3d.nml.
527 */
528 } else if (index == Restart_Read) {
529 *ainame = EG_strdup("Restart_Read");
530 defval->type = String;
531 defval->vals.string = NULL((void*)0);
532 defval->nullVal = IsNull;
533 defval->units = NULL((void*)0);
534 defval->lfixed = Change;
535
536 /*! \page aimInputsFUN3D
537 * - <B>Restart_Read = NULL</B> <br>
538 * This corresponds to the restart_read variable in the \&code_run_control namelist of fun3d.nml.
539 */
540 } else if (index == Boundary_Condition) {
541 *ainame = EG_strdup("Boundary_Condition");
542 defval->type = Tuple;
543 defval->nullVal = IsNull;
544 //defval->units = NULL;
545 defval->dim = Vector;
546 defval->lfixed = Change;
547 defval->vals.tuple = NULL((void*)0);
548
549 /*! \page aimInputsFUN3D
550 * - <B>Boundary_Condition = NULL </B> <br>
551 * See \ref cfdBoundaryConditions for additional details.
552 */
553 } else if (index == Use_Python_NML) {
554 *ainame = EG_strdup("Use_Python_NML");
555 defval->type = Boolean;
556 defval->vals.integer = (int) false0;
557
558 /*! \page aimInputsFUN3D
559 * - <B>Use_Python_NML = False </B> <br>
560 * By default, even if Python has been linked to the FUN3D AIM it is not used unless the this value is set to True.
561 */
562 } else if (index == Pressure_Scale_Factor) {
563 *ainame = EG_strdup("Pressure_Scale_Factor");
564 defval->type = Double;
565 defval->vals.real = 1.0;
566 defval->units = NULL((void*)0);
567
568 fun3dInstance->pressureScaleFactor = defval;
569
570 /*! \page aimInputsFUN3D
571 * - <B>Pressure_Scale_Factor = 1.0</B> <br>
572 * Value to scale Cp data when transferring data. Data is scaled based on Pressure = Pressure_Scale_Factor*Cp + Pressure_Scale_Offset.
573 */
574 } else if (index == Pressure_Scale_Offset) {
575 *ainame = EG_strdup("Pressure_Scale_Offset");
576 defval->type = Double;
577 defval->vals.real = 0.0;
578 defval->units = NULL((void*)0);
579
580 fun3dInstance->pressureScaleOffset = defval;
581
582 /*! \page aimInputsFUN3D
583 * - <B>Pressure_Scale_Offset = 0.0</B> <br>
584 * Value to offset Cp data when transferring data. Data is scaled based on Pressure = Pressure_Scale_Factor*Cp + Pressure_Scale_Offset.
585 */
586 } else if (index == NonInertial_Rotation_Rate) {
587 *ainame = EG_strdup("NonInertial_Rotation_Rate");
588 defval->type = Double;
589 defval->dim = Vector;
590 defval->nrow = 3;
591 defval->ncol = 1;
592 defval->units = NULL((void*)0);
593 defval->vals.reals = (double *) EG_alloc(defval->nrow*sizeof(double));
594 if (defval->vals.reals == NULL((void*)0)) {
595 return EGADS_MALLOC-4;
596 } else {
597 defval->vals.reals[0] = 0.0;
598 defval->vals.reals[1] = 0.0;
599 defval->vals.reals[2] = 0.0;
600 }
601 defval->nullVal = IsNull;
602 defval->lfixed = Fixed;
603
604 /*! \page aimInputsFUN3D
605 * - <B>NonInertial_Rotation_Rate = NULL [0.0, 0.0, 0.0]</B> <br>
606 * Array values correspond to the rotation\_rate\_x, rotation\_rate\_y, rotation\_rate\_z variables, respectively,
607 * in the \&noninertial\_reference\_frame namelist of fun3d.nml.
608 */
609 } else if (index == NonInertial_Rotation_Center) {
610 *ainame = EG_strdup("NonInertial_Rotation_Center");
611 defval->type = Double;
612 defval->dim = Vector;
613 defval->nrow = 3;
614 defval->ncol = 1;
615 defval->units = NULL((void*)0);
616 defval->vals.reals = (double *) EG_alloc(defval->nrow*sizeof(double));
617 if (defval->vals.reals == NULL((void*)0)) {
618 return EGADS_MALLOC-4;
619 } else {
620 defval->vals.reals[0] = 0.0;
621 defval->vals.reals[1] = 0.0;
622 defval->vals.reals[2] = 0.0;
623 }
624 defval->nullVal = IsNull;
625 defval->lfixed = Fixed;
626
627 /*! \page aimInputsFUN3D
628 * - <B>NonInertial_Rotation_Center = NULL, [0.0, 0.0, 0.0]</B> <br>
629 * Array values correspond to the rotation\_center\_x, rotation\_center\_y, rotation\_center\_z variables, respectively,
630 * in the \&noninertial\_reference\_frame namelist of fun3d.nml.
631 */
632 } else if (index == Two_Dimensional) {
633 *ainame = EG_strdup("Two_Dimensional");
634 defval->type = Boolean;
635 defval->vals.integer = (int) false0;
636
637 /*! \page aimInputsFUN3D
638 * - <B>Two_Dimensional = False</B> <br>
639 * Run FUN3D in 2D mode. If set to True, the body must be a single "sheet" body in the x-z plane (a rudimentary node
640 * swapping routine is attempted if not in the x-z plane). A 3D mesh will be written out,
641 * where the body is extruded a length of 1 in the y-direction.
642 */
643 } else if (index == Modal_Aeroelastic) {
644 *ainame = EG_strdup("Modal_Aeroelastic");
645 defval->type = Tuple;
646 defval->nullVal = IsNull;
647 //defval->units = NULL;
648 defval->dim = Vector;
649 defval->lfixed = Change;
650 defval->vals.tuple = NULL((void*)0);
651
652 /*! \page aimInputsFUN3D
653 * - <B>Modal_Aeroelastic = NULL </B> <br>
654 * See \ref cfdModalAeroelastic for additional details.
655 */
656 } else if (index == Modal_Ref_Velocity) {
657 *ainame = EG_strdup("Modal_Ref_Velocity");
658 defval->type = Double;
659 defval->nullVal = IsNull;
660 //defval->units = NULL;
661 defval->dim = Scalar;
662 defval->lfixed = Change;
663
664 /*! \page aimInputsFUN3D
665 * - <B>Modal_Ref_Velocity = NULL </B> <br>
666 * The freestream velocity in structural dynamics equation units; used for scaling during modal
667 * aeroelastic simulations. This corresponds to the uinf variable in the \&aeroelastic\_modal\_data
668 * namelist of movingbody.input.
669 */
670 } else if (index == Modal_Ref_Length) {
671 *ainame = EG_strdup("Modal_Ref_Length");
672 defval->type = Double;
673 //defval->units = NULL;
674 defval->dim = Scalar;
675 defval->lfixed = Change;
676 defval->vals.real = 1.0;
677
678 /*! \page aimInputsFUN3D
679 * - <B>Modal_Ref_Length = 1.0 </B> <br>
680 * The scaling factor between CFD and the structural dynamics equation units; used for scaling during modal
681 * aeroelastic simulations. This corresponds to the grefl variable in the \&aeroelastic\_modal\_data
682 * namelist of movingbody.input.
683 */
684 } else if (index == Modal_Ref_Dynamic_Pressure) {
685 *ainame = EG_strdup("Modal_Ref_Dynamic_Pressure");
686 defval->type = Double;
687 defval->nullVal = IsNull;
688 //defval->units = NULL;
689 defval->lfixed = Change;
690 defval->dim = Scalar;
691
692 /*! \page aimInputsFUN3D
693 * - <B>Modal_Ref_Dynamic_Pressure = NULL </B> <br>
694 * The freestream dynamic pressure in structural dynamics equation units; used for scaling during modal
695 * aeroelastic simulations. This corresponds to the qinf variable in the \&aeroelastic\_modal\_data
696 * namelist of movingbody.input.
697 */
698 } else if (index == Time_Accuracy) {
699 *ainame = EG_strdup("Time_Accuracy");
700 defval->type = String;
701 defval->vals.string = NULL((void*)0);
702 defval->nullVal = IsNull;
703 defval->units = NULL((void*)0);
704 defval->lfixed = Change;
705
706 /*! \page aimInputsFUN3D
707 * - <B>Time_Accuracy = NULL </B> <br>
708 * Defines the temporal scheme to use. This corresponds to the time_accuracy variable
709 * in the \&nonlinear_solver_parameters namelist of fun3d.nml.
710 */
711 } else if (index == Time_Step) {
712 *ainame = EG_strdup("Time_Step");
713 defval->type = Double;
714 defval->nullVal = IsNull;
715 defval->units = NULL((void*)0);
716 defval->lfixed = Change;
717 defval->dim = Scalar;
718
719 /*! \page aimInputsFUN3D
720 * - <B>Time_Step = NULL </B> <br>
721 * Non-dimensional time step during time accurate simulations. This corresponds to the time_step_nondim
722 * variable in the \&nonlinear_solver_parameters namelist of fun3d.nml.
723 */
724 } else if (index == Num_Subiter) {
725 *ainame = EG_strdup("Num_Subiter");
726 defval->type = Integer;
727 defval->nullVal = IsNull;
728 defval->units = NULL((void*)0);
729 defval->lfixed = Change;
730 defval->dim = Scalar;
731
732 /*! \page aimInputsFUN3D
733 * - <B>Num_Subiter = NULL </B> <br>
734 * Number of subiterations used during a time step in a time accurate simulations. This
735 * corresponds to the subiterations variable in the \&nonlinear_solver_parameters namelist of fun3d.nml.
736 */
737 } else if (index == Temporal_Error) {
738 *ainame = EG_strdup("Temporal_Error");
739 defval->type = Double;
740 defval->nullVal = IsNull;
741 defval->units = NULL((void*)0);
742 defval->lfixed = Change;
743 defval->dim = Scalar;
744
745 /*! \page aimInputsFUN3D
746 * - <B>Temporal_Error = NULL </B> <br>
747 * This sets the tolerance for which subiterations are stopped during time accurate simulations. This
748 * corresponds to the temporal_err_floor variable in the \&nonlinear_solver_parameters namelist of fun3d.nml.
749 */
750 } else if (index == Reference_Area) {
751 *ainame = EG_strdup("Reference_Area");
752 defval->type = Double;
753 defval->nullVal = IsNull;
754 defval->units = NULL((void*)0);
755 defval->lfixed = Change;
756 defval->dim = Scalar;
757 defval->vals.real = 0.0;
758
759 /*! \page aimInputsFUN3D
760 * - <B>Reference_Area = NULL </B> <br>
761 * This sets the reference area for used in force and moment calculations. This
762 * corresponds to the area_reference variable in the \&force_moment_integ_properties namelist of fun3d.nml.
763 * Alternatively, the geometry (body) attribute "capsReferenceArea" maybe used to specify this variable
764 * (note: values set through the AIM input will supersede the attribution value).
765 */
766 } else if (index == Moment_Length) {
767 *ainame = EG_strdup("Moment_Length");
768 defval->type = Double;
769 defval->dim = Vector;
770 defval->nrow = 2;
771 defval->ncol = 1;
772 defval->units = NULL((void*)0);
773 defval->vals.reals = (double *) EG_alloc(defval->nrow*sizeof(double));
774 if (defval->vals.reals == NULL((void*)0)) {
775 return EGADS_MALLOC-4;
776 } else {
777 defval->vals.reals[0] = 0.0;
778 defval->vals.reals[1] = 0.0;
779 }
780 defval->nullVal = IsNull;
781 defval->lfixed = Fixed;
782
783 /*! \page aimInputsFUN3D
784 * - <B>Moment_Length = NULL, [0.0, 0.0]</B> <br>
785 * Array values correspond to the x_moment_length and y_moment_length variables,
786 * respectively, in the \&force_moment_integ_properties namelist of fun3d.nml.
787 * Alternatively, the geometry (body) attributes "capsReferenceChord" and "capsReferenceSpan" may be
788 * used to specify the x- and y- moment lengths, respectively (note: values set through
789 * the AIM input will supersede the attribution values).
790 */
791 } else if (index == Moment_Center) {
792 *ainame = EG_strdup("Moment_Center");
793 defval->type = Double;
794 defval->dim = Vector;
795 defval->nrow = 3;
796 defval->ncol = 1;
797 defval->units = NULL((void*)0);
798 defval->vals.reals = (double *) EG_alloc(defval->nrow*sizeof(double));
799 if (defval->vals.reals == NULL((void*)0)) {
800 return EGADS_MALLOC-4;
801 } else {
802 defval->vals.reals[0] = 0.0;
803 defval->vals.reals[1] = 0.0;
804 defval->vals.reals[2] = 0.0;
805 }
806 defval->nullVal = IsNull;
807 defval->lfixed = Fixed;
808
809 /*! \page aimInputsFUN3D
810 * - <B>Moment_Center = NULL, [0.0, 0.0, 0.0]</B> <br>
811 * Array values correspond to the x_moment_center, y_moment_center, and z_moment_center variables,
812 * respectively, in the \&force_moment_integ_properties namelist of fun3d.nml.
813 * Alternatively, the geometry (body) attributes "capsReferenceX", "capsReferenceY",
814 * and "capsReferenceZ" may be used to specify the x-, y-, and z- moment centers, respectively
815 * (note: values set through the AIM input will supersede the attribution values).
816 */
817 } else if (index == FUN3D_Version) {
818 *ainame = EG_strdup("FUN3D_Version");
819 defval->type = Double;
820 defval->dim = Scalar;
821 defval->units = NULL((void*)0);
822 defval->vals.real = 13.1;
823 defval->lfixed = Fixed;
824
825 /*! \page aimInputsFUN3D
826 * - <B>FUN3D_Version = 13.1 </B> <br>
827 * FUN3D version to generate specific configuration file for; currently only has influence over
828 * rubber.data (sensitivity file) and aeroelastic modal data namelist in moving_body.input .
829 */
830 } else if (index == Design_Variable) {
831 *ainame = EG_strdup("Design_Variable");
832 defval->type = Tuple;
833 defval->nullVal = IsNull;
834 defval->lfixed = Change;
835 defval->vals.tuple = NULL((void*)0);
836 defval->dim = Vector;
837
838 /*! \page aimInputsFUN3D
839 * - <B> Design_Variable = NULL</B> <br>
840 * List of AnalysisIn and/or GeometryIn variable names used to compute sensitivities of Design_Functional for optimization, see \ref cfdDesignVariable for additional details.
841 */
842 } else if (index == Design_Functional) {
843 *ainame = EG_strdup("Design_Functional");
844 defval->type = Tuple;
845 defval->nullVal = IsNull;
846 defval->lfixed = Change;
847 defval->vals.tuple = NULL((void*)0);
848 defval->dim = Vector;
849
850 /*! \page aimInputsFUN3D
851 * - <B> Design_Functional = NULL</B> <br>
852 * The design functional tuple is used to input functional information for optimization, see \ref cfdDesignFunctional for additional details.
853 * Using this requires Design_SensFile = False.
854 */
855 } else if (index == Design_SensFile) {
856 *ainame = EG_strdup("Design_SensFile");
857 defval->type = Boolean;
858 defval->lfixed = Fixed;
859 defval->vals.integer = (int)false0;
860 defval->dim = Scalar;
861 defval->nullVal = NotNull;
862
863 /*! \page aimInputsFUN3D
864 * - <B> Design_SensFile = False</B> <br>
865 * Read <Proj_Name>.sens file to compute functional sensitivities w.r.t Design_Variable.
866 * Using this requires Design_Functional = NULL.
867 */
868 } else if (index == Design_Sensitivity) {
869 *ainame = EG_strdup("Design_Sensitivity");
870 defval->type = Boolean;
871 defval->lfixed = Fixed;
872 defval->vals.integer = (int)false0;
873 defval->dim = Scalar;
874 defval->nullVal = NotNull;
875
876 /*! \page aimInputsFUN3D
877 * - <B> Design_Sensitivity = False</B> <br>
878 * If True and Design_Functional is set, create geometric sensitivities Fun3D input files needed to compute Design_Functional sensitivities w.r.t Design_Variable.
879 * If True and Design_SensFile = True, read functional sensitivities from <Proj_Name>.sens and compute sensitivities w.r.t Design_Variable.
880 * The value of the design functionals become available as Dynamic Output Value Objects using the "name" of the functionals.
881 */
882 } else if (index == Mesh) {
883 *ainame = AIM_NAME(Mesh)EG_strdup("Mesh");
884 defval->type = PointerMesh;
885 defval->nrow = 1;
886 defval->lfixed = Fixed;
887 defval->vals.AIMptr = NULL((void*)0);
888 defval->nullVal = IsNull;
889 AIM_STRDUP(defval->meshWriter, MESHWRITER, aimInfo, status){ if (defval->meshWriter != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "fun3dAIM.c", 889, __func__, 1, "AIM_STRDUP: %s != NULL!"
, "defval->meshWriter"); goto cleanup; } defval->meshWriter
= EG_strdup("ugridWriter"); if (defval->meshWriter == ((void
*)0)) { status = -4; aim_status(aimInfo, status, "fun3dAIM.c"
, 889, __func__, 2, "AIM_STRDUP: %s %s", "defval->meshWriter"
, "ugridWriter"); goto cleanup; } }
;
890
891 /*! \page aimInputsFUN3D
892 * - <B>Mesh = NULL</B> <br>
893 * A Area_Mesh or Volume_Mesh link for 2D and 3D calculations respectively.
894 */
895
896 } else {
897 status = CAPS_BADINDEX-304;
898 AIM_STATUS(aimInfo, status, "Unknown input index %d!", index)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 898
, __func__, 2, "Unknown input index %d!", index); goto cleanup
; }
;
899 }
900
901 AIM_NOTNULL(*ainame, aimInfo, status){ if (*ainame == ((void*)0)) { status = -307; aim_status(aimInfo
, status, "fun3dAIM.c", 901, __func__, 1, "%s == NULL!", "*ainame"
); goto cleanup; } }
;
902
903cleanup:
904 if (status != CAPS_SUCCESS0) AIM_FREE(*ainame){ EG_free(*ainame); *ainame = ((void*)0); };
905 return status;
906}
907
908
909int aimPreAnalysis(void *instStore, void *aimInfo, capsValue *aimInputs)
910{
911 // Function return flag
912 int status;
913
914 // Python linking
915 int pythonLinked = (int) false0;
916 int usePython = (int) false0;
917
918 // Indexing
919 int i, body;
920
921 int attrLevel = 0;
922
923 // EGADS return values
924 int atype, alen;
925 const int *ints;
926 const char *string, *intents;
927 const double *reals;
928
929 // Output filename
930 char filename[PATH_MAX4096];
931 char gridfile[PATH_MAX4096];
932 const char *projectName=NULL((void*)0);
933
934 // AIM input bodies
935 int numBody;
936 ego *bodies = NULL((void*)0);
937 int bodySubType = 0, bodyOClass, bodyNumChild, *bodySense = NULL((void*)0);
938 ego bodyRef, *bodyChild = NULL((void*)0);
939 double bodyData[4];
940
941 // FUN3D Version
942 double fun3dVersion;
943
944 // Boundary/surface properties
945 cfdBoundaryConditionStruct bcProps;
946
947 // Modal Aeroelastic properties
948 cfdModalAeroelasticStruct modalAeroelastic;
949
950 // Boundary conditions container - for writing .mapbc file
951 bndCondStruct bndConds;
952
953 // Mesh reference obtained from meshing AIM
954 aimMeshRef *meshRef = NULL((void*)0);
955
956 // Discrete data transfer variables
957 char **boundName = NULL((void*)0);
958 int numBoundName;
959
960#ifdef HAVE_PYTHON1
961 PyObject* mobj = NULL((void*)0);
962#if CYTHON_PEP489_MULTI_PHASE_INIT(((3 << 24) | (8 << 16) | (9 << 8) | (0xF <<
4) | (0 << 0)) >= 0x03050000)
963 PyModuleDef *mdef = NULL((void*)0);
964 PyObject *modname = NULL((void*)0);
965#endif
966#endif
967
968 aimStorage *fun3dInstance;
969
970 fun3dInstance = (aimStorage *) instStore;
971 AIM_NOTNULL(fun3dInstance, aimInfo, status){ if (fun3dInstance == ((void*)0)) { status = -307; aim_status
(aimInfo, status, "fun3dAIM.c", 971, __func__, 1, "%s == NULL!"
, "fun3dInstance"); goto cleanup; } }
;
972 AIM_NOTNULL(aimInputs, aimInfo, status){ if (aimInputs == ((void*)0)) { status = -307; aim_status(aimInfo
, status, "fun3dAIM.c", 972, __func__, 1, "%s == NULL!", "aimInputs"
); goto cleanup; } }
;
973
974 // Initiate structures variables - will be destroyed during cleanup
975 status = initiate_cfdBoundaryConditionStruct(&bcProps);
976 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 976
, __func__, 0); goto cleanup; }
;
977
978 status = initiate_cfdModalAeroelasticStruct(&modalAeroelastic);
979 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 979
, __func__, 0); goto cleanup; }
;
980
981 status = initiate_bndCondStruct(&bndConds);
982 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 982
, __func__, 0); goto cleanup; }
;
983
984 if (aimInputs[Design_Functional-1].nullVal == NotNull &&
985 aimInputs[Design_SensFile-1].vals.integer == (int)true1) {
986 AIM_ERROR(aimInfo, "Cannot set both 'Design_Functional' and 'Design_SensFile'!"){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 986, __func__
, "Cannot set both 'Design_Functional' and 'Design_SensFile'!"
); }
;
987 status = CAPS_BADVALUE-311;
988 goto cleanup;
989 }
990
991 // Get AIM bodies
992 status = aim_getBodies(aimInfo, &intents, &numBody, &bodies);
993 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 993
, __func__, 0); goto cleanup; }
;
994
995#ifdef DEBUG
996 printf(" fun3dAIM/aimPreAnalysis numBody = %d!\n", numBody);
997#endif
998
999 if ((numBody <= 0) || (bodies == NULL((void*)0))) {
1000#ifdef DEBUG
1001 printf(" fun3dAIM/aimPreAnalysis No Bodies!\n");
1002#endif
1003 return CAPS_SOURCEERR-330;
1004 }
1005
1006 // Get Version number
1007 fun3dVersion = aimInputs[FUN3D_Version-1].vals.real;
1008
1009 // Get reference quantities from the bodies
1010 for (body=0; body < numBody; body++) {
1011
1012 if (aimInputs[Reference_Area-1].nullVal == IsNull) {
1013
1014 status = EG_attributeRet(bodies[body], "capsReferenceArea", &atype,
1015 &alen, &ints, &reals, &string);
1016 if (status == EGADS_SUCCESS0) {
1017
1018 if (atype == ATTRREAL2) {
1019 aimInputs[Reference_Area-1].vals.real = (double) reals[0];
1020 aimInputs[Reference_Area-1].nullVal = NotNull;
1021 } else {
1022 printf("capsReferenceArea should be followed by a single real value!\n");
1023 status = CAPS_BADVALUE-311;
1024 goto cleanup;
1025 }
1026 }
1027 }
1028
1029 if (aimInputs[Moment_Length-1].nullVal == IsNull) {
1030
1031 status = EG_attributeRet(bodies[body], "capsReferenceChord", &atype,
1032 &alen, &ints, &reals, &string);
1033 if (status == EGADS_SUCCESS0){
1034
1035 if (atype == ATTRREAL2) {
1036 aimInputs[Moment_Length-1].vals.reals[0] = (double) reals[0];
1037 aimInputs[Moment_Length-1].nullVal = NotNull;
1038 } else {
1039 printf("capsReferenceChord should be followed by a single real value!\n");
1040 status = CAPS_BADVALUE-311;
1041 goto cleanup;
1042 }
1043
1044 }
1045
1046 status = EG_attributeRet(bodies[body], "capsReferenceSpan", &atype,
1047 &alen, &ints, &reals, &string);
1048 if (status == EGADS_SUCCESS0) {
1049
1050 if (atype == ATTRREAL2) {
1051 aimInputs[Moment_Length-1].vals.reals[1] = (double) reals[0];
1052 aimInputs[Moment_Length-1].nullVal = NotNull;
1053 } else {
1054 printf("capsReferenceSpan should be followed by a single real value!\n");
1055 status = CAPS_BADVALUE-311;
1056 goto cleanup;
1057 }
1058 }
1059 }
1060
1061 if (aimInputs[Moment_Center-1].nullVal == IsNull) {
1062
1063 status = EG_attributeRet(bodies[body], "capsReferenceX", &atype,
1064 &alen, &ints, &reals, &string);
1065 if (status == EGADS_SUCCESS0) {
1066
1067 if (atype == ATTRREAL2) {
1068 aimInputs[Moment_Center-1].vals.reals[0] = (double) reals[0];
1069 aimInputs[Moment_Center-1].nullVal = NotNull;
1070 } else {
1071 printf("capsReferenceX should be followed by a single real value!\n");
1072 status = CAPS_BADVALUE-311;
1073 goto cleanup;
1074 }
1075 }
1076
1077 status = EG_attributeRet(bodies[body], "capsReferenceY", &atype,
1078 &alen, &ints, &reals, &string);
1079 if (status == EGADS_SUCCESS0) {
1080
1081 if (atype == ATTRREAL2) {
1082 aimInputs[Moment_Center-1].vals.reals[1] = (double) reals[0];
1083 aimInputs[Moment_Center-1].nullVal = NotNull;
1084 } else {
1085 printf("capsReferenceY should be followed by a single real value!\n");
1086 status = CAPS_BADVALUE-311;
1087 goto cleanup;
1088 }
1089 }
1090
1091 status = EG_attributeRet(bodies[body], "capsReferenceZ", &atype,
1092 &alen, &ints, &reals, &string);
1093 if (status == EGADS_SUCCESS0) {
1094
1095 if (atype == ATTRREAL2) {
1096 aimInputs[Moment_Center-1].vals.reals[2] = (double) reals[0];
1097 aimInputs[Moment_Center-1].nullVal = NotNull;
1098 } else {
1099 printf("capsReferenceZ should be followed by a single real value!\n");
1100 status = CAPS_BADVALUE-311;
1101 goto cleanup;
1102 }
1103 }
1104 }
1105 }
1106
1107 // Check to see if python was linked
1108#ifdef HAVE_PYTHON1
1109 pythonLinked = (int) true1;
1110#else
1111 pythonLinked = (int) false0;
1112#endif
1113
1114 // Should we use python even if it was linked?
1115 usePython = aimInputs[Use_Python_NML-1].vals.integer;
1116 if (usePython == (int) true1 && pythonLinked == (int) false0) {
1117
1118 printf("Use of Python library requested but not linked!\n");
1119 usePython = (int) false0;
1120
1121 } else if (usePython == (int) false0 && pythonLinked == (int) true1) {
1122
1123 printf("Python library was linked, but will not be used!\n");
1124 }
1125
1126 // Get project name
1127 projectName = aimInputs[Proj_Name-1].vals.string;
1128
1129 // Get intent
1130/* Ryan -- please fix
1131 status = check_CAPSIntent(numBody, bodies, &currentIntent);
1132 if (status != CAPS_SUCCESS) goto cleanup;
1133
1134 if (currentIntent != CAPSMAGIC) {
1135 if(currentIntent != CFD) {
1136 printf("All bodies must have the same capsIntent of CFD!\n");
1137 status = CAPS_BADVALUE;
1138 goto cleanup;
1139 }
1140 } */
1141
1142 // Get attribute to index mapping
1143 if (aim_newGeometry(aimInfo) == CAPS_SUCCESS0 ||
1144 fun3dInstance->groupMap.mapName == NULL((void*)0)) {
1145 if (aimInputs[Two_Dimensional-1].vals.integer == (int) true1) {
1146 attrLevel = 2; // Only search down to the edge level of the EGADS body
1147 } else {
1148 attrLevel = 1; // Only search down to the face level of the EGADS body
1149 }
1150
1151 // Get capsGroup name and index mapping to make sure all faces have a capsGroup value
1152 status = create_CAPSGroupAttrToIndexMap(numBody,
1153 bodies,
1154 attrLevel,
1155 &fun3dInstance->groupMap);
1156 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1156
, __func__, 0); goto cleanup; }
;
1157 }
1158
1159 if (aimInputs[Boundary_Condition-1].nullVal == IsNull) {
1160 AIM_ANALYSISIN_ERROR(aimInfo, Boundary_Condition, "No boundary conditions provided!"){ aim_message(aimInfo, CERROR, Boundary_Condition, "fun3dAIM.c"
, 1160, __func__, "No boundary conditions provided!"); }
;
1161 status = CAPS_BADVALUE-311;
1162 goto cleanup;
1163 }
1164
1165 // Get boundary conditions
1166 status = cfd_getBoundaryCondition( aimInfo,
1167 aimInputs[Boundary_Condition-1].length,
1168 aimInputs[Boundary_Condition-1].vals.tuple,
1169 &fun3dInstance->groupMap,
1170 &bcProps);
1171 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1171
, __func__, 0); goto cleanup; }
;
1172
1173 // Get modal aeroelastic information - only get modal aeroelastic inputs if they have be set
1174 if (aimInputs[Modal_Aeroelastic-1].nullVal == NotNull) {
1175
1176 status = cfd_getModalAeroelastic( aimInputs[Modal_Aeroelastic-1].length,
1177 aimInputs[Modal_Aeroelastic-1].vals.tuple,
1178 &modalAeroelastic);
1179 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1179
, __func__, 0); goto cleanup; }
;
1180
1181
1182 modalAeroelastic.freestreamVelocity = aimInputs[Modal_Ref_Velocity-1].vals.real;
1183 modalAeroelastic.freestreamDynamicPressure = aimInputs[Modal_Ref_Dynamic_Pressure-1].vals.real;
1184 modalAeroelastic.lengthScaling = aimInputs[Modal_Ref_Length-1].vals.real;
1185 }
1186
1187 // Get design variables
1188 if (aimInputs[Design_Variable-1].nullVal == NotNull &&
1189 aim_newAnalysisIn(aimInfo, Design_Variable) == CAPS_SUCCESS0) {
1190
1191 if (aimInputs[Design_Functional-1].nullVal == IsNull &&
1192 aimInputs[Design_SensFile-1].vals.integer == (int)false0) {
1193 AIM_ERROR(aimInfo, "\"Design_Variable\" has been set, but no values have been provided for \"Design_Functional\" and \"Design_SensFile\" is False!"){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 1193, __func__
, "\"Design_Variable\" has been set, but no values have been provided for \"Design_Functional\" and \"Design_SensFile\" is False!"
); }
;
1194 status = CAPS_BADVALUE-311;
1195 goto cleanup;
1196 }
1197/*@-nullpass@*/
1198 status = cfd_getDesignVariable(aimInfo,
1199 aimInputs[Design_Variable-1].length,
1200 aimInputs[Design_Variable-1].vals.tuple,
1201 &fun3dInstance->design.numDesignVariable,
1202 &fun3dInstance->design.designVariable);
1203/*@+nullpass@*/
1204 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1204
, __func__, 0); goto cleanup; }
;
1205 }
1206
1207 // Get design functionals
1208 if ( aimInputs[Design_Functional-1].nullVal == NotNull &&
1209 (aim_newAnalysisIn(aimInfo, Design_Functional) == CAPS_SUCCESS0 ||
1210 aim_newAnalysisIn(aimInfo, Design_Variable ) == CAPS_SUCCESS0)) {
1211
1212 status = cfd_getDesignFunctional(aimInfo,
1213 aimInputs[Design_Functional-1].length,
1214 aimInputs[Design_Functional-1].vals.tuple,
1215 &bcProps,
1216 fun3dInstance->design.numDesignVariable,
1217 fun3dInstance->design.designVariable,
1218 &fun3dInstance->design.numDesignFunctional,
1219 &fun3dInstance->design.designFunctional);
1220 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1220
, __func__, 0); goto cleanup; }
;
1221 }
1222
1223
1224 if (aimInputs[Mesh-1].nullVal == IsNull) {
1225 AIM_ANALYSISIN_ERROR(aimInfo, Mesh, "'Mesh' input must be linked to an output 'Area_Mesh' or 'Volume_Mesh'"){ aim_message(aimInfo, CERROR, Mesh, "fun3dAIM.c", 1225, __func__
, "'Mesh' input must be linked to an output 'Area_Mesh' or 'Volume_Mesh'"
); }
;
1226 status = CAPS_BADVALUE-311;
1227 goto cleanup;
1228 }
1229
1230 // Get mesh
1231 meshRef = (aimMeshRef *)aimInputs[Mesh-1].vals.AIMptr;
1232 AIM_NOTNULL(meshRef, aimInfo, status){ if (meshRef == ((void*)0)) { status = -307; aim_status(aimInfo
, status, "fun3dAIM.c", 1232, __func__, 1, "%s == NULL!", "meshRef"
); goto cleanup; } }
;
1233
1234 // Are we running in two-mode
1235 if (aimInputs[Two_Dimensional-1].vals.integer == (int) true1) {
1236
1237 if (numBody > 1) {
1238 AIM_ERROR(aimInfo, "Only 1 body may be provided when running in two mode!! numBody = %d", numBody){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 1238, __func__
, "Only 1 body may be provided when running in two mode!! numBody = %d"
, numBody); }
;
1239 status = CAPS_BADVALUE-311;
1240 goto cleanup;
1241 }
1242
1243 for (body = 0; body < numBody; body++) {
1244 // What type of BODY do we have?
1245 status = EG_getTopology(bodies[body], &bodyRef, &bodyOClass,
1246 &bodySubType, bodyData, &bodyNumChild,
1247 &bodyChild, &bodySense);
1248 if (status != EGADS_SUCCESS0) goto cleanup;
1249
1250 if (bodySubType != FACEBODY7 && bodySubType != SHEETBODY8) {
1251 printf("Body type must be either FACEBODY (%d) or a SHEETBODY (%d) when running in two mode!\n",
1252 FACEBODY7, SHEETBODY8);
1253 status = CAPS_BADTYPE-306;
1254 goto cleanup;
1255 }
1256 }
1257
1258 // Extrude Surface mesh
1259 // WARNING: This will modify bcProps!
1260 status = fun3d_2DMesh(aimInfo,
1261 meshRef,
1262 projectName,
1263 &fun3dInstance->groupMap,
1264 &bcProps);
1265 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1265
, __func__, 0); goto cleanup; }
;
1266 }
1267
1268
1269 // Optimization - functional must be set at a minimum
1270 if (aimInputs[Design_Functional-1].nullVal == NotNull ||
1271 aimInputs[Design_SensFile-1].vals.integer == (int)true1) {
1272
1273 if (meshRef->nmap > 0) {
1274
1275 status = fun3d_makeDirectory(aimInfo);
1276 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1276
, __func__, 0); goto cleanup; }
;
1277
1278 if (aimInputs[Design_Functional-1].nullVal == NotNull) {
1279 if ( aim_newGeometry(aimInfo) == CAPS_SUCCESS0 ||
1280 aim_newAnalysisIn(aimInfo, Design_Sensitivity) == CAPS_SUCCESS0 ||
1281 aim_newAnalysisIn(aimInfo, Design_Variable ) == CAPS_SUCCESS0) {
1282 status = fun3d_writeParameterization(aimInfo,
1283 fun3dInstance->design.numDesignVariable,
1284 fun3dInstance->design.designVariable,
1285 aimInputs[Design_Sensitivity-1].vals.integer,
1286 meshRef);
1287 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1287
, __func__, 0); goto cleanup; }
;
1288 }
1289
1290 /* only write rubber.data file if inputs have changed */
1291 if (aim_newAnalysisIn(aimInfo, Design_Functional ) == CAPS_SUCCESS0 ||
1292 aim_newAnalysisIn(aimInfo, Design_Sensitivity) == CAPS_SUCCESS0 ||
1293 aim_newAnalysisIn(aimInfo, Design_Variable ) == CAPS_SUCCESS0) {
1294 status = fun3d_writeRubber(aimInfo,
1295 fun3dInstance->design,
1296 aimInputs[FUN3D_Version-1].vals.real,
1297 meshRef);
1298 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1298
, __func__, 0); goto cleanup; }
;
1299 }
1300 }
1301#ifdef WIN32
1302 snprintf(filename, PATH_MAX4096, "Flow\\%s%s", projectName, MESHEXTENSION".lb8.ugrid");
1303#else
1304 snprintf(filename, PATH_MAX4096, "Flow/%s%s", projectName, MESHEXTENSION".lb8.ugrid");
1305#endif
1306 } else {
1307 AIM_ERROR(aimInfo, "The volume is not suitable for sensitivity input generation - possibly the volume mesher "{ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 1308, __func__
, "The volume is not suitable for sensitivity input generation - possibly the volume mesher "
"added unaccounted points on the surface mesh"); }
1308 "added unaccounted points on the surface mesh"){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 1308, __func__
, "The volume is not suitable for sensitivity input generation - possibly the volume mesher "
"added unaccounted points on the surface mesh"); }
;
1309 status = CAPS_BADVALUE-311;
1310 goto cleanup;
1311 }
1312 } else {
1313 snprintf(filename, PATH_MAX4096, "%s%s", projectName, MESHEXTENSION".lb8.ugrid");
1314 }
1315
1316 if (aimInputs[Two_Dimensional-1].vals.integer == (int) false0) {
1317 snprintf(gridfile, PATH_MAX4096, "%s%s", meshRef->fileName, MESHEXTENSION".lb8.ugrid");
1318
1319 status = aim_symLink(aimInfo, gridfile, filename);
1320 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1320
, __func__, 0); goto cleanup; }
;
1321 }
1322
1323 status = populate_bndCondStruct_from_bcPropsStruct(&bcProps, &bndConds);
1324 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1324
, __func__, 0); goto cleanup; }
;
1325
1326 // Replace dummy values in bcVal with FUN3D specific values
1327 for (i = 0; i < bcProps.numSurfaceProp ; i++) {
1328
1329 // {UnknownBoundary, Inviscid, Viscous, Farfield, Extrapolate, Freestream,
1330 // BackPressure, Symmetry, SubsonicInflow, SubsonicOutflow,
1331 // MassflowIn, MassflowOut, FixedInflow, FixedOutflow}
1332
1333 if (bcProps.surfaceProp[i].surfaceType == Inviscid ) bndConds.bcVal[i] = 3000;
1334 else if (bcProps.surfaceProp[i].surfaceType == Viscous ) bndConds.bcVal[i] = 4000;
1335 else if (bcProps.surfaceProp[i].surfaceType == Farfield ) bndConds.bcVal[i] = 5000;
1336 else if (bcProps.surfaceProp[i].surfaceType == Extrapolate ) bndConds.bcVal[i] = 5026;
1337 else if (bcProps.surfaceProp[i].surfaceType == Freestream ) bndConds.bcVal[i] = 5050;
1338 else if (bcProps.surfaceProp[i].surfaceType == BackPressure ) bndConds.bcVal[i] = 5051;
1339 else if (bcProps.surfaceProp[i].surfaceType == SubsonicInflow ) bndConds.bcVal[i] = 7011;
1340 else if (bcProps.surfaceProp[i].surfaceType == SubsonicOutflow) bndConds.bcVal[i] = 7012;
1341 else if (bcProps.surfaceProp[i].surfaceType == MassflowIn ) bndConds.bcVal[i] = 7036;
1342 else if (bcProps.surfaceProp[i].surfaceType == MassflowOut ) bndConds.bcVal[i] = 7031;
1343 else if (bcProps.surfaceProp[i].surfaceType == FixedInflow ) bndConds.bcVal[i] = 7100;
1344 else if (bcProps.surfaceProp[i].surfaceType == FixedOutflow ) bndConds.bcVal[i] = 7105;
1345 else if (bcProps.surfaceProp[i].surfaceType == MachOutflow ) bndConds.bcVal[i] = 5052;
1346 else if (bcProps.surfaceProp[i].surfaceType == Symmetry ) {
1347
1348 if (bcProps.surfaceProp[i].symmetryPlane == 1) bndConds.bcVal[i] = 6661;
1349 else if (bcProps.surfaceProp[i].symmetryPlane == 2) bndConds.bcVal[i] = 6662;
1350 else if (bcProps.surfaceProp[i].symmetryPlane == 3) bndConds.bcVal[i] = 6663;
1351 else {
1352 AIM_ERROR(aimInfo, "Unknown symmetryPlane for boundary %d", bcProps.surfaceProp[i].bcID){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 1352, __func__
, "Unknown symmetryPlane for boundary %d", bcProps.surfaceProp
[i].bcID); }
;
1353 status = CAPS_BADVALUE-311;
1354 goto cleanup;
1355 }
1356 }
1357 }
1358
1359 if (aimInputs[Design_Functional-1].nullVal == NotNull ||
1360 aimInputs[Design_SensFile-1].vals.integer == (int)true1) {
1361#ifdef WIN32
1362 snprintf(filename, PATH_MAX4096, "Flow\\%s", projectName);
1363#else
1364 snprintf(filename, PATH_MAX4096, "Flow/%s", projectName);
1365#endif
1366 } else {
1367 strcpy(filename, projectName);
1368 }
1369
1370 // Write *.mapbc file
1371 status = write_MAPBC(aimInfo, filename,
1372 bndConds.numBND,
1373 bndConds.bndID,
1374 bndConds.bcVal);
1375 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1375
, __func__, 0); goto cleanup; }
;
1376
1377 // Remove old *.forces file (Fun3D appends to the file)
1378 if (aimInputs[Design_Functional-1].nullVal == NotNull ||
1379 aimInputs[Design_SensFile-1].vals.integer == (int)true1) {
1380#ifdef WIN32
1381 snprintf(filename, PATH_MAX4096, "Flow\\%s%s", projectName, ".forces");
1382#else
1383 snprintf(filename, PATH_MAX4096, "Flow/%s%s", projectName, ".forces");
1384#endif
1385 } else {
1386 snprintf(filename, PATH_MAX4096, "%s%s", projectName, ".forces");
1387 }
1388 remove(filename);
1389
1390 //////////////////////////////////////////////////////////
1391 // Open and write the fun3d.nml input file using Python //
1392 //////////////////////////////////////////////////////////
1393 if (usePython == (int) true1 && pythonLinked == (int) true1) {
1394#ifdef HAVE_PYTHON1
1395 {
1396 // Flag to see if Python was already initialized - i.e. the AIM was called from within Python
1397 int initPy = (int) false0;
1398
1399 // Python thread state variable for new interpreter if needed
1400 //PyThreadState *newThread = NULL;
1401
1402 printf("\nUsing Python to write FUN3D namelist (fun3d.nml)\n");
1403
1404 // Initialize python
1405 if (Py_IsInitialized() == 0) {
1406 printf("\tInitializing Python for FUN3D AIM\n\n");
1407 Py_InitializeEx(0);
1408 initPy = (int) true1;
1409 } else {
1410
1411 /*
1412 // If python is already initialized - create a new interpreter to run the namelist creator
1413 printf("\tInitializing new Python thread for FUN3D AIM\n\n");
1414 PyEval_InitThreads();
1415 newThread = Py_NewInterpreter();
1416 (void) PyThreadState_Swap(newThread);
1417 */
1418 initPy = (int) false0;
1419 }
1420
1421 PyGILState_STATE gstate;
1422 gstate = PyGILState_Ensure();
1423
1424 // Taken from "main" by running cython with --embed
1425 #if PY_MAJOR_VERSION3 < 3
1426 initfun3dNamelist();
1427 #elif CYTHON_PEP489_MULTI_PHASE_INIT(((3 << 24) | (8 << 16) | (9 << 8) | (0xF <<
4) | (0 << 0)) >= 0x03050000)
1428 if (fun3dNamelist_Initialized == (int)false0 || initPy == (int)true1) {
1429 fun3dNamelist_Initialized = (int)true1;
1430 mobj = PyInit_fun3dNamelist();
1431 if (!PyModule_Check(mobj)((((PyObject*)(mobj))->ob_type) == (&PyModule_Type) ||
PyType_IsSubtype((((PyObject*)(mobj))->ob_type), (&PyModule_Type
)))
) {
1432 mdef = (PyModuleDef *) mobj;
1433 modname = PyUnicode_FromString("fun3dNamelist");
1434 mobj = NULL((void*)0);
1435 if (modname) {
1436 mobj = PyModule_NewObject(modname);
1437 Py_DECREF(modname)_Py_DECREF("fun3dAIM.c", 1437, ((PyObject*)(modname)));
1438 if (mobj) PyModule_ExecDef(mobj, mdef);
1439 }
1440 }
1441 }
1442 #else
1443 mobj = PyInit_fun3dNamelist();
1444 #endif
1445
1446 if (PyErr_Occurred()) {
1447 PyErr_Print();
1448 #if PY_MAJOR_VERSION3 < 3
1449 if (Py_FlushLine()) PyErr_Clear();
1450 #endif
1451 /* Release the thread. No Python API allowed beyond this point. */
1452 PyGILState_Release(gstate);
1453 status = CAPS_BADVALUE-311;
1454 goto cleanup;
1455 }
1456
1457 Py_XDECREF(mobj)_Py_XDECREF(((PyObject*)(mobj)));
1458
1459 status = fun3d_writeNMLPython(aimInfo, aimInputs, bcProps);
1460 if (status == -1) {
1461 printf("\tError: Python error occurred while writing namelist file\n");
1462 } else {
1463 printf("\tDone writing nml file with Python\n");
1464 }
1465
1466 if (PyErr_Occurred()) {
1467 PyErr_Print();
1468 #if PY_MAJOR_VERSION3 < 3
1469 if (Py_FlushLine()) PyErr_Clear();
1470 #endif
1471 /* Release the thread. No Python API allowed beyond this point. */
1472 PyGILState_Release(gstate);
1473 status = CAPS_BADVALUE-311;
1474 goto cleanup;
1475 }
1476
1477 /* Release the thread. No Python API allowed beyond this point. */
1478 PyGILState_Release(gstate);
1479
1480 // Close down python
1481 if (initPy == (int) false0) {
1482 /*
1483 printf("\n");
1484 printf("\tClosing new Python thread\n");
1485 Py_EndInterpreter(newThread);
1486 (void) PyThreadState_Swap(NULL); // This function call is probably not necessary;
1487 */
1488 } else {
1489 printf("\tClosing Python\n");
1490 Py_Finalize(); // Do not finalize if the AIM was called from Python
1491 }
1492 }
1493#endif
1494
1495 } else {
1496
1497 if (aimInputs[Overwrite_NML-1].vals.integer == (int) false0) {
1498
1499 printf("Since Python was not linked and/or being used, the \"Overwrite_NML\" input needs to be set to \"True\" to give");
1500 printf(" permission to create a new fun3d.nml. fun3d.nml will NOT be updated!!\n");
1501
1502 } else {
1503
1504 printf("Warning: The fun3d.nml file will be overwritten!\n");
1505
1506 status = fun3d_writeNML(aimInfo, aimInputs, bcProps);
1507 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1507
, __func__, 0); goto cleanup; }
;
1508
1509 }
1510 }
1511
1512 // If data transfer is ok ....
1513 if (meshRef->nmap > 0) {
1514
1515 //See if we have data transfer information
1516 status = aim_getBounds(aimInfo, &numBoundName, &boundName);
1517 if (status == CAPS_SUCCESS0) {
1518
1519 if (aimInputs[Modal_Aeroelastic-1].nullVal == NotNull) {
1520 status = fun3d_dataTransfer(aimInfo,
1521 projectName,
1522 &fun3dInstance->groupMap,
1523 bcProps,
1524 meshRef,
1525 &modalAeroelastic);
1526 if (status == CAPS_SUCCESS0) {
1527 status = fun3d_writeMovingBody(aimInfo, fun3dVersion, bcProps, &modalAeroelastic);
1528 }
1529
1530 } else{
1531 status = fun3d_dataTransfer(aimInfo,
1532 projectName,
1533 &fun3dInstance->groupMap,
1534 bcProps,
1535 meshRef,
1536 NULL((void*)0));
1537 }
1538 if (status != CAPS_SUCCESS0 && status != CAPS_NOTFOUND-303) goto cleanup;
1539 }
1540 } // End if data transfer ok
1541
1542 status = CAPS_SUCCESS0;
1543
1544cleanup:
1545
1546 AIM_FREE(boundName){ EG_free(boundName); boundName = ((void*)0); };
1547
1548 (void) destroy_cfdBoundaryConditionStruct(&bcProps);
1549 (void) destroy_cfdModalAeroelasticStruct(&modalAeroelastic);
1550
1551 (void) destroy_bndCondStruct(&bndConds);
1552
1553 return status;
1554}
1555
1556
1557/* no longer optional and needed for restart */
1558int aimPostAnalysis(void *instStore, void *aimInfo,
1559 /*@unused@*/ int restart, capsValue *aimInputs)
1560{
1561 int status = CAPS_SUCCESS0;
1562
1563 int i, j, k, idv, irow, icol, ibody; // Indexing
1564 int index, offset, state;
1565
1566 char tmp[128], filename[PATH_MAX4096];
1567 int numFunctional=0;
1568 int **functional_map=NULL((void*)0), *vol2tess=NULL((void*)0);
1569 double **functional_xyz=NULL((void*)0);
1570 double functional_dvar;
1571
1572 ego body;
1573
1574 int numNode = 0, *numPoint=NULL((void*)0), numVolNode;
1575
1576 const char *name;
1577 char **names=NULL((void*)0);
1578 double **dxyz = NULL((void*)0);
1579
1580 int numBody;
1581 ego *bodies = NULL((void*)0);
1582 const char *intents;
1583
1584 // Boundary/surface properties
1585 cfdBoundaryConditionStruct bcProps;
1586
1587 capsValue *ProjName=NULL((void*)0);
1588 const char *projectName =NULL((void*)0);
1589
1590 FILE *fp=NULL((void*)0);
1591 capsValue *values=NULL((void*)0), *geomInVal;
1592 capsValue value;
1593
1594 cfdDesignVariableStruct *dvar=NULL((void*)0);
1595
1596 // Mesh reference obtained from meshing AIM
1597 aimMeshRef *meshRef = NULL((void*)0);
1598
1599 aimStorage *fun3dInstance;
1600
1601 fun3dInstance = (aimStorage*)instStore;
1602
1603 // Initiate structures variables - will be destroyed during cleanup
1604 status = initiate_cfdBoundaryConditionStruct(&bcProps);
1605 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1605
, __func__, 0); goto cleanup; }
;
1606
1607 AIM_NOTNULL(aimInputs, aimInfo, status){ if (aimInputs == ((void*)0)) { status = -307; aim_status(aimInfo
, status, "fun3dAIM.c", 1607, __func__, 1, "%s == NULL!", "aimInputs"
); goto cleanup; } }
;
1608 if (aimInputs[Design_Functional-1].nullVal == NotNull) {
1609 status = fun3d_readRubber(aimInfo,
1610 fun3dInstance->design,
1611 aimInputs[FUN3D_Version-1].vals.real);
1612 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1612
, __func__, 0); goto cleanup; }
;
1613
1614 aim_initValue(&value);
1615
1616 if (fun3dInstance->design.designFunctional == NULL((void*)0)) {
1617 // Get AIM bodies
1618 status = aim_getBodies(aimInfo, &intents, &numBody, &bodies);
1619 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1619
, __func__, 0); goto cleanup; }
;
1620
1621 // Get capsGroup name and index mapping to make sure all faces have a capsGroup value
1622 status = create_CAPSGroupAttrToIndexMap(numBody,
1623 bodies,
1624 1, // Only search down to the face level of the EGADS body
1625 &fun3dInstance->groupMap);
1626 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1626
, __func__, 0); goto cleanup; }
;
1627
1628 // Get boundary conditions
1629 status = cfd_getBoundaryCondition( aimInfo,
1630 aimInputs[Boundary_Condition-1].length,
1631 aimInputs[Boundary_Condition-1].vals.tuple,
1632 &fun3dInstance->groupMap,
1633 &bcProps);
1634 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1634
, __func__, 0); goto cleanup; }
;
1635
1636 /*@-nullpass@*/
1637 status = cfd_getDesignVariable(aimInfo,
1638 aimInputs[Design_Variable-1].length,
1639 aimInputs[Design_Variable-1].vals.tuple,
1640 &fun3dInstance->design.numDesignVariable,
1641 &fun3dInstance->design.designVariable);
1642 /*@+nullpass@*/
1643 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1643
, __func__, 0); goto cleanup; }
;
1644
1645 status = cfd_getDesignFunctional(aimInfo,
1646 aimInputs[Design_Functional-1].length,
1647 aimInputs[Design_Functional-1].vals.tuple,
1648 &bcProps,
1649 fun3dInstance->design.numDesignVariable,
1650 fun3dInstance->design.designVariable,
1651 &fun3dInstance->design.numDesignFunctional,
1652 &fun3dInstance->design.designFunctional);
1653 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1653
, __func__, 0); goto cleanup; }
;
1654 }
1655
1656 for (i = 0; i < fun3dInstance->design.numDesignFunctional; i++) {
1657
1658 /* allocate derivatives */
1659 AIM_ALLOC(value.derivs, fun3dInstance->design.designFunctional[i].numDesignVariable, capsDeriv, aimInfo, status){ if (value.derivs != ((void*)0)) { status = -4; aim_status(aimInfo
, status, "fun3dAIM.c", 1659, __func__, 1, "AIM_ALLOC: %s != NULL"
, "value.derivs"); goto cleanup; } size_t memorysize = fun3dInstance
->design.designFunctional[i].numDesignVariable; value.derivs
= (capsDeriv *) EG_alloc(memorysize*sizeof(capsDeriv)); if (
value.derivs == ((void*)0)) { status = -4; aim_status(aimInfo
, status, "fun3dAIM.c", 1659, __func__, 3, "AIM_ALLOC: %s size %zu type %s"
, "value.derivs", memorysize, "capsDeriv"); goto cleanup; } }
;
1660 for (j = 0; j < fun3dInstance->design.designFunctional[i].numDesignVariable; j++) {
1661 value.derivs[j].name = NULL((void*)0);
1662 value.derivs[j].deriv = NULL((void*)0);
1663 value.derivs[j].len_wrt = 0;
1664 }
1665 value.nderiv = fun3dInstance->design.designFunctional[i].numDesignVariable;
1666
1667 value.vals.real = fun3dInstance->design.designFunctional[i].value;
1668 value.type = DoubleDeriv;
1669
1670 for (j = 0; j < fun3dInstance->design.designFunctional[i].numDesignVariable; j++) {
1671
1672 dvar = &fun3dInstance->design.designFunctional[i].dvar[j];
1673
1674 AIM_STRDUP(value.derivs[j].name, dvar->name, aimInfo, status){ if (value.derivs[j].name != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "fun3dAIM.c", 1674, __func__, 1, "AIM_STRDUP: %s != NULL!"
, "value.derivs[j].name"); goto cleanup; } value.derivs[j].name
= EG_strdup(dvar->name); if (value.derivs[j].name == ((void
*)0)) { status = -4; aim_status(aimInfo, status, "fun3dAIM.c"
, 1674, __func__, 2, "AIM_STRDUP: %s %s", "value.derivs[j].name"
, dvar->name); goto cleanup; } }
;
1675 AIM_ALLOC(value.derivs[j].deriv, dvar->var->length, double, aimInfo, status){ if (value.derivs[j].deriv != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "fun3dAIM.c", 1675, __func__, 1, "AIM_ALLOC: %s != NULL"
, "value.derivs[j].deriv"); goto cleanup; } size_t memorysize
= dvar->var->length; value.derivs[j].deriv = (double *
) EG_alloc(memorysize*sizeof(double)); if (value.derivs[j].deriv
== ((void*)0)) { status = -4; aim_status(aimInfo, status, "fun3dAIM.c"
, 1675, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "value.derivs[j].deriv"
, memorysize, "double"); goto cleanup; } }
;
1676 value.derivs[j].len_wrt = dvar->var->length;
1677
1678 for (k = 0; k < dvar->var->length; k++) {
1679 value.derivs[j].deriv[k] = dvar->value[k];
1680 }
1681 }
1682
1683 /* create the dynamic output */
1684 status = aim_makeDynamicOutput(aimInfo, fun3dInstance->design.designFunctional[i].name, &value);
1685 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1685
, __func__, 0); goto cleanup; }
;
1686 }
1687 }
1688
1689 if (aimInputs[Design_SensFile-1].vals.integer == (int)true1) {
1690
1691 if (fun3dInstance->design.designVariable == NULL((void*)0)) {
1692 // Get AIM bodies
1693 status = aim_getBodies(aimInfo, &intents, &numBody, &bodies);
1694 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1694
, __func__, 0); goto cleanup; }
;
1695
1696 // Get capsGroup name and index mapping to make sure all faces have a capsGroup value
1697 status = create_CAPSGroupAttrToIndexMap(numBody,
1698 bodies,
1699 1, // Only search down to the face level of the EGADS body
1700 &fun3dInstance->groupMap);
1701 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1701
, __func__, 0); goto cleanup; }
;
1702
1703 // Get boundary conditions
1704 status = cfd_getBoundaryCondition( aimInfo,
1705 aimInputs[Boundary_Condition-1].length,
1706 aimInputs[Boundary_Condition-1].vals.tuple,
1707 &fun3dInstance->groupMap,
1708 &bcProps);
1709 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1709
, __func__, 0); goto cleanup; }
;
1710
1711 /*@-nullpass@*/
1712 status = cfd_getDesignVariable(aimInfo,
1713 aimInputs[Design_Variable-1].length,
1714 aimInputs[Design_Variable-1].vals.tuple,
1715 &fun3dInstance->design.numDesignVariable,
1716 &fun3dInstance->design.designVariable);
1717 /*@+nullpass@*/
1718 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1718
, __func__, 0); goto cleanup; }
;
1719 }
1720
1721 status = aim_getValue(aimInfo, Proj_Name, ANALYSISIN, &ProjName);
1722 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1722
, __func__, 0); goto cleanup; }
;
1723 projectName = ProjName->vals.string;
1724
1725 // Get mesh
1726 meshRef = (aimMeshRef *)aimInputs[Mesh-1].vals.AIMptr;
1727 AIM_NOTNULL(meshRef, aimInfo, status){ if (meshRef == ((void*)0)) { status = -307; aim_status(aimInfo
, status, "fun3dAIM.c", 1727, __func__, 1, "%s == NULL!", "meshRef"
); goto cleanup; } }
;
1728
1729 // Read the number of volume nodes from the mesh
1730#ifdef WIN32
1731 snprintf(filename, PATH_MAX4096, "Flow\\%s%s", projectName, MESHEXTENSION".lb8.ugrid");
1732#else
1733 snprintf(filename, PATH_MAX4096, "Flow/%s%s", projectName, MESHEXTENSION".lb8.ugrid");
1734#endif
1735 fp = aim_fopen(aimInfo, filename, "rb");
1736 if (fp == NULL((void*)0)) {
1737 AIM_ERROR(aimInfo, "Unable to open: %s", filename){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 1737, __func__
, "Unable to open: %s", filename); }
;
1738 status = CAPS_IOERR-332;
1739 goto cleanup;
1740 }
1741 status = fread(&numVolNode, sizeof(int), 1, fp);
1742 if (status != 1) status = CAPS_IOERR-332; else status = CAPS_SUCCESS0;
1743 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1743
, __func__, 0); goto cleanup; }
;
1744 fclose(fp); fp = NULL((void*)0);
1745
1746 AIM_ALLOC(vol2tess, 2*numVolNode, int, aimInfo, status){ if (vol2tess != ((void*)0)) { status = -4; aim_status(aimInfo
, status, "fun3dAIM.c", 1746, __func__, 1, "AIM_ALLOC: %s != NULL"
, "vol2tess"); goto cleanup; } size_t memorysize = 2*numVolNode
; vol2tess = (int *) EG_alloc(memorysize*sizeof(int)); if (vol2tess
== ((void*)0)) { status = -4; aim_status(aimInfo, status, "fun3dAIM.c"
, 1746, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "vol2tess"
, memorysize, "int"); goto cleanup; } }
;
1747 for (i = 0; i < 2*numVolNode; i++) vol2tess[i] = 0;
1748
1749 numNode = 0;
1750 for (ibody = 0; ibody < meshRef->nmap; ibody++) {
1751 EG_statusTessBody(meshRef->maps[ibody].tess, &body, &state, &offset);
1752 numNode += offset;
1753
1754 for (i = 0; i < offset; i++) {
1755 j = meshRef->maps[ibody].map[i];
1756 vol2tess[2*(j-1)+0] = ibody;
1757 vol2tess[2*(j-1)+1] = i;
1758 }
1759 }
1760
1761 // Read <Proj_Name>.sens
1762 snprintf(tmp, 128, "%s%s", projectName, ".sens");
1763 fp = aim_fopen(aimInfo, tmp, "r");
1764 if (fp == NULL((void*)0)) {
1765 AIM_ERROR(aimInfo, "Unable to open: %s", tmp){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 1765, __func__
, "Unable to open: %s", tmp); }
;
1766 status = CAPS_IOERR-332;
1767 goto cleanup;
1768 }
1769
1770 // Number of nodes and functinoals in the file
1771 status = fscanf(fp, "%d", &numFunctional);
1772 if (status != 1) status = CAPS_IOERR-332; else status = CAPS_SUCCESS0;
1773 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1773
, __func__, 0); goto cleanup; }
;
1774
1775 AIM_ALLOC(numPoint, numFunctional, int, aimInfo, status){ if (numPoint != ((void*)0)) { status = -4; aim_status(aimInfo
, status, "fun3dAIM.c", 1775, __func__, 1, "AIM_ALLOC: %s != NULL"
, "numPoint"); goto cleanup; } size_t memorysize = numFunctional
; numPoint = (int *) EG_alloc(memorysize*sizeof(int)); if (numPoint
== ((void*)0)) { status = -4; aim_status(aimInfo, status, "fun3dAIM.c"
, 1775, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "numPoint"
, memorysize, "int"); goto cleanup; } }
;
1776 for (i = 0; i < numFunctional; i++) numPoint[i] = 0;
1777
1778 AIM_ALLOC(functional_map, numFunctional, int*, aimInfo, status){ if (functional_map != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "fun3dAIM.c", 1778, __func__, 1, "AIM_ALLOC: %s != NULL"
, "functional_map"); goto cleanup; } size_t memorysize = numFunctional
; functional_map = (int* *) EG_alloc(memorysize*sizeof(int*))
; if (functional_map == ((void*)0)) { status = -4; aim_status
(aimInfo, status, "fun3dAIM.c", 1778, __func__, 3, "AIM_ALLOC: %s size %zu type %s"
, "functional_map", memorysize, "int*"); goto cleanup; } }
;
1779 for (i = 0; i < numFunctional; i++) functional_map[i] = NULL((void*)0);
1780
1781 AIM_ALLOC(functional_xyz, numFunctional, double*, aimInfo, status){ if (functional_xyz != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "fun3dAIM.c", 1781, __func__, 1, "AIM_ALLOC: %s != NULL"
, "functional_xyz"); goto cleanup; } size_t memorysize = numFunctional
; functional_xyz = (double* *) EG_alloc(memorysize*sizeof(double
*)); if (functional_xyz == ((void*)0)) { status = -4; aim_status
(aimInfo, status, "fun3dAIM.c", 1781, __func__, 3, "AIM_ALLOC: %s size %zu type %s"
, "functional_xyz", memorysize, "double*"); goto cleanup; } }
;
1782 for (i = 0; i < numFunctional; i++) functional_xyz[i] = NULL((void*)0);
1783
1784 AIM_ALLOC(names, numFunctional, char*, aimInfo, status){ if (names != ((void*)0)) { status = -4; aim_status(aimInfo,
status, "fun3dAIM.c", 1784, __func__, 1, "AIM_ALLOC: %s != NULL"
, "names"); goto cleanup; } size_t memorysize = numFunctional
; names = (char* *) EG_alloc(memorysize*sizeof(char*)); if (names
== ((void*)0)) { status = -4; aim_status(aimInfo, status, "fun3dAIM.c"
, 1784, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "names"
, memorysize, "char*"); goto cleanup; } }
;
1785 for (i = 0; i < numFunctional; i++) names[i] = NULL((void*)0);
1786
1787 AIM_ALLOC(values, numFunctional, capsValue, aimInfo, status){ if (values != ((void*)0)) { status = -4; aim_status(aimInfo
, status, "fun3dAIM.c", 1787, __func__, 1, "AIM_ALLOC: %s != NULL"
, "values"); goto cleanup; } size_t memorysize = numFunctional
; values = (capsValue *) EG_alloc(memorysize*sizeof(capsValue
)); if (values == ((void*)0)) { status = -4; aim_status(aimInfo
, status, "fun3dAIM.c", 1787, __func__, 3, "AIM_ALLOC: %s size %zu type %s"
, "values", memorysize, "capsValue"); goto cleanup; } }
;
1788 for (i = 0; i < numFunctional; i++) aim_initValue(&values[i]);
1789
1790 for (i = 0; i < numFunctional; i++) {
1791 values[i].type = DoubleDeriv;
1792
1793 /* allocate derivatives */
1794 AIM_ALLOC(values[i].derivs, fun3dInstance->design.numDesignVariable, capsDeriv, aimInfo, status){ if (values[i].derivs != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "fun3dAIM.c", 1794, __func__, 1, "AIM_ALLOC: %s != NULL"
, "values[i].derivs"); goto cleanup; } size_t memorysize = fun3dInstance
->design.numDesignVariable; values[i].derivs = (capsDeriv *
) EG_alloc(memorysize*sizeof(capsDeriv)); if (values[i].derivs
== ((void*)0)) { status = -4; aim_status(aimInfo, status, "fun3dAIM.c"
, 1794, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "values[i].derivs"
, memorysize, "capsDeriv"); goto cleanup; } }
;
1795 for (idv = 0; idv < fun3dInstance->design.numDesignVariable; idv++) {
1796 values[i].derivs[idv].name = NULL((void*)0);
1797 values[i].derivs[idv].deriv = NULL((void*)0);
1798 values[i].derivs[idv].len_wrt = 0;
1799 }
1800 values[i].nderiv = fun3dInstance->design.numDesignVariable;
1801 }
1802
1803 // Read in Functional name, value and dFunctinoal/dxyz
1804 for (i = 0; i < numFunctional; i++) {
1805
1806 status = fscanf(fp, "%s", tmp);
1807 if (status == EOF(-1)) {
1808 AIM_ERROR(aimInfo, "Failed to read sens file functional name"){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 1808, __func__
, "Failed to read sens file functional name"); }
;
1809 status = CAPS_IOERR-332; goto cleanup;
1810 }
1811
1812 AIM_STRDUP(names[i], tmp, aimInfo, status){ if (names[i] != ((void*)0)) { status = -4; aim_status(aimInfo
, status, "fun3dAIM.c", 1812, __func__, 1, "AIM_STRDUP: %s != NULL!"
, "names[i]"); goto cleanup; } names[i] = EG_strdup(tmp); if (
names[i] == ((void*)0)) { status = -4; aim_status(aimInfo, status
, "fun3dAIM.c", 1812, __func__, 2, "AIM_STRDUP: %s %s", "names[i]"
, tmp); goto cleanup; } }
;
1813
1814 status = fscanf(fp, "%lf", &values[i].vals.real);
1815 if (status == EOF(-1) || status != 1) {
1816 AIM_ERROR(aimInfo, "Failed to read sens file functional value"){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 1816, __func__
, "Failed to read sens file functional value"); }
;
1817 status = CAPS_IOERR-332; goto cleanup;
1818 }
1819
1820 status = fscanf(fp, "%d", &numPoint[i]);
1821 if (status == EOF(-1) || status != 1) {
1822 AIM_ERROR(aimInfo, "Failed to read sens file number of points"){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 1822, __func__
, "Failed to read sens file number of points"); }
;
1823 status = CAPS_IOERR-332; goto cleanup;
1824 }
1825
1826 AIM_ALLOC(functional_map[i], numPoint[i], int , aimInfo, status){ if (functional_map[i] != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "fun3dAIM.c", 1826, __func__, 1, "AIM_ALLOC: %s != NULL"
, "functional_map[i]"); goto cleanup; } size_t memorysize = numPoint
[i]; functional_map[i] = (int *) EG_alloc(memorysize*sizeof(int
)); if (functional_map[i] == ((void*)0)) { status = -4; aim_status
(aimInfo, status, "fun3dAIM.c", 1826, __func__, 3, "AIM_ALLOC: %s size %zu type %s"
, "functional_map[i]", memorysize, "int"); goto cleanup; } }
;
1827 AIM_ALLOC(functional_xyz[i], 3*numPoint[i], double, aimInfo, status){ if (functional_xyz[i] != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "fun3dAIM.c", 1827, __func__, 1, "AIM_ALLOC: %s != NULL"
, "functional_xyz[i]"); goto cleanup; } size_t memorysize = 3
*numPoint[i]; functional_xyz[i] = (double *) EG_alloc(memorysize
*sizeof(double)); if (functional_xyz[i] == ((void*)0)) { status
= -4; aim_status(aimInfo, status, "fun3dAIM.c", 1827, __func__
, 3, "AIM_ALLOC: %s size %zu type %s", "functional_xyz[i]", memorysize
, "double"); goto cleanup; } }
;
1828
1829 for (j = 0; j < numPoint[i]; j++) {
1830 status = fscanf(fp, "%d %lf %lf %lf", &functional_map[i][j],
1831 &functional_xyz[i][3*j+0],
1832 &functional_xyz[i][3*j+1],
1833 &functional_xyz[i][3*j+2]);
1834 if (status == EOF(-1) || status != 4) {
1835 AIM_ERROR(aimInfo, "Failed to read sens file data"){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 1835, __func__
, "Failed to read sens file data"); }
;
1836 status = CAPS_IOERR-332; goto cleanup;
1837 }
1838
1839 if (functional_map[i][j] < 1 || functional_map[i][j] > numVolNode) {
1840 AIM_ERROR(aimInfo, "sens file volume mesh vertex index: %d out-of-range [1-%d]", functional_map[i][j], numVolNode){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 1840, __func__
, "sens file volume mesh vertex index: %d out-of-range [1-%d]"
, functional_map[i][j], numVolNode); }
;
1841 status = CAPS_IOERR-332; goto cleanup;
1842 }
1843 }
1844 }
1845
1846 AIM_ALLOC(dxyz, meshRef->nmap, double*, aimInfo, status){ if (dxyz != ((void*)0)) { status = -4; aim_status(aimInfo, status
, "fun3dAIM.c", 1846, __func__, 1, "AIM_ALLOC: %s != NULL", "dxyz"
); goto cleanup; } size_t memorysize = meshRef->nmap; dxyz
= (double* *) EG_alloc(memorysize*sizeof(double*)); if (dxyz
== ((void*)0)) { status = -4; aim_status(aimInfo, status, "fun3dAIM.c"
, 1846, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "dxyz"
, memorysize, "double*"); goto cleanup; } }
;
1847 for (ibody = 0; ibody < meshRef->nmap; ibody++) dxyz[ibody] = NULL((void*)0);
1848
1849 /* set derivatives */
1850 for (idv = 0; idv < fun3dInstance->design.numDesignVariable; idv++) {
1851
1852 name = fun3dInstance->design.designVariable[idv].name;
1853
1854 // Loop over the geometry in values and compute sensitivities for all bodies
1855 index = aim_getIndex(aimInfo, name, GEOMETRYIN);
1856 status = aim_getValue(aimInfo, index, GEOMETRYIN, &geomInVal);
1857 AIM_STATUS(aimInfo, status, "Design_SensFile only supports geometric sensitivities!")if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1857
, __func__, 1, "Design_SensFile only supports geometric sensitivities!"
); goto cleanup; }
;
1858
1859 for (i = 0; i < numFunctional; i++) {
1860 AIM_STRDUP(values[i].derivs[idv].name, name, aimInfo, status){ if (values[i].derivs[idv].name != ((void*)0)) { status = -4
; aim_status(aimInfo, status, "fun3dAIM.c", 1860, __func__, 1
, "AIM_STRDUP: %s != NULL!", "values[i].derivs[idv].name"); goto
cleanup; } values[i].derivs[idv].name = EG_strdup(name); if (
values[i].derivs[idv].name == ((void*)0)) { status = -4; aim_status
(aimInfo, status, "fun3dAIM.c", 1860, __func__, 2, "AIM_STRDUP: %s %s"
, "values[i].derivs[idv].name", name); goto cleanup; } }
;
1861
1862 AIM_ALLOC(values[i].derivs[idv].deriv, geomInVal->length, double, aimInfo, status){ if (values[i].derivs[idv].deriv != ((void*)0)) { status = -
4; aim_status(aimInfo, status, "fun3dAIM.c", 1862, __func__, 1
, "AIM_ALLOC: %s != NULL", "values[i].derivs[idv].deriv"); goto
cleanup; } size_t memorysize = geomInVal->length; values[
i].derivs[idv].deriv = (double *) EG_alloc(memorysize*sizeof(
double)); if (values[i].derivs[idv].deriv == ((void*)0)) { status
= -4; aim_status(aimInfo, status, "fun3dAIM.c", 1862, __func__
, 3, "AIM_ALLOC: %s size %zu type %s", "values[i].derivs[idv].deriv"
, memorysize, "double"); goto cleanup; } }
;
1863 values[i].derivs[idv].len_wrt = geomInVal->length;
1864 for (j = 0; j < geomInVal->length; j++)
1865 values[i].derivs[idv].deriv[j] = 0;
1866 }
1867
1868 for (irow = 0; irow < geomInVal->nrow; irow++) {
1869 for (icol = 0; icol < geomInVal->ncol; icol++) {
1870
1871 // get the sensitvity for each body
1872 for (ibody = 0; ibody < meshRef->nmap; ibody++) {
1873 status = aim_tessSensitivity(aimInfo,
1874 name,
1875 irow+1, icol+1, // row, col
1876 meshRef->maps[ibody].tess,
1877 &numNode, &dxyz[ibody]);
1878 AIM_STATUS(aimInfo, status, "Sensitivity for: %s\n", name)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1878
, __func__, 2, "Sensitivity for: %s\n", name); goto cleanup; }
;
1879 AIM_NOTNULL(dxyz[ibody], aimInfo, status){ if (dxyz[ibody] == ((void*)0)) { status = -307; aim_status(
aimInfo, status, "fun3dAIM.c", 1879, __func__, 1, "%s == NULL!"
, "dxyz[ibody]"); goto cleanup; } }
;
1880 }
1881
1882 for (i = 0; i < numFunctional; i++) {
1883 functional_dvar = values[i].derivs[idv].deriv[geomInVal->ncol*irow + icol];
1884
1885 for (j = 0; j < numPoint[i]; j++) {
1886 k = functional_map[i][j]-1; // 1-based indexing into volume
1887
1888 ibody = vol2tess[2*k]; // body index
1889 k = vol2tess[2*k+1]; // 0-based surface index
1890 if (k == -1) {
1891 AIM_ERROR(aimInfo, "Volume mesh vertex %d is not on a surface!", functional_map[i][j]){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 1891, __func__
, "Volume mesh vertex %d is not on a surface!", functional_map
[i][j]); }
;
1892 status = CAPS_IOERR-332;
1893 goto cleanup;
1894 }
1895 if ( ibody < 0 || ibody >= meshRef->nmap ) {
1896 AIM_ERROR(aimInfo, "Inconsistent surface node body index: %d should be in [0-%d]", vol2tess[2*k], meshRef->nmap-1){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 1896, __func__
, "Inconsistent surface node body index: %d should be in [0-%d]"
, vol2tess[2*k], meshRef->nmap-1); }
;
1897 status = CAPS_IOERR-332;
1898 goto cleanup;
1899 }
1900
1901 functional_dvar += functional_xyz[i][3*j+0]*dxyz[ibody][3*k + 0] // dx/dGeomIn
1902 + functional_xyz[i][3*j+1]*dxyz[ibody][3*k + 1] // dy/dGeomIn
1903 + functional_xyz[i][3*j+2]*dxyz[ibody][3*k + 2]; // dz/dGeomIn
1904 }
1905 values[i].derivs[idv].deriv[geomInVal->ncol*irow + icol] = functional_dvar;
1906 }
1907
1908 for (ibody = 0; ibody < meshRef->nmap; ibody++)
1909 AIM_FREE(dxyz[ibody]){ EG_free(dxyz[ibody]); dxyz[ibody] = ((void*)0); };
1910 }
1911 }
1912 }
1913
1914 /* create the dynamic output */
1915 for (i = 0; i < numFunctional; i++) {
1916 status = aim_makeDynamicOutput(aimInfo, names[i], &values[i]);
1917 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1917
, __func__, 0); goto cleanup; }
;
1918 }
1919 }
1920
1921cleanup:
1922 if (fp != NULL((void*)0)) fclose(fp);
1923
1924 if (functional_xyz != NULL((void*)0))
1925 for (i = 0; i < numFunctional; i++)
1926 AIM_FREE(functional_xyz[i]){ EG_free(functional_xyz[i]); functional_xyz[i] = ((void*)0);
}
;
1927
1928 if (functional_map != NULL((void*)0))
1929 for (i = 0; i < numFunctional; i++)
1930 AIM_FREE(functional_map[i]){ EG_free(functional_map[i]); functional_map[i] = ((void*)0);
}
;
1931
1932 if (names != NULL((void*)0))
1933 for (i = 0; i < numFunctional; i++)
1934 AIM_FREE(names[i]){ EG_free(names[i]); names[i] = ((void*)0); };
1935
1936 if (dxyz != NULL((void*)0) && meshRef != NULL((void*)0))
1937 for (ibody = 0; ibody < meshRef->nmap; ibody++)
1938 AIM_FREE(dxyz[ibody]){ EG_free(dxyz[ibody]); dxyz[ibody] = ((void*)0); };
1939
1940 AIM_FREE(functional_xyz){ EG_free(functional_xyz); functional_xyz = ((void*)0); };
1941 AIM_FREE(functional_map){ EG_free(functional_map); functional_map = ((void*)0); };
1942 AIM_FREE(vol2tess){ EG_free(vol2tess); vol2tess = ((void*)0); };
1943 AIM_FREE(names){ EG_free(names); names = ((void*)0); };
1944 AIM_FREE(values){ EG_free(values); values = ((void*)0); };
1945 AIM_FREE(dxyz){ EG_free(dxyz); dxyz = ((void*)0); };
1946 AIM_FREE(numPoint){ EG_free(numPoint); numPoint = ((void*)0); };
1947
1948 (void) destroy_cfdBoundaryConditionStruct(&bcProps);
1949
1950 return status;
1951}
1952
1953
1954int aimOutputs(/*@unused@*/ void *instStore, /*@unused@*/ void *aimStruc,
1955 int index, char **aoname, capsValue *form)
1956{
1957
1958 /*! \page aimOutputsFUN3D AIM Outputs
1959 * The following list outlines the FUN3D outputs available through the AIM interface. All variables currently
1960 * correspond to values for all boundaries (total) found in the *.forces file
1961 */
1962
1963#ifdef DEBUG
1964 printf(" fun3dAIM/aimOutputs index = %d!\n", index);
1965#endif
1966
1967 // Total Forces - Pressure + Viscous
1968 if (index == CLtot ) *aoname = EG_strdup("CLtot");
1969 else if (index == CDtot ) *aoname = EG_strdup("CDtot");
1970 else if (index == CMXtot) *aoname = EG_strdup("CMXtot");
1971 else if (index == CMYtot) *aoname = EG_strdup("CMYtot");
1972 else if (index == CMZtot) *aoname = EG_strdup("CMZtot");
1973 else if (index == CXtot ) *aoname = EG_strdup("CXtot");
1974 else if (index == CYtot ) *aoname = EG_strdup("CYtot");
1975 else if (index == CZtot ) *aoname = EG_strdup("CZtot");
1976
1977 /*! \page aimOutputsFUN3D
1978 * Net Forces - Pressure + Viscous:
1979 * - <B>CLtot</B> = The lift coefficient.
1980 * - <B>CDtot</B> = The drag coefficient.
1981 * - <B>CMXtot</B> = The moment coefficient about the x-axis.
1982 * - <B>CMYtot</B> = The moment coefficient about the y-axis.
1983 * - <B>CMZtot</B> = The moment coefficient about the z-axis.
1984 * - <B>CXtot</B> = The force coefficient about the x-axis.
1985 * - <B>CYtot</B> = The force coefficient about the y-axis.
1986 * - <B>CZtot</B> = The force coefficient about the z-axis.
1987 * .
1988 *
1989 */
1990
1991 // Pressure Forces
1992 else if (index == CLtot_p ) *aoname = EG_strdup("CLtot_p");
1993 else if (index == CDtot_p ) *aoname = EG_strdup("CDtot_p");
1994 else if (index == CMXtot_p) *aoname = EG_strdup("CMXtot_p");
1995 else if (index == CMYtot_p) *aoname = EG_strdup("CMYtot_p");
1996 else if (index == CMZtot_p) *aoname = EG_strdup("CMZtot_p");
1997 else if (index == CXtot_p ) *aoname = EG_strdup("CXtot_p");
1998 else if (index == CYtot_p ) *aoname = EG_strdup("CYtot_p");
1999 else if (index == CZtot_p ) *aoname = EG_strdup("CZtot_p");
2000
2001 /*! \page aimOutputsFUN3D
2002 * Pressure Forces:
2003 * - <B>CLtot_p</B> = The lift coefficient - pressure contribution only.
2004 * - <B>CDtot_p</B> = The drag coefficient - pressure contribution only.
2005 * - <B>CMXtot_p</B> = The moment coefficient about the x-axis - pressure contribution only.
2006 * - <B>CMYtot_p</B> = The moment coefficient about the y-axis - pressure contribution only.
2007 * - <B>CMZtot_p</B> = The moment coefficient about the z-axis - pressure contribution only.
2008 * - <B>CXtot_p</B> = The force coefficient about the x-axis - pressure contribution only.
2009 * - <B>CYtot_p</B> = The force coefficient about the y-axis - pressure contribution only.
2010 * - <B>CZtot_p</B> = The force coefficient about the z-axis - pressure contribution only.
2011 * .
2012 *
2013 */
2014
2015 // Viscous Forces
2016 else if (index == CLtot_v ) *aoname = EG_strdup("CLtot_v");
2017 else if (index == CDtot_v ) *aoname = EG_strdup("CDtot_v");
2018 else if (index == CMXtot_v) *aoname = EG_strdup("CMXtot_v");
2019 else if (index == CMYtot_v) *aoname = EG_strdup("CMYtot_v");
2020 else if (index == CMZtot_v) *aoname = EG_strdup("CMZtot_v");
2021 else if (index == CXtot_v ) *aoname = EG_strdup("CXtot_v");
2022 else if (index == CYtot_v ) *aoname = EG_strdup("CYtot_v");
2023 else if (index == CZtot_v ) *aoname = EG_strdup("CZtot_v");
2024
2025 /*! \page aimOutputsFUN3D
2026 * Viscous Forces:
2027 * - <B>CLtot_v</B> = The lift coefficient - viscous contribution only.
2028 * - <B>CDtot_v</B> = The drag coefficient - viscous contribution only.
2029 * - <B>CMXtot_v</B> = The moment coefficient about the x-axis - viscous contribution only.
2030 * - <B>CMYtot_v</B> = The moment coefficient about the y-axis - viscous contribution only.
2031 * - <B>CMZtot_v</B> = The moment coefficient about the z-axis - viscous contribution only.
2032 * - <B>CXtot_v</B> = The force coefficient about the x-axis - viscous contribution only.
2033 * - <B>CYtot_v</B> = The force coefficient about the y-axis - viscous contribution only.
2034 * - <B>CZtot_v</B> = The force coefficient about the z-axis - viscous contribution only.
2035 */
2036 else if (index == Forces) {
2037 *aoname = EG_strdup("Forces");
2038 form->type = Tuple;
2039 form->nullVal = IsNull;
2040 //defval->units = NULL;
2041 form->dim = Vector;
2042 form->lfixed = Change;
2043 form->vals.tuple = NULL((void*)0);
2044
2045 /*! \page aimOutputsFUN3D
2046 * Force components:
2047 * - <B>Forces</B> = Returns a tuple array of JSON string dictionaries of forces and moments for each boundary (combined
2048 * forces also included). The structure for the Forces tuple = ("Boundary Name", "Value").
2049 * "Boundary Name" defines the boundary/component name (or "Total") and the "Value" is a JSON string dictionary. Entries
2050 * in the dictionary are the same as the other output variables without "tot" in the
2051 * name (e.g. CL, CD, CMX, CL_p, CMX_v, etc.).
2052 */
2053
2054 } else {
2055 printf(" fun3dAIM/aimOutputs index = %d NOT Found!\n", index);
2056 return CAPS_NOTFOUND-303;
2057 }
2058
2059 if (index < Forces) {
2060 form->type = Double;
2061 form->dim = Vector;
2062 form->nrow = 1;
2063 form->ncol = 1;
2064 form->units = NULL((void*)0);
2065 form->nullVal = IsNull;
2066
2067 form->vals.reals = NULL((void*)0);
2068 form->vals.real = 0;
2069 }
2070
2071 return CAPS_SUCCESS0;
2072}
2073
2074
2075static int fun3d_readForcesJSON(void *aimInfo,
2076 FILE *fp, mapAttrToIndexStruct *attrMap,
2077 capsValue *val)
2078{
2079 int status = CAPS_SUCCESS0; // Function return status
2080
2081 size_t linecap = 0;
2082
2083 char *line = NULL((void*)0); // Temporary line holder
2084 char *strValue;
2085 char *newLine;
2086 const char *keyWord = NULL((void*)0);
2087
2088 char lineVal[80];
2089 char json[9*80 + 5];
2090 char num1[15], num2[15], num3[15];
2091
2092 char *title = "FORCE SUMMARY FOR BOUNDARY";
2093 char *titleTot = "FORCE TOTALS FOR ALL BOUNDARIES";
2094 char name[80];
2095 int nameIndex;
2096
2097 int i = 7, j = 30, k = 53;
2098
2099 if (fp == NULL((void*)0)) {
2100 status = CAPS_NULLVALUE-307;
2101 goto cleanup;
2102 }
2103
2104 if (attrMap == NULL((void*)0)) {
2105 status = CAPS_NULLVALUE-307;
2106 goto cleanup;
2107 }
2108
2109 if (val == NULL((void*)0)) {
2110 status = CAPS_NULLVALUE-307;
2111 goto cleanup;
2112 }
2113
2114 val->nrow = 0;
2115 val->vals.tuple = NULL((void*)0);
2116
2117 while (getline(&line, &linecap, fp) >= 0) {
2118
2119 if (line == NULL((void*)0)) continue;
2120
2121 strValue = strstr(line, title);
2122
2123 if ( (strValue != NULL((void*)0)) || (strstr(line, titleTot) != NULL((void*)0)) ){
2124
2125 if (strValue != NULL((void*)0)) {
2126
2127 sprintf(name, "%s", &strValue[strlen(title)+1]);
2128 if ( (newLine = strchr(name, '\n')) != NULL((void*)0)) *newLine = '\0';
2129
2130 } else {
2131
2132 sprintf(name, "%s", "Total");
2133 }
2134
2135 AIM_REALL(val->vals.tuple, val->nrow+1, capsTuple, aimInfo, status){ size_t memorysize = val->nrow+1; val->vals.tuple = (capsTuple
*) EG_reall(val->vals.tuple, memorysize*sizeof(capsTuple)
); if (val->vals.tuple == ((void*)0)) { status = -4; aim_status
(aimInfo, status, "fun3dAIM.c", 2135, __func__, 3, "AIM_REALL: %s size %zu type %s"
, "val->vals.tuple", memorysize, "capsTuple"); goto cleanup
; } }
;
2136 val->nrow += 1;
2137
2138 val->nullVal = NotNull;
2139 val->vals.tuple[val->nrow -1 ].name = NULL((void*)0);
2140 val->vals.tuple[val->nrow -1 ].value = NULL((void*)0);
2141
2142 // Initiate JSON string
2143 sprintf(json, "{");
2144
2145 if (strValue != NULL((void*)0)) {
2146 status = getline(&line, &linecap, fp); //Skip line - "Boundary type"
2147 if (status <=0) goto cleanup;
2148 }
2149
2150 status = getline(&line, &linecap, fp); //Skip line - "----"
2151 if (status <=0) goto cleanup;
2152
2153 status = getline(&line, &linecap, fp); //Skip line - "Pressure forces"
2154 if (status <=0) goto cleanup;
2155
2156 status = getline(&line, &linecap, fp);
2157 if (status <=0) goto cleanup;
2158
2159 strncpy(num1, &line[i], 14); num1[14] = '\0';
2160 strncpy(num2, &line[j], 14); num2[14] = '\0';
2161
2162 sprintf(lineVal, "\"%s\":%s,\"%s\":%s,","CL_p", num1, "CD_p", num2);
2163 strcat(json, lineVal); // Add to JSON string
2164
2165 status = getline(&line, &linecap, fp);
2166 if (status <=0) goto cleanup;
2167
2168 strncpy(num1, &line[i], 14); num1[14] = '\0';
2169 strncpy(num2, &line[j], 14); num2[14] = '\0';
2170 strncpy(num3, &line[k], 14); num3[14] = '\0';
2171
2172 sprintf(lineVal, "\"%s\":%s,\"%s\":%s,\"%s\":%s,",
2173 "CMX_p", num1, "CMY_p", num2, "CMZ_p", num3);
2174 strcat(json, lineVal); // Add to JSON string
2175
2176 status = getline(&line, &linecap, fp);
2177 if (status <=0) goto cleanup;
2178
2179 strncpy(num1, &line[i], 14); num1[14] = '\0';
2180 strncpy(num2, &line[j], 14); num2[14] = '\0';
2181 strncpy(num3, &line[k], 14); num3[14] = '\0';
2182
2183 sprintf(lineVal, "\"%s\":%s,\"%s\":%s,\"%s\":%s,",
2184 "CX_p", num1, "CY_p", num2, "CZ_p", num3);
2185 strcat(json, lineVal); // Add to JSON string
2186
2187 status = getline(&line, &linecap, fp); //Skip line - "Viscous forces"
2188 if (status <=0) goto cleanup;
2189
2190 status = getline(&line, &linecap, fp);
2191 if (status <=0) goto cleanup;
2192
2193 strncpy(num1, &line[i], 14); num1[14] = '\0';
2194 strncpy(num2, &line[j], 14); num2[14] = '\0';
2195
2196 sprintf(lineVal, "\"%s\":%s,\"%s\":%s,","CL_v", num1, "CD_v", num2);
2197 strcat(json,lineVal); // Add to JSON string
2198
2199 status = getline(&line, &linecap, fp);
2200 if (status <=0) goto cleanup;
2201
2202 strncpy(num1, &line[i], 14); num1[14] = '\0';
2203 strncpy(num2, &line[j], 14); num2[14] = '\0';
2204 strncpy(num3, &line[k], 14); num3[14] = '\0';
2205
2206 sprintf(lineVal, "\"%s\":%s,\"%s\":%s,\"%s\":%s,",
2207 "CMX_v", num1, "CMY_v", num2, "CMZ_v", num3);
2208 strcat(json,lineVal); // Add to JSON string
2209
2210 status = getline(&line, &linecap, fp);
2211 if (status <=0) goto cleanup;
2212
2213 strncpy(num1, &line[i], 14); num1[14] = '\0';
2214 strncpy(num2, &line[j], 14); num2[14] = '\0';
2215 strncpy(num3, &line[k], 14); num3[14] = '\0';
2216
2217 sprintf(lineVal, "\"%s\":%s,\"%s\":%s,\"%s\":%s,",
2218 "CX_v", num1, "CY_v", num2, "CZ_v", num3);
2219 strcat(json,lineVal); // Add to JSON string
2220
2221 status = getline(&line, &linecap, fp); //Skip line - "Total forces"
2222 if (status <=0) goto cleanup;
2223
2224 status = getline(&line, &linecap, fp);
2225 if (status <=0) goto cleanup;
2226
2227 strncpy(num1, &line[i], 14); num1[14] = '\0';
2228 strncpy(num2, &line[j], 14); num2[14] = '\0';
2229
2230 sprintf(lineVal, "\"%s\":%s,\"%s\":%s,","CL", num1, "CD", num2);
2231 strcat(json,lineVal); // Add to JSON string
2232
2233 status = getline(&line, &linecap, fp);
2234 if (status <=0) goto cleanup;
2235
2236 strncpy(num1, &line[i], 14); num1[14] = '\0';
2237 strncpy(num2, &line[j], 14); num2[14] = '\0';
2238 strncpy(num3, &line[k], 14); num3[14] = '\0';
2239
2240 sprintf(lineVal, "\"%s\":%s,\"%s\":%s,\"%s\":%s,",
2241 "CMX", num1, "CMY", num2, "CMZ", num3);
2242 strcat(json,lineVal); // Add to JSON string
2243
2244 status = getline(&line, &linecap, fp);
2245 if (status <=0) goto cleanup;
2246
2247 strncpy(num1, &line[i], 14); num1[14] = '\0';
2248 strncpy(num2, &line[j], 14); num2[14] = '\0';
2249 strncpy(num3, &line[k], 14); num3[14] = '\0';
2250
2251 sprintf(lineVal, "\"%s\":%s,\"%s\":%s,\"%s\":%s",
2252 "CX", num1, "CY", num2, "CZ", num3);
2253 strcat(json,lineVal); // Add to JSON string
2254
2255 strcat(json,"}");
2256
2257// printf("JSON = %s\n", json);
2258
2259 if (strcmp(name, "Total") != 0) {
2260 status = string_toInteger(name, &nameIndex);
2261 if (status != CAPS_SUCCESS0) goto cleanup;
2262 } else {
2263 nameIndex = -1;
2264 }
2265
2266 status = get_mapAttrToIndexKeyword(attrMap, nameIndex, &keyWord);
2267 if (status == CAPS_SUCCESS0) {
2268 AIM_STRDUP(val->vals.tuple[val->nrow-1].name, keyWord, aimInfo, status){ if (val->vals.tuple[val->nrow-1].name != ((void*)0)) {
status = -4; aim_status(aimInfo, status, "fun3dAIM.c", 2268,
__func__, 1, "AIM_STRDUP: %s != NULL!", "val->vals.tuple[val->nrow-1].name"
); goto cleanup; } val->vals.tuple[val->nrow-1].name = EG_strdup
(keyWord); if (val->vals.tuple[val->nrow-1].name == ((void
*)0)) { status = -4; aim_status(aimInfo, status, "fun3dAIM.c"
, 2268, __func__, 2, "AIM_STRDUP: %s %s", "val->vals.tuple[val->nrow-1].name"
, keyWord); goto cleanup; } }
;
2269 } else {
2270 AIM_STRDUP(val->vals.tuple[val->nrow-1].name, name, aimInfo, status){ if (val->vals.tuple[val->nrow-1].name != ((void*)0)) {
status = -4; aim_status(aimInfo, status, "fun3dAIM.c", 2270,
__func__, 1, "AIM_STRDUP: %s != NULL!", "val->vals.tuple[val->nrow-1].name"
); goto cleanup; } val->vals.tuple[val->nrow-1].name = EG_strdup
(name); if (val->vals.tuple[val->nrow-1].name == ((void
*)0)) { status = -4; aim_status(aimInfo, status, "fun3dAIM.c"
, 2270, __func__, 2, "AIM_STRDUP: %s %s", "val->vals.tuple[val->nrow-1].name"
, name); goto cleanup; } }
;
2271 }
2272
2273 AIM_STRDUP(val->vals.tuple[val->nrow-1].value, json, aimInfo, status){ if (val->vals.tuple[val->nrow-1].value != ((void*)0))
{ status = -4; aim_status(aimInfo, status, "fun3dAIM.c", 2273
, __func__, 1, "AIM_STRDUP: %s != NULL!", "val->vals.tuple[val->nrow-1].value"
); goto cleanup; } val->vals.tuple[val->nrow-1].value =
EG_strdup(json); if (val->vals.tuple[val->nrow-1].value
== ((void*)0)) { status = -4; aim_status(aimInfo, status, "fun3dAIM.c"
, 2273, __func__, 2, "AIM_STRDUP: %s %s", "val->vals.tuple[val->nrow-1].value"
, json); goto cleanup; } }
;
2274
2275 // Reset name index value in case we have totals next
2276 nameIndex = 0;
2277 }
2278 }
2279
2280 status = CAPS_SUCCESS0;
2281
2282cleanup:
2283 if (status != CAPS_SUCCESS0)
2284 printf("Premature exit in fun3dAIM fun3d_readForcesJSON status = %d\n",
2285 status);
2286
2287 if (line != NULL((void*)0)) EG_free(line);
2288
2289 return status;
2290}
2291
2292
2293static int fun3d_readForces(void *aimInfo, FILE *fp, int index, capsValue *val)
2294{
2295
2296 int status; // Function return
2297
2298 size_t linecap = 0;
2299
2300 char *strKeyword = NULL((void*)0), *bndSectionKeyword = NULL((void*)0), *bndSubSectionKeyword = NULL((void*)0); // Keyword strings
2301
2302 char *strValue; // Holder string for value of keyword
2303 char *line = NULL((void*)0); // Temporary line holder
2304
2305 int bndSectionFound = (int) false0;
2306 int bndSubSectionFound = (int) false0;
2307
2308 if (fp == NULL((void*)0)) {
2309 status = CAPS_NULLVALUE-307;
2310 goto cleanup;
2311 }
2312
2313 if (val == NULL((void*)0)) {
2314 status = CAPS_NULLVALUE-307;
2315 goto cleanup;
2316 }
2317
2318 // Set the "search" string(s)
2319 if (index <= CZtot) {
2320
2321 bndSectionKeyword = (char *) " FORCE TOTALS FOR ALL BOUNDARIES\n";
2322 bndSubSectionKeyword = (char *) " Total forces\n";
2323
2324 } else if (index <= CZtot_p) {
2325
2326 bndSectionKeyword = (char *) " FORCE TOTALS FOR ALL BOUNDARIES\n";
2327 bndSubSectionKeyword = (char *) " Pressure forces\n";
2328
2329 } else if (index <= CZtot_v) {
2330
2331 bndSectionKeyword = (char *) " FORCE TOTALS FOR ALL BOUNDARIES\n";
2332 bndSubSectionKeyword = (char *) " Viscous forces\n";
2333 } else if (index == Forces) {
2334 bndSectionKeyword = (char *) "FORCE SUMMARY FOR BOUNDARY";
2335 } else {
2336 AIM_ERROR(aimInfo, "Developer error: Bad index %d", index){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 2336, __func__
, "Developer error: Bad index %d", index); }
;
2337 status = CAPS_NOTIMPLEMENT-334;
2338 goto cleanup;
2339 }
2340
2341 if (index == CLtot || index == CLtot_p || index == CLtot_v ) strKeyword = (char *) "Cl =";
2342 else if (index == CDtot || index == CDtot_p || index == CDtot_v ) strKeyword = (char *) "Cd =";
2343 else if (index == CMXtot || index == CMXtot_p || index == CMXtot_v) strKeyword = (char *) "Cmx =";
2344 else if (index == CMYtot || index == CMYtot_p || index == CMYtot_v) strKeyword = (char *) "Cmy =";
2345 else if (index == CMZtot || index == CMZtot_p || index == CMZtot_v) strKeyword = (char *) "Cmz =";
2346 else if (index == CXtot || index == CXtot_p || index == CXtot_v ) strKeyword = (char *) "Cx =";
2347 else if (index == CYtot || index == CYtot_p || index == CYtot_v ) strKeyword = (char *) "Cy =";
2348 else if (index == CZtot || index == CZtot_p || index == CZtot_v ) strKeyword = (char *) "Cz =";
2349 else {
2350 AIM_ERROR(aimInfo, "Unrecognized output variable index - %d\n", index){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 2350, __func__
, "Unrecognized output variable index - %d\n", index); }
;
2351 return CAPS_BADINDEX-304;
2352 }
2353
2354 // Scan the file for the string
2355 strValue = NULL((void*)0);
2356 while (getline(&line, &linecap, fp) >= 0) {
2357
2358 if (line == NULL((void*)0)) continue;
2359
2360 if (strcmp(line, bndSectionKeyword) == 0 && bndSectionFound == (int) false0) {
2361
2362 //printf("FOUND section\n");
2363 bndSectionFound = (int) true1;
2364 continue; // Skip to next line
2365 }
2366
2367 if (bndSubSectionKeyword != NULL((void*)0))
2368 if (strcmp(line, bndSubSectionKeyword) == 0 &&
2369 bndSectionFound == (int) true1 && bndSubSectionFound == (int) false0) {
2370
2371 //printf("Found sub-sections\n");
2372 bndSubSectionFound = (int) true1;
2373 continue; // Skipe to next line
2374 }
2375
2376 if (bndSectionFound == (int) true1 && bndSubSectionFound == (int) true1){
2377
2378 strValue = strstr(line, strKeyword);
2379
2380 if (strValue != NULL((void*)0)) {
2381
2382 //printf("String value %s\n", strValue);
2383
2384 // Found it -- get the value
2385
2386 status = string_toDouble(&strValue[6], &val->vals.real);
2387 if (status != CAPS_SUCCESS0) goto cleanup;
2388 val->nullVal = NotNull;
2389
2390 break;
2391 }
2392 }
2393 }
2394
2395 if (strValue == NULL((void*)0)) {
2396 AIM_ERROR(aimInfo, "Failed to find %s in .forces file", bndSectionKeyword){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 2396, __func__
, "Failed to find %s in .forces file", bndSectionKeyword); }
;
2397 status = CAPS_NOTFOUND-303;
2398 goto cleanup;
2399 }
2400
2401 status = CAPS_SUCCESS0;
2402
2403cleanup:
2404
2405 if (line != NULL((void*)0)) EG_free(line);
2406
2407 return status;
2408}
2409
2410
2411// Calculate FUN3D output
2412int aimCalcOutput(void *instStore, /*@unused@*/ void *aimInfo, int index,
2413 capsValue *val)
2414{
2415 int status = CAPS_SUCCESS0;
2416
2417 char filename[PATH_MAX4096]; // File to open
2418 char fileExtension[] = ".forces";
2419 capsValue *ProjName=NULL((void*)0);
2420 const char *projectName =NULL((void*)0);
2421
2422 FILE *fp = NULL((void*)0); // File pointer
2423 capsValue *design_functional=NULL((void*)0), *design_sensfile=NULL((void*)0);
2424 aimStorage *fun3dInstance;
2425
2426 fun3dInstance = (aimStorage *) instStore;
2427
2428 status = aim_getValue(aimInfo, Proj_Name, ANALYSISIN, &ProjName);
2429 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 2429
, __func__, 0); goto cleanup; }
;
2430 projectName = ProjName->vals.string;
2431
2432 val->vals.real = 0.0; // Set default value
2433
2434 if (index <= Forces) {
2435 // Open fun3d *.force file
2436 status = aim_getValue(aimInfo, Design_Functional, ANALYSISIN, &design_functional);
2437 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 2437
, __func__, 0); goto cleanup; }
;
2438 AIM_NOTNULL(design_functional, aimInfo, status){ if (design_functional == ((void*)0)) { status = -307; aim_status
(aimInfo, status, "fun3dAIM.c", 2438, __func__, 1, "%s == NULL!"
, "design_functional"); goto cleanup; } }
;
2439
2440 status = aim_getValue(aimInfo, Design_SensFile, ANALYSISIN, &design_sensfile);
2441 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 2441
, __func__, 0); goto cleanup; }
;
2442 AIM_NOTNULL(design_sensfile, aimInfo, status){ if (design_sensfile == ((void*)0)) { status = -307; aim_status
(aimInfo, status, "fun3dAIM.c", 2442, __func__, 1, "%s == NULL!"
, "design_sensfile"); goto cleanup; } }
;
2443
2444 if (design_functional->nullVal == NotNull ||
2445 design_sensfile->vals.integer == (int) true1) {
2446#ifdef WIN32
2447 snprintf(filename, PATH_MAX4096, "Flow\\%s%s", projectName, fileExtension);
2448#else
2449 snprintf(filename, PATH_MAX4096, "Flow/%s%s", projectName, fileExtension);
2450#endif
2451 } else {
2452 snprintf(filename, PATH_MAX4096, "%s%s", projectName, fileExtension);
2453 }
2454
2455 fp = aim_fopen(aimInfo, filename, "r");
2456 if (fp == NULL((void*)0)) {
2457 AIM_ERROR(aimInfo, "Could not open file: %s", filename){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 2457, __func__
, "Could not open file: %s", filename); }
;
2458 status = CAPS_IOERR-332;
2459 goto cleanup;
2460 }
2461
2462 if (index < Forces) {
2463 status = fun3d_readForces(aimInfo, fp, index, val);
2464 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 2464
, __func__, 0); goto cleanup; }
;
2465
2466 } else if (index == Forces) {
2467 status = fun3d_readForcesJSON(aimInfo, fp, &fun3dInstance->groupMap, val);
2468 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 2468
, __func__, 0); goto cleanup; }
;
2469 }
2470
2471 } else {
2472 AIM_ERROR(aimInfo, "Unknown output index %d", index){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 2472, __func__
, "Unknown output index %d", index); }
;
2473 status = CAPS_BADINDEX-304;
2474 goto cleanup;
2475 }
2476
2477 status = CAPS_SUCCESS0;
2478
2479cleanup:
2480
2481 if (fp != NULL((void*)0)) fclose(fp);
2482
2483 return status;
2484}
2485
2486
2487void aimCleanup(void *instStore)
2488{
2489 aimStorage *fun3dInstance;
2490
2491#ifdef DEBUG
2492 printf(" fun3dAIM/aimCleanup!\n");
2493
2494#endif
2495 fun3dInstance = (aimStorage *) instStore;
2496
2497 // Clean up fun3dInstance data
2498
2499 // Attribute to index map
2500 (void) destroy_mapAttrToIndexStruct(&fun3dInstance->groupMap);
2501 //status = destroy_mapAttrToIndexStruct(&fun3dInstance->attrMap);
2502 //if (status != CAPS_SUCCESS) return status;
2503
2504 // Pointer to caps input value for scaling pressure during data transfer
2505 fun3dInstance->pressureScaleFactor = NULL((void*)0);
2506
2507 // Pointer to caps input value for offset pressure during data transfer
2508 fun3dInstance->pressureScaleOffset = NULL((void*)0);
2509
2510 // Design information
2511 (void) destroy_cfdDesignStruct(&fun3dInstance->design);
2512
2513 // Cleanup units
2514 destroy_cfdUnitsStruct(&fun3dInstance->units);
2515
2516 EG_free(fun3dInstance);
2517}
2518
2519
2520/************************************************************************/
2521// CAPS transferring functions
2522
2523void aimFreeDiscrPtr(void *ptrm)
2524{
2525#ifdef DEBUG
2526 printf(" fun3dAIM/aimFreeDiscr!\n");
2527#endif
2528
2529 /* free up this capsDiscr user pointer */
2530 AIM_FREE(ptrm){ EG_free(ptrm); ptrm = ((void*)0); };
2531}
2532
2533
2534int aimDiscr(char *tname, capsDiscr *discr)
2535{
2536
2537 int i; // Indexing
2538
2539 int status; // Function return status
2540
2541 int numBody;
2542
2543 // EGADS objects
2544 ego *bodies = NULL((void*)0), *tess = NULL((void*)0);
2545
2546 const char *intents;
2547 capsValue *meshVal;
2548
2549 // Volume Mesh obtained from meshing AIM
2550 aimMeshRef *meshRef;
2551
2552 aimStorage *fun3dInstance;
2553
2554 fun3dInstance = (aimStorage *) discr->instStore;
2555
2556#ifdef DEBUG
2557 printf(" fun3dAIM/aimDiscr: tname = %s!\n", tname);
2558#endif
2559
2560 if (tname == NULL((void*)0)) return CAPS_NOTFOUND-303;
2561
2562 // Currently this ONLY works if the capsTranfer lives on single body!
2563 status = aim_getBodies(discr->aInfo, &intents, &numBody, &bodies);
2564 if (status != CAPS_SUCCESS0) {
2565 printf(" fun3dAIM/aimDiscr: aim_getBodies = %d!\n", status);
2566 return status;
2567 }
2568 if (bodies == NULL((void*)0)) {
2569 AIM_ERROR(discr->aInfo, " fun3dAIM/aimDiscr: NULL Bodies!\n"){ aim_message(discr->aInfo, CERROR, 0 , "fun3dAIM.c", 2569
, __func__, " fun3dAIM/aimDiscr: NULL Bodies!\n"); }
;
2570 return CAPS_NULLOBJ-309;
2571 }
2572
2573
2574 // Get the mesh Value
2575 status = aim_getValue(discr->aInfo, Mesh, ANALYSISIN, &meshVal);
2576 AIM_STATUS(discr->aInfo, status)if (status != 0) { aim_status(discr->aInfo, status, "fun3dAIM.c"
, 2576, __func__, 0); goto cleanup; }
;
2577
2578 if (meshVal->nullVal == IsNull) {
2579 AIM_ANALYSISIN_ERROR(discr->aInfo, Mesh, "'Mesh' input must be linked to an output 'Area_Mesh' or 'Volume_Mesh'"){ aim_message(discr->aInfo, CERROR, Mesh, "fun3dAIM.c", 2579
, __func__, "'Mesh' input must be linked to an output 'Area_Mesh' or 'Volume_Mesh'"
); }
;
2580 status = CAPS_BADVALUE-311;
2581 goto cleanup;
2582 }
2583
2584 // Get mesh
2585 meshRef = (aimMeshRef *)meshVal->vals.AIMptr;
2586 AIM_NOTNULL(meshRef, discr->aInfo, status){ if (meshRef == ((void*)0)) { status = -307; aim_status(discr
->aInfo, status, "fun3dAIM.c", 2586, __func__, 1, "%s == NULL!"
, "meshRef"); goto cleanup; } }
;
2587
2588 if (meshRef->nmap == 0) {
2589 AIM_ERROR(discr->aInfo, "No surface meshes in volume mesh - data transfer isn't possible.\n"){ aim_message(discr->aInfo, CERROR, 0 , "fun3dAIM.c", 2589
, __func__, "No surface meshes in volume mesh - data transfer isn't possible.\n"
); }
;
2590 status = CAPS_BADVALUE-311;
2591 goto cleanup;
2592 }
2593
2594 if (aim_newGeometry(discr->aInfo) == CAPS_SUCCESS0 &&
2595 fun3dInstance->groupMap.numAttribute == 0) {
2596 // Get capsGroup name and index mapping to make sure all faces have a capsGroup value
2597 status = create_CAPSGroupAttrToIndexMap(numBody,
2598 bodies,
2599 1, // Only search down to the face level of the EGADS body
2600 &fun3dInstance->groupMap);
2601 AIM_STATUS(discr->aInfo, status)if (status != 0) { aim_status(discr->aInfo, status, "fun3dAIM.c"
, 2601, __func__, 0); goto cleanup; }
;
2602 }
2603
2604 // Lets check the volume mesh
2605
2606 // Do we have an individual surface mesh for each body
2607 if (meshRef->nmap != numBody) {
2608 AIM_ERROR( discr->aInfo, "Number of surface mesh in the linked volume mesh (%d) does not match the number"){ aim_message(discr->aInfo, CERROR, 0 , "fun3dAIM.c", 2608
, __func__, "Number of surface mesh in the linked volume mesh (%d) does not match the number"
); }
;
2609 AIM_ADDLINE(discr->aInfo,"of bodies (%d) - data transfer is NOT possible.", meshRef->nmap,numBody){ aim_addLine(discr->aInfo, "of bodies (%d) - data transfer is NOT possible."
, meshRef->nmap,numBody); }
;
2610 status = CAPS_MISMATCH-324;
2611 goto cleanup;
2612 }
2613
2614 // To this point is doesn't appear that the volume mesh has done anything bad to our surface mesh(es)
2615
2616 // Lets store away our tessellation now
2617 AIM_ALLOC(tess, meshRef->nmap, ego, discr->aInfo, status){ if (tess != ((void*)0)) { status = -4; aim_status(discr->
aInfo, status, "fun3dAIM.c", 2617, __func__, 1, "AIM_ALLOC: %s != NULL"
, "tess"); goto cleanup; } size_t memorysize = meshRef->nmap
; tess = (ego *) EG_alloc(memorysize*sizeof(ego)); if (tess ==
((void*)0)) { status = -4; aim_status(discr->aInfo, status
, "fun3dAIM.c", 2617, __func__, 3, "AIM_ALLOC: %s size %zu type %s"
, "tess", memorysize, "ego"); goto cleanup; } }
;
2618 for (i = 0; i < meshRef->nmap; i++) {
2619 tess[i] = meshRef->maps[i].tess;
2620 }
2621
2622 status = mesh_fillDiscr(tname, &fun3dInstance->groupMap, meshRef->nmap, tess, discr);
2623 AIM_STATUS(discr->aInfo, status)if (status != 0) { aim_status(discr->aInfo, status, "fun3dAIM.c"
, 2623, __func__, 0); goto cleanup; }
;
2624
2625#ifdef DEBUG
2626 printf(" fun3dAIM/aimDiscr: Finished!!\n");
2627#endif
2628
2629 status = CAPS_SUCCESS0;
2630
2631cleanup:
2632 AIM_FREE(tess){ EG_free(tess); tess = ((void*)0); };
2633 return status;
2634}
2635
2636
2637int
2638aimLocateElement(capsDiscr *discr, double *params, double *param,
2639 int *bIndex, int *eIndex, double *bary)
2640{
2641 return aim_locateElement(discr, params, param, bIndex, eIndex, bary);
2642}
2643
2644
2645int aimTransfer(capsDiscr *discr, const char *dataName, int numPoint,
2646 int dataRank, double *dataVal, /*@unused@*/ char **units)
2647{
2648 /*! \page dataTransferFUN3D FUN3D Data Transfer
2649 *
2650 * The FUN3D AIM has the ability to transfer surface data (e.g. pressure distributions) to and from the AIM
2651 * using the conservative and interpolative data transfer schemes in CAPS. Currently these transfers may only
2652 * take place on triangular meshes.
2653 *
2654 * \section dataFromFUN3D Data transfer from FUN3D (FieldOut)
2655 *
2656 * <ul>
2657 * <li> <B>"Pressure", "P", "Cp", or "CoefficientOfPressure"</B> </li> <br>
2658 * Loads the coefficient of pressure distribution from [project_name]_ddfdrive_bndry[#].dat file(s)
2659 * (as generate from a FUN3D command line option of -\-write_aero_loads_to_file) into the data
2660 * transfer scheme. This distribution may be scaled based on
2661 * Pressure = Pressure_Scale_Factor*Cp + Pressure_Scale_Offset, where "Pressure_Scale_Factor"
2662 * and "Pressure_Scale_Offset" are AIM inputs (\ref aimInputsFUN3D).
2663 * </ul>
2664 *
2665 */ // Rest of this block comes from fun3dUtil.c
2666
2667 int status, status2; // Function return status
2668 int i, j, dataPoint, capsGroupIndex, bIndex; // Indexing
2669 aimStorage *fun3dInstance;
2670
2671 // Aero-Load data variables
2672 int numVariable;
1
'numVariable' declared without an initial value
2673 int numDataPoint;
2674 char **variableName = NULL((void*)0);
2675 double **dataMatrix = NULL((void*)0);
2676 double dataScaleFactor = 1.0;
2677 double dataScaleOffset = 0.0;
2678 //char *dataUnits = NULL;
2679
2680 // Indexing in data variables
2681 int globalIDIndex = -99;
2682 int variableIndex = -99;
2683
2684 // Variables used in global node mapping
2685 int *storage;
2686 int globalNodeID;
2687 int found = (int) false0;
2688
2689 // Filename stuff
2690 int *capsGroupList;
2691 char *filename = NULL((void*)0); //"pyCAPS_FUN3D_Tetgen_ddfdrive_bndry1.dat";
2692 capsValue *ProjName=NULL((void*)0);
2693 const char *projectName =NULL((void*)0);
2694
2695#ifdef DEBUG
2696 printf(" fun3dAIM/aimTransfer name = %s npts = %d/%d!\n",
2697 dataName, numPoint, dataRank);
2698#endif
2699
2700 fun3dInstance = (aimStorage *) discr->instStore;
2701
2702 if (strcasecmp(dataName, "Pressure") != 0 &&
2703 strcasecmp(dataName, "P") != 0 &&
2704 strcasecmp(dataName, "Cp") != 0 &&
2705 strcasecmp(dataName, "CoefficientOfPressure") != 0) {
2706
2707 printf("Unrecognized data transfer variable - %s\n", dataName);
2708 return CAPS_NOTFOUND-303;
2709 }
2710
2711 status = aim_getValue(discr->aInfo, Proj_Name, ANALYSISIN, &ProjName);
2712 AIM_STATUS(discr->aInfo, status)if (status != 0) { aim_status(discr->aInfo, status, "fun3dAIM.c"
, 2712, __func__, 0); goto cleanup; }
;
2
Assuming 'status' is not equal to 0
3
Taking true branch
4
Control jumps to line 2865
2713 projectName = ProjName->vals.string;
2714
2715 //Get the appropriate parts of the tessellation to data
2716 storage = (int *) discr->ptrm;
2717 capsGroupList = &storage[0]; // List of boundary ID (attrMap) in the transfer
2718
2719 // Zero out data
2720 for (i = 0; i < numPoint; i++) {
2721 for (j = 0; j < dataRank; j++ ) {
2722 dataVal[dataRank*i+j] = 0;
2723 }
2724 }
2725
2726 for (capsGroupIndex = 0; capsGroupIndex < capsGroupList[0]; capsGroupIndex++) {
2727
2728 AIM_ALLOC(filename, strlen(projectName) +{ if (filename != ((void*)0)) { status = -4; aim_status(discr
->aInfo, status, "fun3dAIM.c", 2729, __func__, 1, "AIM_ALLOC: %s != NULL"
, "filename"); goto cleanup; } size_t memorysize = strlen(projectName
) + strlen("_ddfdrive_bndry.dat")+7; filename = (char *) EG_alloc
(memorysize*sizeof(char)); if (filename == ((void*)0)) { status
= -4; aim_status(discr->aInfo, status, "fun3dAIM.c", 2729
, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "filename", memorysize
, "char"); goto cleanup; } }
2729 strlen("_ddfdrive_bndry.dat")+7, char, discr->aInfo, status){ if (filename != ((void*)0)) { status = -4; aim_status(discr
->aInfo, status, "fun3dAIM.c", 2729, __func__, 1, "AIM_ALLOC: %s != NULL"
, "filename"); goto cleanup; } size_t memorysize = strlen(projectName
) + strlen("_ddfdrive_bndry.dat")+7; filename = (char *) EG_alloc
(memorysize*sizeof(char)); if (filename == ((void*)0)) { status
= -4; aim_status(discr->aInfo, status, "fun3dAIM.c", 2729
, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "filename", memorysize
, "char"); goto cleanup; } }
;
2730
2731 sprintf(filename,"%s%s%d%s",projectName,
2732 "_ddfdrive_bndry",
2733 capsGroupList[capsGroupIndex+1],
2734 ".dat");
2735
2736 status = fun3d_readAeroLoad(discr->aInfo, filename,
2737 &numVariable,
2738 &variableName,
2739 &numDataPoint,
2740 &dataMatrix);
2741 // Try body file
2742 if (status == CAPS_IOERR-332) {
2743
2744 AIM_REALL(filename, strlen(projectName) +{ size_t memorysize = strlen(projectName) + strlen("_ddfdrive_body1.dat"
)+7; filename = (char *) EG_reall(filename, memorysize*sizeof
(char)); if (filename == ((void*)0)) { status = -4; aim_status
(discr->aInfo, status, "fun3dAIM.c", 2745, __func__, 3, "AIM_REALL: %s size %zu type %s"
, "filename", memorysize, "char"); goto cleanup; } }
2745 strlen("_ddfdrive_body1.dat")+7, char, discr->aInfo, status){ size_t memorysize = strlen(projectName) + strlen("_ddfdrive_body1.dat"
)+7; filename = (char *) EG_reall(filename, memorysize*sizeof
(char)); if (filename == ((void*)0)) { status = -4; aim_status
(discr->aInfo, status, "fun3dAIM.c", 2745, __func__, 3, "AIM_REALL: %s size %zu type %s"
, "filename", memorysize, "char"); goto cleanup; } }
;
2746
2747 sprintf(filename,"%s%s%s",projectName,
2748 "_ddfdrive_body1",
2749 ".dat");
2750
2751 printf("Instead trying file : %s\n", filename);
2752
2753 status = fun3d_readAeroLoad(discr->aInfo, filename,
2754 &numVariable,
2755 &variableName,
2756 &numDataPoint,
2757 &dataMatrix);
2758 }
2759
2760 AIM_FREE(filename){ EG_free(filename); filename = ((void*)0); };
2761 AIM_STATUS(discr->aInfo, status)if (status != 0) { aim_status(discr->aInfo, status, "fun3dAIM.c"
, 2761, __func__, 0); goto cleanup; }
;
2762
2763 printf("Number of variables %d\n", numVariable);
2764 // Output some of the first row of the data
2765 //for (i = 0; i < numVariable; i++) printf("Variable %d - %.6f\n", i, dataMatrix[i][0]);
2766
2767 // Loop through the variable list to find which one is the global node ID variable
2768 for (i = 0; i < numVariable; i++) {
2769 AIM_NOTNULL(variableName, discr->aInfo, status){ if (variableName == ((void*)0)) { status = -307; aim_status
(discr->aInfo, status, "fun3dAIM.c", 2769, __func__, 1, "%s == NULL!"
, "variableName"); goto cleanup; } }
;
2770 if (strcasecmp("id", variableName[i]) == 0) {
2771 globalIDIndex = i;
2772 break;
2773 }
2774 }
2775
2776 if (globalIDIndex == -99) {
2777 AIM_ERROR(discr->aInfo, "Global node number variable not found in data file\n"){ aim_message(discr->aInfo, CERROR, 0 , "fun3dAIM.c", 2777
, __func__, "Global node number variable not found in data file\n"
); }
;
2778 status = CAPS_NOTFOUND-303;
2779 goto cleanup;
2780 }
2781
2782 // Loop through the variable list to see if we can find the transfer data name
2783 for (i = 0; i < numVariable; i++) {
2784 AIM_NOTNULL(variableName, discr->aInfo, status){ if (variableName == ((void*)0)) { status = -307; aim_status
(discr->aInfo, status, "fun3dAIM.c", 2784, __func__, 1, "%s == NULL!"
, "variableName"); goto cleanup; } }
;
2785
2786 if (strcasecmp(dataName, "Pressure") == 0 ||
2787 strcasecmp(dataName, "P") == 0 ||
2788 strcasecmp(dataName, "Cp") == 0 ||
2789 strcasecmp(dataName, "CoefficientOfPressure") == 0) {
2790
2791 if (dataRank != 1) {
2792 printf("Data transfer rank should be 1 not %d\n", dataRank);
2793 status = CAPS_BADRANK-301;
2794 goto cleanup;
2795 }
2796
2797 dataScaleFactor = fun3dInstance->pressureScaleFactor->vals.real;
2798 dataScaleOffset = fun3dInstance->pressureScaleOffset->vals.real;
2799
2800 //dataUnits = fun3dInstance->pressureScaleFactor->units;
2801 if (strcasecmp("cp", variableName[i]) == 0) {
2802 variableIndex = i;
2803 break;
2804 }
2805 }
2806 }
2807
2808 if (variableIndex == -99) {
2809 AIM_ERROR(discr->aInfo, "Variable %s not found in data file\n", dataName){ aim_message(discr->aInfo, CERROR, 0 , "fun3dAIM.c", 2809
, __func__, "Variable %s not found in data file\n", dataName)
; }
;
2810 status = CAPS_NOTFOUND-303;
2811 goto cleanup;
2812 }
2813 if (dataMatrix == NULL((void*)0)) {
2814 AIM_ERROR(discr->aInfo, "Variable %s daata mtrix is NULL!\n", dataName){ aim_message(discr->aInfo, CERROR, 0 , "fun3dAIM.c", 2814
, __func__, "Variable %s daata mtrix is NULL!\n", dataName); }
;
2815 status = CAPS_NULLVALUE-307;
2816 goto cleanup;
2817 }
2818
2819 for (i = 0; i < numPoint; i++) {
2820
2821 bIndex = discr->tessGlobal[2*i ];
2822 globalNodeID = discr->tessGlobal[2*i+1] +
2823 discr->bodys[bIndex-1].globalOffset;
2824
2825 found = (int) false0;
2826 for (dataPoint = 0; dataPoint < numDataPoint; dataPoint++) {
2827 if ((int) dataMatrix[globalIDIndex][dataPoint] == globalNodeID) {
2828 found = (int) true1;
2829 break;
2830 }
2831 }
2832
2833 if (found == (int) true1) {
2834 for (j = 0; j < dataRank; j++) {
2835
2836 // Add something for units - aim_covert()
2837
2838 dataVal[dataRank*i+j] = dataMatrix[variableIndex][dataPoint]*dataScaleFactor +
2839 dataScaleOffset;
2840 //printf("DataValue = %f\n",dataVal[dataRank*i+j]);
2841 //dataVal[dataRank*i+j] = 99;
2842
2843 }
2844 }
2845 }
2846
2847 // Free data matrix
2848 if (dataMatrix != NULL((void*)0)) {
2849 for (i = 0; i < numVariable; i++) {
2850 AIM_FREE(dataMatrix[i]){ EG_free(dataMatrix[i]); dataMatrix[i] = ((void*)0); };
2851 }
2852 AIM_FREE(dataMatrix){ EG_free(dataMatrix); dataMatrix = ((void*)0); };
2853 }
2854
2855 // Free variable list
2856 status = string_freeArray(numVariable, &variableName);
2857 AIM_STATUS(discr->aInfo, status)if (status != 0) { aim_status(discr->aInfo, status, "fun3dAIM.c"
, 2857, __func__, 0); goto cleanup; }
;
2858
2859 }
2860
2861 status = CAPS_SUCCESS0;
2862
2863cleanup:
2864 // Free data matrix
2865 if (dataMatrix
4.1
'dataMatrix' is equal to NULL
!= NULL((void*)0)) {
5
Taking false branch
2866 for (i = 0; i < numVariable; i++) {
2867 AIM_FREE(dataMatrix[i]){ EG_free(dataMatrix[i]); dataMatrix[i] = ((void*)0); };
2868 }
2869 AIM_FREE(dataMatrix){ EG_free(dataMatrix); dataMatrix = ((void*)0); };
2870 }
2871
2872 // Free variable list
2873 status2 = string_freeArray(numVariable, &variableName);
6
1st function call argument is an uninitialized value
2874 if (status2 != CAPS_SUCCESS0) return status2;
2875
2876 return status;
2877}
2878
2879
2880int
2881aimInterpolation(capsDiscr *discr, /*@unused@*/ const char *name, int bIndex,
2882 int eIndex, double *bary, int rank,
2883 double *data, double *result)
2884{
2885#ifdef DEBUG
2886 printf(" fun3dAIM/aimInterpolation %s!\n", name);
2887#endif
2888 return aim_interpolation(discr, name, bIndex, eIndex,
2889 bary, rank, data, result);
2890}
2891
2892
2893int
2894aimInterpolateBar(capsDiscr *discr, /*@unused@*/ const char *name, int bIndex,
2895 int eIndex, double *bary, int rank,
2896 double *r_bar, double *d_bar)
2897{
2898#ifdef DEBUG
2899 printf(" fun3dAIM/aimInterpolateBar %s!\n", name);
2900#endif
2901 return aim_interpolateBar(discr, name, bIndex, eIndex,
2902 bary, rank, r_bar, d_bar);
2903}
2904
2905
2906int
2907aimIntegration(capsDiscr *discr, /*@unused@*/ const char *name, int bIndex,
2908 int eIndex, int rank, double *data, double *result)
2909{
2910#ifdef DEBUG
2911 printf(" fun3dAIM/aimIntegration %s!\n", name);
2912#endif
2913 return aim_integration(discr, name, bIndex, eIndex, rank,
2914 data, result);
2915}
2916
2917
2918int
2919aimIntegrateBar(capsDiscr *discr, /*@unused@*/ const char *name, int bIndex,
2920 int eIndex, int rank, double *r_bar, double *d_bar)
2921{
2922#ifdef DEBUG
2923 printf(" fun3dAIM/aimIntegrateBar %s!\n", name);
2924#endif
2925 return aim_integrateBar(discr, name, bIndex, eIndex, rank,
2926 r_bar, d_bar);
2927}