File: | fun3dAIM.c |
Warning: | line 2878, column 15 1st function call argument is an uninitialized value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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) | |||
71 | static 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 | ||||
102 | enum 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 | ||||
139 | typedef 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 | ||||
161 | int 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 | ||||
294 | cleanup: | |||
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 | ||||
310 | int 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 | ||||
903 | cleanup: | |||
904 | if (status != CAPS_SUCCESS0) AIM_FREE(*ainame){ EG_free(*ainame); *ainame = ((void*)0); }; | |||
905 | return status; | |||
906 | } | |||
907 | ||||
908 | ||||
909 | int 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, ¤tIntent); | |||
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 | ||||
1544 | cleanup: | |||
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 */ | |||
1558 | int 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.numDesignFunctional == 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 | AIM_NOTNULL(bodies, aimInfo, status){ if (bodies == ((void*)0)) { status = -307; aim_status(aimInfo , status, "fun3dAIM.c", 1620, __func__, 1, "%s == NULL!", "bodies" ); goto cleanup; } }; | |||
1621 | ||||
1622 | // Get capsGroup name and index mapping to make sure all faces have a capsGroup value | |||
1623 | status = create_CAPSGroupAttrToIndexMap(numBody, | |||
1624 | bodies, | |||
1625 | 1, // Only search down to the face level of the EGADS body | |||
1626 | &fun3dInstance->groupMap); | |||
1627 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1627 , __func__, 0); goto cleanup; }; | |||
1628 | ||||
1629 | // Get boundary conditions | |||
1630 | status = cfd_getBoundaryCondition( aimInfo, | |||
1631 | aimInputs[Boundary_Condition-1].length, | |||
1632 | aimInputs[Boundary_Condition-1].vals.tuple, | |||
1633 | &fun3dInstance->groupMap, | |||
1634 | &bcProps); | |||
1635 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1635 , __func__, 0); goto cleanup; }; | |||
1636 | ||||
1637 | /*@-nullpass@*/ | |||
1638 | status = cfd_getDesignVariable(aimInfo, | |||
1639 | aimInputs[Design_Variable-1].length, | |||
1640 | aimInputs[Design_Variable-1].vals.tuple, | |||
1641 | &fun3dInstance->design.numDesignVariable, | |||
1642 | &fun3dInstance->design.designVariable); | |||
1643 | /*@+nullpass@*/ | |||
1644 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1644 , __func__, 0); goto cleanup; }; | |||
1645 | ||||
1646 | status = cfd_getDesignFunctional(aimInfo, | |||
1647 | aimInputs[Design_Functional-1].length, | |||
1648 | aimInputs[Design_Functional-1].vals.tuple, | |||
1649 | &bcProps, | |||
1650 | fun3dInstance->design.numDesignVariable, | |||
1651 | fun3dInstance->design.designVariable, | |||
1652 | &fun3dInstance->design.numDesignFunctional, | |||
1653 | &fun3dInstance->design.designFunctional); | |||
1654 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1654 , __func__, 0); goto cleanup; }; | |||
1655 | } | |||
1656 | ||||
1657 | for (i = 0; i < fun3dInstance->design.numDesignFunctional; i++) { | |||
1658 | ||||
1659 | /* allocate derivatives */ | |||
1660 | 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", 1660, __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", 1660, __func__, 3, "AIM_ALLOC: %s size %zu type %s" , "value.derivs", memorysize, "capsDeriv"); goto cleanup; } }; | |||
1661 | for (j = 0; j < fun3dInstance->design.designFunctional[i].numDesignVariable; j++) { | |||
1662 | value.derivs[j].name = NULL((void*)0); | |||
1663 | value.derivs[j].deriv = NULL((void*)0); | |||
1664 | value.derivs[j].len_wrt = 0; | |||
1665 | } | |||
1666 | value.nderiv = fun3dInstance->design.designFunctional[i].numDesignVariable; | |||
1667 | ||||
1668 | value.vals.real = fun3dInstance->design.designFunctional[i].value; | |||
1669 | value.type = DoubleDeriv; | |||
1670 | ||||
1671 | for (j = 0; j < fun3dInstance->design.designFunctional[i].numDesignVariable; j++) { | |||
1672 | ||||
1673 | dvar = &fun3dInstance->design.designFunctional[i].dvar[j]; | |||
1674 | ||||
1675 | 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", 1675, __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" , 1675, __func__, 2, "AIM_STRDUP: %s %s", "value.derivs[j].name" , dvar->name); goto cleanup; } }; | |||
1676 | 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", 1676, __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" , 1676, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "value.derivs[j].deriv" , memorysize, "double"); goto cleanup; } }; | |||
1677 | value.derivs[j].len_wrt = dvar->var->length; | |||
1678 | ||||
1679 | for (k = 0; k < dvar->var->length; k++) { | |||
1680 | value.derivs[j].deriv[k] = dvar->value[k]; | |||
1681 | } | |||
1682 | } | |||
1683 | ||||
1684 | /* create the dynamic output */ | |||
1685 | status = aim_makeDynamicOutput(aimInfo, fun3dInstance->design.designFunctional[i].name, &value); | |||
1686 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1686 , __func__, 0); goto cleanup; }; | |||
1687 | } | |||
1688 | } | |||
1689 | ||||
1690 | if (aimInputs[Design_SensFile-1].vals.integer == (int)true1) { | |||
1691 | ||||
1692 | if (fun3dInstance->design.numDesignVariable == 0) { | |||
1693 | // Get AIM bodies | |||
1694 | status = aim_getBodies(aimInfo, &intents, &numBody, &bodies); | |||
1695 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1695 , __func__, 0); goto cleanup; }; | |||
1696 | AIM_NOTNULL(bodies, aimInfo, status){ if (bodies == ((void*)0)) { status = -307; aim_status(aimInfo , status, "fun3dAIM.c", 1696, __func__, 1, "%s == NULL!", "bodies" ); goto cleanup; } }; | |||
1697 | ||||
1698 | // Get capsGroup name and index mapping to make sure all faces have a capsGroup value | |||
1699 | status = create_CAPSGroupAttrToIndexMap(numBody, | |||
1700 | bodies, | |||
1701 | 1, // Only search down to the face level of the EGADS body | |||
1702 | &fun3dInstance->groupMap); | |||
1703 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1703 , __func__, 0); goto cleanup; }; | |||
1704 | ||||
1705 | // Get boundary conditions | |||
1706 | status = cfd_getBoundaryCondition( aimInfo, | |||
1707 | aimInputs[Boundary_Condition-1].length, | |||
1708 | aimInputs[Boundary_Condition-1].vals.tuple, | |||
1709 | &fun3dInstance->groupMap, | |||
1710 | &bcProps); | |||
1711 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1711 , __func__, 0); goto cleanup; }; | |||
1712 | ||||
1713 | /*@-nullpass@*/ | |||
1714 | status = cfd_getDesignVariable(aimInfo, | |||
1715 | aimInputs[Design_Variable-1].length, | |||
1716 | aimInputs[Design_Variable-1].vals.tuple, | |||
1717 | &fun3dInstance->design.numDesignVariable, | |||
1718 | &fun3dInstance->design.designVariable); | |||
1719 | /*@+nullpass@*/ | |||
1720 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1720 , __func__, 0); goto cleanup; }; | |||
1721 | } | |||
1722 | ||||
1723 | status = aim_getValue(aimInfo, Proj_Name, ANALYSISIN, &ProjName); | |||
1724 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1724 , __func__, 0); goto cleanup; }; | |||
1725 | AIM_NOTNULL(ProjName, aimInfo, status){ if (ProjName == ((void*)0)) { status = -307; aim_status(aimInfo , status, "fun3dAIM.c", 1725, __func__, 1, "%s == NULL!", "ProjName" ); goto cleanup; } }; | |||
1726 | projectName = ProjName->vals.string; | |||
1727 | ||||
1728 | // Get mesh | |||
1729 | meshRef = (aimMeshRef *)aimInputs[Mesh-1].vals.AIMptr; | |||
1730 | AIM_NOTNULL(meshRef, aimInfo, status){ if (meshRef == ((void*)0)) { status = -307; aim_status(aimInfo , status, "fun3dAIM.c", 1730, __func__, 1, "%s == NULL!", "meshRef" ); goto cleanup; } }; | |||
1731 | ||||
1732 | // Read the number of volume nodes from the mesh | |||
1733 | #ifdef WIN32 | |||
1734 | snprintf(filename, PATH_MAX4096, "Flow\\%s%s", projectName, MESHEXTENSION".lb8.ugrid"); | |||
1735 | #else | |||
1736 | snprintf(filename, PATH_MAX4096, "Flow/%s%s", projectName, MESHEXTENSION".lb8.ugrid"); | |||
1737 | #endif | |||
1738 | fp = aim_fopen(aimInfo, filename, "rb"); | |||
1739 | if (fp == NULL((void*)0)) { | |||
1740 | AIM_ERROR(aimInfo, "Unable to open: %s", filename){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 1740, __func__ , "Unable to open: %s", filename); }; | |||
1741 | status = CAPS_IOERR-332; | |||
1742 | goto cleanup; | |||
1743 | } | |||
1744 | status = fread(&numVolNode, sizeof(int), 1, fp); | |||
1745 | if (status != 1) status = CAPS_IOERR-332; else status = CAPS_SUCCESS0; | |||
1746 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1746 , __func__, 0); goto cleanup; }; | |||
1747 | fclose(fp); fp = NULL((void*)0); | |||
1748 | ||||
1749 | AIM_ALLOC(vol2tess, 2*numVolNode, int, aimInfo, status){ if (vol2tess != ((void*)0)) { status = -4; aim_status(aimInfo , status, "fun3dAIM.c", 1749, __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" , 1749, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "vol2tess" , memorysize, "int"); goto cleanup; } }; | |||
1750 | for (i = 0; i < 2*numVolNode; i++) vol2tess[i] = 0; | |||
1751 | ||||
1752 | numNode = 0; | |||
1753 | for (ibody = 0; ibody < meshRef->nmap; ibody++) { | |||
1754 | EG_statusTessBody(meshRef->maps[ibody].tess, &body, &state, &offset); | |||
1755 | numNode += offset; | |||
1756 | ||||
1757 | for (i = 0; i < offset; i++) { | |||
1758 | j = meshRef->maps[ibody].map[i]; | |||
1759 | vol2tess[2*(j-1)+0] = ibody; | |||
1760 | vol2tess[2*(j-1)+1] = i; | |||
1761 | } | |||
1762 | } | |||
1763 | ||||
1764 | // Read <Proj_Name>.sens | |||
1765 | snprintf(tmp, 128, "%s%s", projectName, ".sens"); | |||
1766 | fp = aim_fopen(aimInfo, tmp, "r"); | |||
1767 | if (fp == NULL((void*)0)) { | |||
1768 | AIM_ERROR(aimInfo, "Unable to open: %s", tmp){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 1768, __func__ , "Unable to open: %s", tmp); }; | |||
1769 | status = CAPS_IOERR-332; | |||
1770 | goto cleanup; | |||
1771 | } | |||
1772 | ||||
1773 | // Number of nodes and functinoals in the file | |||
1774 | status = fscanf(fp, "%d", &numFunctional); | |||
1775 | if (status != 1) status = CAPS_IOERR-332; else status = CAPS_SUCCESS0; | |||
1776 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1776 , __func__, 0); goto cleanup; }; | |||
1777 | ||||
1778 | AIM_ALLOC(numPoint, numFunctional, int, aimInfo, status){ if (numPoint != ((void*)0)) { status = -4; aim_status(aimInfo , status, "fun3dAIM.c", 1778, __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" , 1778, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "numPoint" , memorysize, "int"); goto cleanup; } }; | |||
1779 | for (i = 0; i < numFunctional; i++) numPoint[i] = 0; | |||
1780 | ||||
1781 | AIM_ALLOC(functional_map, numFunctional, int*, aimInfo, status){ if (functional_map != ((void*)0)) { status = -4; aim_status (aimInfo, status, "fun3dAIM.c", 1781, __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", 1781, __func__, 3, "AIM_ALLOC: %s size %zu type %s" , "functional_map", memorysize, "int*"); goto cleanup; } }; | |||
1782 | for (i = 0; i < numFunctional; i++) functional_map[i] = NULL((void*)0); | |||
1783 | ||||
1784 | AIM_ALLOC(functional_xyz, numFunctional, double*, aimInfo, status){ if (functional_xyz != ((void*)0)) { status = -4; aim_status (aimInfo, status, "fun3dAIM.c", 1784, __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", 1784, __func__, 3, "AIM_ALLOC: %s size %zu type %s" , "functional_xyz", memorysize, "double*"); goto cleanup; } }; | |||
1785 | for (i = 0; i < numFunctional; i++) functional_xyz[i] = NULL((void*)0); | |||
1786 | ||||
1787 | AIM_ALLOC(names, numFunctional, char*, aimInfo, status){ if (names != ((void*)0)) { status = -4; aim_status(aimInfo, status, "fun3dAIM.c", 1787, __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" , 1787, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "names" , memorysize, "char*"); goto cleanup; } }; | |||
1788 | for (i = 0; i < numFunctional; i++) names[i] = NULL((void*)0); | |||
1789 | ||||
1790 | AIM_ALLOC(values, numFunctional, capsValue, aimInfo, status){ if (values != ((void*)0)) { status = -4; aim_status(aimInfo , status, "fun3dAIM.c", 1790, __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", 1790, __func__, 3, "AIM_ALLOC: %s size %zu type %s" , "values", memorysize, "capsValue"); goto cleanup; } }; | |||
1791 | for (i = 0; i < numFunctional; i++) aim_initValue(&values[i]); | |||
1792 | ||||
1793 | for (i = 0; i < numFunctional; i++) { | |||
1794 | values[i].type = DoubleDeriv; | |||
1795 | ||||
1796 | /* allocate derivatives */ | |||
1797 | 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", 1797, __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" , 1797, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "values[i].derivs" , memorysize, "capsDeriv"); goto cleanup; } }; | |||
1798 | for (idv = 0; idv < fun3dInstance->design.numDesignVariable; idv++) { | |||
1799 | values[i].derivs[idv].name = NULL((void*)0); | |||
1800 | values[i].derivs[idv].deriv = NULL((void*)0); | |||
1801 | values[i].derivs[idv].len_wrt = 0; | |||
1802 | } | |||
1803 | values[i].nderiv = fun3dInstance->design.numDesignVariable; | |||
1804 | } | |||
1805 | ||||
1806 | // Read in Functional name, value and dFunctinoal/dxyz | |||
1807 | for (i = 0; i < numFunctional; i++) { | |||
1808 | ||||
1809 | status = fscanf(fp, "%s", tmp); | |||
1810 | if (status == EOF(-1)) { | |||
1811 | AIM_ERROR(aimInfo, "Failed to read sens file functional name"){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 1811, __func__ , "Failed to read sens file functional name"); }; | |||
1812 | status = CAPS_IOERR-332; goto cleanup; | |||
1813 | } | |||
1814 | ||||
1815 | AIM_STRDUP(names[i], tmp, aimInfo, status){ if (names[i] != ((void*)0)) { status = -4; aim_status(aimInfo , status, "fun3dAIM.c", 1815, __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", 1815, __func__, 2, "AIM_STRDUP: %s %s", "names[i]" , tmp); goto cleanup; } }; | |||
1816 | ||||
1817 | status = fscanf(fp, "%lf", &values[i].vals.real); | |||
1818 | if (status == EOF(-1) || status != 1) { | |||
1819 | AIM_ERROR(aimInfo, "Failed to read sens file functional value"){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 1819, __func__ , "Failed to read sens file functional value"); }; | |||
1820 | status = CAPS_IOERR-332; goto cleanup; | |||
1821 | } | |||
1822 | ||||
1823 | status = fscanf(fp, "%d", &numPoint[i]); | |||
1824 | if (status == EOF(-1) || status != 1) { | |||
1825 | AIM_ERROR(aimInfo, "Failed to read sens file number of points"){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 1825, __func__ , "Failed to read sens file number of points"); }; | |||
1826 | status = CAPS_IOERR-332; goto cleanup; | |||
1827 | } | |||
1828 | ||||
1829 | AIM_ALLOC(functional_map[i], numPoint[i], int , aimInfo, status){ if (functional_map[i] != ((void*)0)) { status = -4; aim_status (aimInfo, status, "fun3dAIM.c", 1829, __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", 1829, __func__, 3, "AIM_ALLOC: %s size %zu type %s" , "functional_map[i]", memorysize, "int"); goto cleanup; } }; | |||
1830 | 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", 1830, __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", 1830, __func__ , 3, "AIM_ALLOC: %s size %zu type %s", "functional_xyz[i]", memorysize , "double"); goto cleanup; } }; | |||
1831 | ||||
1832 | for (j = 0; j < numPoint[i]; j++) { | |||
1833 | status = fscanf(fp, "%d %lf %lf %lf", &functional_map[i][j], | |||
1834 | &functional_xyz[i][3*j+0], | |||
1835 | &functional_xyz[i][3*j+1], | |||
1836 | &functional_xyz[i][3*j+2]); | |||
1837 | if (status == EOF(-1) || status != 4) { | |||
1838 | AIM_ERROR(aimInfo, "Failed to read sens file data"){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 1838, __func__ , "Failed to read sens file data"); }; | |||
1839 | status = CAPS_IOERR-332; goto cleanup; | |||
1840 | } | |||
1841 | ||||
1842 | if (functional_map[i][j] < 1 || functional_map[i][j] > numVolNode) { | |||
1843 | 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", 1843, __func__ , "sens file volume mesh vertex index: %d out-of-range [1-%d]" , functional_map[i][j], numVolNode); }; | |||
1844 | status = CAPS_IOERR-332; goto cleanup; | |||
1845 | } | |||
1846 | } | |||
1847 | } | |||
1848 | ||||
1849 | AIM_ALLOC(dxyz, meshRef->nmap, double*, aimInfo, status){ if (dxyz != ((void*)0)) { status = -4; aim_status(aimInfo, status , "fun3dAIM.c", 1849, __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" , 1849, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "dxyz" , memorysize, "double*"); goto cleanup; } }; | |||
1850 | for (ibody = 0; ibody < meshRef->nmap; ibody++) dxyz[ibody] = NULL((void*)0); | |||
1851 | ||||
1852 | /* set derivatives */ | |||
1853 | for (idv = 0; idv < fun3dInstance->design.numDesignVariable; idv++) { | |||
1854 | ||||
1855 | name = fun3dInstance->design.designVariable[idv].name; | |||
1856 | ||||
1857 | // Loop over the geometry in values and compute sensitivities for all bodies | |||
1858 | index = aim_getIndex(aimInfo, name, GEOMETRYIN); | |||
1859 | status = aim_getValue(aimInfo, index, GEOMETRYIN, &geomInVal); | |||
1860 | AIM_STATUS(aimInfo, status, "Design_SensFile only supports geometric sensitivities!")if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1860 , __func__, 1, "Design_SensFile only supports geometric sensitivities!" ); goto cleanup; }; | |||
1861 | ||||
1862 | for (i = 0; i < numFunctional; i++) { | |||
1863 | 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", 1863, __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", 1863, __func__, 2, "AIM_STRDUP: %s %s" , "values[i].derivs[idv].name", name); goto cleanup; } }; | |||
1864 | ||||
1865 | 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", 1865, __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", 1865, __func__ , 3, "AIM_ALLOC: %s size %zu type %s", "values[i].derivs[idv].deriv" , memorysize, "double"); goto cleanup; } }; | |||
1866 | values[i].derivs[idv].len_wrt = geomInVal->length; | |||
1867 | for (j = 0; j < geomInVal->length; j++) | |||
1868 | values[i].derivs[idv].deriv[j] = 0; | |||
1869 | } | |||
1870 | ||||
1871 | for (irow = 0; irow < geomInVal->nrow; irow++) { | |||
1872 | for (icol = 0; icol < geomInVal->ncol; icol++) { | |||
1873 | ||||
1874 | // get the sensitvity for each body | |||
1875 | for (ibody = 0; ibody < meshRef->nmap; ibody++) { | |||
1876 | status = aim_tessSensitivity(aimInfo, | |||
1877 | name, | |||
1878 | irow+1, icol+1, // row, col | |||
1879 | meshRef->maps[ibody].tess, | |||
1880 | &numNode, &dxyz[ibody]); | |||
1881 | AIM_STATUS(aimInfo, status, "Sensitivity for: %s\n", name)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1881 , __func__, 2, "Sensitivity for: %s\n", name); goto cleanup; }; | |||
1882 | AIM_NOTNULL(dxyz[ibody], aimInfo, status){ if (dxyz[ibody] == ((void*)0)) { status = -307; aim_status( aimInfo, status, "fun3dAIM.c", 1882, __func__, 1, "%s == NULL!" , "dxyz[ibody]"); goto cleanup; } }; | |||
1883 | } | |||
1884 | ||||
1885 | for (i = 0; i < numFunctional; i++) { | |||
1886 | functional_dvar = values[i].derivs[idv].deriv[geomInVal->ncol*irow + icol]; | |||
1887 | ||||
1888 | for (j = 0; j < numPoint[i]; j++) { | |||
1889 | k = functional_map[i][j]-1; // 1-based indexing into volume | |||
1890 | ||||
1891 | ibody = vol2tess[2*k]; // body index | |||
1892 | k = vol2tess[2*k+1]; // 0-based surface index | |||
1893 | if (k == -1) { | |||
1894 | AIM_ERROR(aimInfo, "Volume mesh vertex %d is not on a surface!", functional_map[i][j]){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 1894, __func__ , "Volume mesh vertex %d is not on a surface!", functional_map [i][j]); }; | |||
1895 | status = CAPS_IOERR-332; | |||
1896 | goto cleanup; | |||
1897 | } | |||
1898 | if ( ibody < 0 || ibody >= meshRef->nmap ) { | |||
1899 | 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", 1899, __func__ , "Inconsistent surface node body index: %d should be in [0-%d]" , vol2tess[2*k], meshRef->nmap-1); }; | |||
1900 | status = CAPS_IOERR-332; | |||
1901 | goto cleanup; | |||
1902 | } | |||
1903 | ||||
1904 | functional_dvar += functional_xyz[i][3*j+0]*dxyz[ibody][3*k + 0] // dx/dGeomIn | |||
1905 | + functional_xyz[i][3*j+1]*dxyz[ibody][3*k + 1] // dy/dGeomIn | |||
1906 | + functional_xyz[i][3*j+2]*dxyz[ibody][3*k + 2]; // dz/dGeomIn | |||
1907 | } | |||
1908 | values[i].derivs[idv].deriv[geomInVal->ncol*irow + icol] = functional_dvar; | |||
1909 | } | |||
1910 | ||||
1911 | for (ibody = 0; ibody < meshRef->nmap; ibody++) | |||
1912 | AIM_FREE(dxyz[ibody]){ EG_free(dxyz[ibody]); dxyz[ibody] = ((void*)0); }; | |||
1913 | } | |||
1914 | } | |||
1915 | } | |||
1916 | ||||
1917 | /* create the dynamic output */ | |||
1918 | for (i = 0; i < numFunctional; i++) { | |||
1919 | status = aim_makeDynamicOutput(aimInfo, names[i], &values[i]); | |||
1920 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 1920 , __func__, 0); goto cleanup; }; | |||
1921 | } | |||
1922 | } | |||
1923 | ||||
1924 | cleanup: | |||
1925 | if (fp != NULL((void*)0)) fclose(fp); | |||
1926 | ||||
1927 | if (functional_xyz != NULL((void*)0)) | |||
1928 | for (i = 0; i < numFunctional; i++) | |||
1929 | AIM_FREE(functional_xyz[i]){ EG_free(functional_xyz[i]); functional_xyz[i] = ((void*)0); }; | |||
1930 | ||||
1931 | if (functional_map != NULL((void*)0)) | |||
1932 | for (i = 0; i < numFunctional; i++) | |||
1933 | AIM_FREE(functional_map[i]){ EG_free(functional_map[i]); functional_map[i] = ((void*)0); }; | |||
1934 | ||||
1935 | if (names != NULL((void*)0)) | |||
1936 | for (i = 0; i < numFunctional; i++) | |||
1937 | AIM_FREE(names[i]){ EG_free(names[i]); names[i] = ((void*)0); }; | |||
1938 | ||||
1939 | if (dxyz != NULL((void*)0) && meshRef != NULL((void*)0)) | |||
1940 | for (ibody = 0; ibody < meshRef->nmap; ibody++) | |||
1941 | AIM_FREE(dxyz[ibody]){ EG_free(dxyz[ibody]); dxyz[ibody] = ((void*)0); }; | |||
1942 | ||||
1943 | AIM_FREE(functional_xyz){ EG_free(functional_xyz); functional_xyz = ((void*)0); }; | |||
1944 | AIM_FREE(functional_map){ EG_free(functional_map); functional_map = ((void*)0); }; | |||
1945 | AIM_FREE(vol2tess){ EG_free(vol2tess); vol2tess = ((void*)0); }; | |||
1946 | AIM_FREE(names){ EG_free(names); names = ((void*)0); }; | |||
1947 | AIM_FREE(values){ EG_free(values); values = ((void*)0); }; | |||
1948 | AIM_FREE(dxyz){ EG_free(dxyz); dxyz = ((void*)0); }; | |||
1949 | AIM_FREE(numPoint){ EG_free(numPoint); numPoint = ((void*)0); }; | |||
1950 | ||||
1951 | (void) destroy_cfdBoundaryConditionStruct(&bcProps); | |||
1952 | ||||
1953 | return status; | |||
1954 | } | |||
1955 | ||||
1956 | ||||
1957 | int aimOutputs(/*@unused@*/ void *instStore, /*@unused@*/ void *aimStruc, | |||
1958 | int index, char **aoname, capsValue *form) | |||
1959 | { | |||
1960 | ||||
1961 | /*! \page aimOutputsFUN3D AIM Outputs | |||
1962 | * The following list outlines the FUN3D outputs available through the AIM interface. All variables currently | |||
1963 | * correspond to values for all boundaries (total) found in the *.forces file | |||
1964 | */ | |||
1965 | ||||
1966 | #ifdef DEBUG | |||
1967 | printf(" fun3dAIM/aimOutputs index = %d!\n", index); | |||
1968 | #endif | |||
1969 | ||||
1970 | // Total Forces - Pressure + Viscous | |||
1971 | if (index == CLtot ) *aoname = EG_strdup("CLtot"); | |||
1972 | else if (index == CDtot ) *aoname = EG_strdup("CDtot"); | |||
1973 | else if (index == CMXtot) *aoname = EG_strdup("CMXtot"); | |||
1974 | else if (index == CMYtot) *aoname = EG_strdup("CMYtot"); | |||
1975 | else if (index == CMZtot) *aoname = EG_strdup("CMZtot"); | |||
1976 | else if (index == CXtot ) *aoname = EG_strdup("CXtot"); | |||
1977 | else if (index == CYtot ) *aoname = EG_strdup("CYtot"); | |||
1978 | else if (index == CZtot ) *aoname = EG_strdup("CZtot"); | |||
1979 | ||||
1980 | /*! \page aimOutputsFUN3D | |||
1981 | * Net Forces - Pressure + Viscous: | |||
1982 | * - <B>CLtot</B> = The lift coefficient. | |||
1983 | * - <B>CDtot</B> = The drag coefficient. | |||
1984 | * - <B>CMXtot</B> = The moment coefficient about the x-axis. | |||
1985 | * - <B>CMYtot</B> = The moment coefficient about the y-axis. | |||
1986 | * - <B>CMZtot</B> = The moment coefficient about the z-axis. | |||
1987 | * - <B>CXtot</B> = The force coefficient about the x-axis. | |||
1988 | * - <B>CYtot</B> = The force coefficient about the y-axis. | |||
1989 | * - <B>CZtot</B> = The force coefficient about the z-axis. | |||
1990 | * . | |||
1991 | * | |||
1992 | */ | |||
1993 | ||||
1994 | // Pressure Forces | |||
1995 | else if (index == CLtot_p ) *aoname = EG_strdup("CLtot_p"); | |||
1996 | else if (index == CDtot_p ) *aoname = EG_strdup("CDtot_p"); | |||
1997 | else if (index == CMXtot_p) *aoname = EG_strdup("CMXtot_p"); | |||
1998 | else if (index == CMYtot_p) *aoname = EG_strdup("CMYtot_p"); | |||
1999 | else if (index == CMZtot_p) *aoname = EG_strdup("CMZtot_p"); | |||
2000 | else if (index == CXtot_p ) *aoname = EG_strdup("CXtot_p"); | |||
2001 | else if (index == CYtot_p ) *aoname = EG_strdup("CYtot_p"); | |||
2002 | else if (index == CZtot_p ) *aoname = EG_strdup("CZtot_p"); | |||
2003 | ||||
2004 | /*! \page aimOutputsFUN3D | |||
2005 | * Pressure Forces: | |||
2006 | * - <B>CLtot_p</B> = The lift coefficient - pressure contribution only. | |||
2007 | * - <B>CDtot_p</B> = The drag coefficient - pressure contribution only. | |||
2008 | * - <B>CMXtot_p</B> = The moment coefficient about the x-axis - pressure contribution only. | |||
2009 | * - <B>CMYtot_p</B> = The moment coefficient about the y-axis - pressure contribution only. | |||
2010 | * - <B>CMZtot_p</B> = The moment coefficient about the z-axis - pressure contribution only. | |||
2011 | * - <B>CXtot_p</B> = The force coefficient about the x-axis - pressure contribution only. | |||
2012 | * - <B>CYtot_p</B> = The force coefficient about the y-axis - pressure contribution only. | |||
2013 | * - <B>CZtot_p</B> = The force coefficient about the z-axis - pressure contribution only. | |||
2014 | * . | |||
2015 | * | |||
2016 | */ | |||
2017 | ||||
2018 | // Viscous Forces | |||
2019 | else if (index == CLtot_v ) *aoname = EG_strdup("CLtot_v"); | |||
2020 | else if (index == CDtot_v ) *aoname = EG_strdup("CDtot_v"); | |||
2021 | else if (index == CMXtot_v) *aoname = EG_strdup("CMXtot_v"); | |||
2022 | else if (index == CMYtot_v) *aoname = EG_strdup("CMYtot_v"); | |||
2023 | else if (index == CMZtot_v) *aoname = EG_strdup("CMZtot_v"); | |||
2024 | else if (index == CXtot_v ) *aoname = EG_strdup("CXtot_v"); | |||
2025 | else if (index == CYtot_v ) *aoname = EG_strdup("CYtot_v"); | |||
2026 | else if (index == CZtot_v ) *aoname = EG_strdup("CZtot_v"); | |||
2027 | ||||
2028 | /*! \page aimOutputsFUN3D | |||
2029 | * Viscous Forces: | |||
2030 | * - <B>CLtot_v</B> = The lift coefficient - viscous contribution only. | |||
2031 | * - <B>CDtot_v</B> = The drag coefficient - viscous contribution only. | |||
2032 | * - <B>CMXtot_v</B> = The moment coefficient about the x-axis - viscous contribution only. | |||
2033 | * - <B>CMYtot_v</B> = The moment coefficient about the y-axis - viscous contribution only. | |||
2034 | * - <B>CMZtot_v</B> = The moment coefficient about the z-axis - viscous contribution only. | |||
2035 | * - <B>CXtot_v</B> = The force coefficient about the x-axis - viscous contribution only. | |||
2036 | * - <B>CYtot_v</B> = The force coefficient about the y-axis - viscous contribution only. | |||
2037 | * - <B>CZtot_v</B> = The force coefficient about the z-axis - viscous contribution only. | |||
2038 | */ | |||
2039 | else if (index == Forces) { | |||
2040 | *aoname = EG_strdup("Forces"); | |||
2041 | form->type = Tuple; | |||
2042 | form->nullVal = IsNull; | |||
2043 | //defval->units = NULL; | |||
2044 | form->dim = Vector; | |||
2045 | form->lfixed = Change; | |||
2046 | form->vals.tuple = NULL((void*)0); | |||
2047 | ||||
2048 | /*! \page aimOutputsFUN3D | |||
2049 | * Force components: | |||
2050 | * - <B>Forces</B> = Returns a tuple array of JSON string dictionaries of forces and moments for each boundary (combined | |||
2051 | * forces also included). The structure for the Forces tuple = ("Boundary Name", "Value"). | |||
2052 | * "Boundary Name" defines the boundary/component name (or "Total") and the "Value" is a JSON string dictionary. Entries | |||
2053 | * in the dictionary are the same as the other output variables without "tot" in the | |||
2054 | * name (e.g. CL, CD, CMX, CL_p, CMX_v, etc.). | |||
2055 | */ | |||
2056 | ||||
2057 | } else { | |||
2058 | printf(" fun3dAIM/aimOutputs index = %d NOT Found!\n", index); | |||
2059 | return CAPS_NOTFOUND-303; | |||
2060 | } | |||
2061 | ||||
2062 | if (index < Forces) { | |||
2063 | form->type = Double; | |||
2064 | form->dim = Vector; | |||
2065 | form->nrow = 1; | |||
2066 | form->ncol = 1; | |||
2067 | form->units = NULL((void*)0); | |||
2068 | form->nullVal = IsNull; | |||
2069 | ||||
2070 | form->vals.reals = NULL((void*)0); | |||
2071 | form->vals.real = 0; | |||
2072 | } | |||
2073 | ||||
2074 | return CAPS_SUCCESS0; | |||
2075 | } | |||
2076 | ||||
2077 | ||||
2078 | static int fun3d_readForcesJSON(void *aimInfo, | |||
2079 | FILE *fp, mapAttrToIndexStruct *attrMap, | |||
2080 | capsValue *val) | |||
2081 | { | |||
2082 | int status = CAPS_SUCCESS0; // Function return status | |||
2083 | ||||
2084 | size_t linecap = 0; | |||
2085 | ||||
2086 | char *line = NULL((void*)0); // Temporary line holder | |||
2087 | char *strValue; | |||
2088 | char *newLine; | |||
2089 | const char *keyWord = NULL((void*)0); | |||
2090 | ||||
2091 | char lineVal[80]; | |||
2092 | char json[9*80 + 5]; | |||
2093 | char num1[15], num2[15], num3[15]; | |||
2094 | ||||
2095 | char *title = "FORCE SUMMARY FOR BOUNDARY"; | |||
2096 | char *titleTot = "FORCE TOTALS FOR ALL BOUNDARIES"; | |||
2097 | char name[80]; | |||
2098 | int nameIndex; | |||
2099 | ||||
2100 | int i = 7, j = 30, k = 53; | |||
2101 | ||||
2102 | if (fp == NULL((void*)0)) { | |||
2103 | status = CAPS_NULLVALUE-307; | |||
2104 | goto cleanup; | |||
2105 | } | |||
2106 | ||||
2107 | if (attrMap == NULL((void*)0)) { | |||
2108 | status = CAPS_NULLVALUE-307; | |||
2109 | goto cleanup; | |||
2110 | } | |||
2111 | ||||
2112 | if (val == NULL((void*)0)) { | |||
2113 | status = CAPS_NULLVALUE-307; | |||
2114 | goto cleanup; | |||
2115 | } | |||
2116 | ||||
2117 | val->nrow = 0; | |||
2118 | val->vals.tuple = NULL((void*)0); | |||
2119 | ||||
2120 | while (getline(&line, &linecap, fp) >= 0) { | |||
2121 | ||||
2122 | if (line == NULL((void*)0)) continue; | |||
2123 | ||||
2124 | strValue = strstr(line, title); | |||
2125 | ||||
2126 | if ( (strValue != NULL((void*)0)) || (strstr(line, titleTot) != NULL((void*)0)) ){ | |||
2127 | ||||
2128 | if (strValue != NULL((void*)0)) { | |||
2129 | ||||
2130 | sprintf(name, "%s", &strValue[strlen(title)+1]); | |||
2131 | if ( (newLine = strchr(name, '\n')) != NULL((void*)0)) *newLine = '\0'; | |||
2132 | ||||
2133 | } else { | |||
2134 | ||||
2135 | sprintf(name, "%s", "Total"); | |||
2136 | } | |||
2137 | ||||
2138 | 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", 2138, __func__, 3, "AIM_REALL: %s size %zu type %s" , "val->vals.tuple", memorysize, "capsTuple"); goto cleanup ; } }; | |||
2139 | val->nrow += 1; | |||
2140 | ||||
2141 | val->nullVal = NotNull; | |||
2142 | val->vals.tuple[val->nrow -1 ].name = NULL((void*)0); | |||
2143 | val->vals.tuple[val->nrow -1 ].value = NULL((void*)0); | |||
2144 | ||||
2145 | // Initiate JSON string | |||
2146 | sprintf(json, "{"); | |||
2147 | ||||
2148 | if (strValue != NULL((void*)0)) { | |||
2149 | status = getline(&line, &linecap, fp); //Skip line - "Boundary type" | |||
2150 | if (status <=0) goto cleanup; | |||
2151 | } | |||
2152 | ||||
2153 | status = getline(&line, &linecap, fp); //Skip line - "----" | |||
2154 | if (status <=0) goto cleanup; | |||
2155 | ||||
2156 | status = getline(&line, &linecap, fp); //Skip line - "Pressure forces" | |||
2157 | if (status <=0) goto cleanup; | |||
2158 | ||||
2159 | status = getline(&line, &linecap, fp); | |||
2160 | if (status <=0) goto cleanup; | |||
2161 | ||||
2162 | strncpy(num1, &line[i], 14); num1[14] = '\0'; | |||
2163 | strncpy(num2, &line[j], 14); num2[14] = '\0'; | |||
2164 | ||||
2165 | sprintf(lineVal, "\"%s\":%s,\"%s\":%s,","CL_p", num1, "CD_p", num2); | |||
2166 | strcat(json, lineVal); // Add to JSON string | |||
2167 | ||||
2168 | status = getline(&line, &linecap, fp); | |||
2169 | if (status <=0) goto cleanup; | |||
2170 | ||||
2171 | strncpy(num1, &line[i], 14); num1[14] = '\0'; | |||
2172 | strncpy(num2, &line[j], 14); num2[14] = '\0'; | |||
2173 | strncpy(num3, &line[k], 14); num3[14] = '\0'; | |||
2174 | ||||
2175 | sprintf(lineVal, "\"%s\":%s,\"%s\":%s,\"%s\":%s,", | |||
2176 | "CMX_p", num1, "CMY_p", num2, "CMZ_p", num3); | |||
2177 | strcat(json, lineVal); // Add to JSON string | |||
2178 | ||||
2179 | status = getline(&line, &linecap, fp); | |||
2180 | if (status <=0) goto cleanup; | |||
2181 | ||||
2182 | strncpy(num1, &line[i], 14); num1[14] = '\0'; | |||
2183 | strncpy(num2, &line[j], 14); num2[14] = '\0'; | |||
2184 | strncpy(num3, &line[k], 14); num3[14] = '\0'; | |||
2185 | ||||
2186 | sprintf(lineVal, "\"%s\":%s,\"%s\":%s,\"%s\":%s,", | |||
2187 | "CX_p", num1, "CY_p", num2, "CZ_p", num3); | |||
2188 | strcat(json, lineVal); // Add to JSON string | |||
2189 | ||||
2190 | status = getline(&line, &linecap, fp); //Skip line - "Viscous forces" | |||
2191 | if (status <=0) goto cleanup; | |||
2192 | ||||
2193 | status = getline(&line, &linecap, fp); | |||
2194 | if (status <=0) goto cleanup; | |||
2195 | ||||
2196 | strncpy(num1, &line[i], 14); num1[14] = '\0'; | |||
2197 | strncpy(num2, &line[j], 14); num2[14] = '\0'; | |||
2198 | ||||
2199 | sprintf(lineVal, "\"%s\":%s,\"%s\":%s,","CL_v", num1, "CD_v", num2); | |||
2200 | strcat(json,lineVal); // Add to JSON string | |||
2201 | ||||
2202 | status = getline(&line, &linecap, fp); | |||
2203 | if (status <=0) goto cleanup; | |||
2204 | ||||
2205 | strncpy(num1, &line[i], 14); num1[14] = '\0'; | |||
2206 | strncpy(num2, &line[j], 14); num2[14] = '\0'; | |||
2207 | strncpy(num3, &line[k], 14); num3[14] = '\0'; | |||
2208 | ||||
2209 | sprintf(lineVal, "\"%s\":%s,\"%s\":%s,\"%s\":%s,", | |||
2210 | "CMX_v", num1, "CMY_v", num2, "CMZ_v", num3); | |||
2211 | strcat(json,lineVal); // Add to JSON string | |||
2212 | ||||
2213 | status = getline(&line, &linecap, fp); | |||
2214 | if (status <=0) goto cleanup; | |||
2215 | ||||
2216 | strncpy(num1, &line[i], 14); num1[14] = '\0'; | |||
2217 | strncpy(num2, &line[j], 14); num2[14] = '\0'; | |||
2218 | strncpy(num3, &line[k], 14); num3[14] = '\0'; | |||
2219 | ||||
2220 | sprintf(lineVal, "\"%s\":%s,\"%s\":%s,\"%s\":%s,", | |||
2221 | "CX_v", num1, "CY_v", num2, "CZ_v", num3); | |||
2222 | strcat(json,lineVal); // Add to JSON string | |||
2223 | ||||
2224 | status = getline(&line, &linecap, fp); //Skip line - "Total forces" | |||
2225 | if (status <=0) goto cleanup; | |||
2226 | ||||
2227 | status = getline(&line, &linecap, fp); | |||
2228 | if (status <=0) goto cleanup; | |||
2229 | ||||
2230 | strncpy(num1, &line[i], 14); num1[14] = '\0'; | |||
2231 | strncpy(num2, &line[j], 14); num2[14] = '\0'; | |||
2232 | ||||
2233 | sprintf(lineVal, "\"%s\":%s,\"%s\":%s,","CL", num1, "CD", num2); | |||
2234 | strcat(json,lineVal); // Add to JSON string | |||
2235 | ||||
2236 | status = getline(&line, &linecap, fp); | |||
2237 | if (status <=0) goto cleanup; | |||
2238 | ||||
2239 | strncpy(num1, &line[i], 14); num1[14] = '\0'; | |||
2240 | strncpy(num2, &line[j], 14); num2[14] = '\0'; | |||
2241 | strncpy(num3, &line[k], 14); num3[14] = '\0'; | |||
2242 | ||||
2243 | sprintf(lineVal, "\"%s\":%s,\"%s\":%s,\"%s\":%s,", | |||
2244 | "CMX", num1, "CMY", num2, "CMZ", num3); | |||
2245 | strcat(json,lineVal); // Add to JSON string | |||
2246 | ||||
2247 | status = getline(&line, &linecap, fp); | |||
2248 | if (status <=0) goto cleanup; | |||
2249 | ||||
2250 | strncpy(num1, &line[i], 14); num1[14] = '\0'; | |||
2251 | strncpy(num2, &line[j], 14); num2[14] = '\0'; | |||
2252 | strncpy(num3, &line[k], 14); num3[14] = '\0'; | |||
2253 | ||||
2254 | sprintf(lineVal, "\"%s\":%s,\"%s\":%s,\"%s\":%s", | |||
2255 | "CX", num1, "CY", num2, "CZ", num3); | |||
2256 | strcat(json,lineVal); // Add to JSON string | |||
2257 | ||||
2258 | strcat(json,"}"); | |||
2259 | ||||
2260 | // printf("JSON = %s\n", json); | |||
2261 | ||||
2262 | if (strcmp(name, "Total") != 0) { | |||
2263 | status = string_toInteger(name, &nameIndex); | |||
2264 | if (status != CAPS_SUCCESS0) goto cleanup; | |||
2265 | } else { | |||
2266 | nameIndex = -1; | |||
2267 | } | |||
2268 | ||||
2269 | status = get_mapAttrToIndexKeyword(attrMap, nameIndex, &keyWord); | |||
2270 | if (status == CAPS_SUCCESS0) { | |||
2271 | 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", 2271, __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" , 2271, __func__, 2, "AIM_STRDUP: %s %s", "val->vals.tuple[val->nrow-1].name" , keyWord); goto cleanup; } }; | |||
2272 | } else { | |||
2273 | 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", 2273, __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" , 2273, __func__, 2, "AIM_STRDUP: %s %s", "val->vals.tuple[val->nrow-1].name" , name); goto cleanup; } }; | |||
2274 | } | |||
2275 | ||||
2276 | 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", 2276 , __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" , 2276, __func__, 2, "AIM_STRDUP: %s %s", "val->vals.tuple[val->nrow-1].value" , json); goto cleanup; } }; | |||
2277 | ||||
2278 | // Reset name index value in case we have totals next | |||
2279 | nameIndex = 0; | |||
2280 | } | |||
2281 | } | |||
2282 | ||||
2283 | status = CAPS_SUCCESS0; | |||
2284 | ||||
2285 | cleanup: | |||
2286 | if (status != CAPS_SUCCESS0) | |||
2287 | printf("Premature exit in fun3dAIM fun3d_readForcesJSON status = %d\n", | |||
2288 | status); | |||
2289 | ||||
2290 | if (line != NULL((void*)0)) EG_free(line); | |||
2291 | ||||
2292 | return status; | |||
2293 | } | |||
2294 | ||||
2295 | ||||
2296 | static int fun3d_readForces(void *aimInfo, FILE *fp, int index, capsValue *val) | |||
2297 | { | |||
2298 | ||||
2299 | int status; // Function return | |||
2300 | ||||
2301 | size_t linecap = 0; | |||
2302 | ||||
2303 | char *strKeyword = NULL((void*)0), *bndSectionKeyword = NULL((void*)0), *bndSubSectionKeyword = NULL((void*)0); // Keyword strings | |||
2304 | ||||
2305 | char *strValue; // Holder string for value of keyword | |||
2306 | char *line = NULL((void*)0); // Temporary line holder | |||
2307 | ||||
2308 | int bndSectionFound = (int) false0; | |||
2309 | int bndSubSectionFound = (int) false0; | |||
2310 | ||||
2311 | if (fp == NULL((void*)0)) { | |||
2312 | status = CAPS_NULLVALUE-307; | |||
2313 | goto cleanup; | |||
2314 | } | |||
2315 | ||||
2316 | if (val == NULL((void*)0)) { | |||
2317 | status = CAPS_NULLVALUE-307; | |||
2318 | goto cleanup; | |||
2319 | } | |||
2320 | ||||
2321 | // Set the "search" string(s) | |||
2322 | if (index <= CZtot) { | |||
2323 | ||||
2324 | bndSectionKeyword = (char *) " FORCE TOTALS FOR ALL BOUNDARIES\n"; | |||
2325 | bndSubSectionKeyword = (char *) " Total forces\n"; | |||
2326 | ||||
2327 | } else if (index <= CZtot_p) { | |||
2328 | ||||
2329 | bndSectionKeyword = (char *) " FORCE TOTALS FOR ALL BOUNDARIES\n"; | |||
2330 | bndSubSectionKeyword = (char *) " Pressure forces\n"; | |||
2331 | ||||
2332 | } else if (index <= CZtot_v) { | |||
2333 | ||||
2334 | bndSectionKeyword = (char *) " FORCE TOTALS FOR ALL BOUNDARIES\n"; | |||
2335 | bndSubSectionKeyword = (char *) " Viscous forces\n"; | |||
2336 | } else if (index == Forces) { | |||
2337 | bndSectionKeyword = (char *) "FORCE SUMMARY FOR BOUNDARY"; | |||
2338 | } else { | |||
2339 | AIM_ERROR(aimInfo, "Developer error: Bad index %d", index){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 2339, __func__ , "Developer error: Bad index %d", index); }; | |||
2340 | status = CAPS_NOTIMPLEMENT-334; | |||
2341 | goto cleanup; | |||
2342 | } | |||
2343 | ||||
2344 | if (index == CLtot || index == CLtot_p || index == CLtot_v ) strKeyword = (char *) "Cl ="; | |||
2345 | else if (index == CDtot || index == CDtot_p || index == CDtot_v ) strKeyword = (char *) "Cd ="; | |||
2346 | else if (index == CMXtot || index == CMXtot_p || index == CMXtot_v) strKeyword = (char *) "Cmx ="; | |||
2347 | else if (index == CMYtot || index == CMYtot_p || index == CMYtot_v) strKeyword = (char *) "Cmy ="; | |||
2348 | else if (index == CMZtot || index == CMZtot_p || index == CMZtot_v) strKeyword = (char *) "Cmz ="; | |||
2349 | else if (index == CXtot || index == CXtot_p || index == CXtot_v ) strKeyword = (char *) "Cx ="; | |||
2350 | else if (index == CYtot || index == CYtot_p || index == CYtot_v ) strKeyword = (char *) "Cy ="; | |||
2351 | else if (index == CZtot || index == CZtot_p || index == CZtot_v ) strKeyword = (char *) "Cz ="; | |||
2352 | else { | |||
2353 | AIM_ERROR(aimInfo, "Unrecognized output variable index - %d\n", index){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 2353, __func__ , "Unrecognized output variable index - %d\n", index); }; | |||
2354 | return CAPS_BADINDEX-304; | |||
2355 | } | |||
2356 | ||||
2357 | // Scan the file for the string | |||
2358 | strValue = NULL((void*)0); | |||
2359 | while (getline(&line, &linecap, fp) >= 0) { | |||
2360 | ||||
2361 | if (line == NULL((void*)0)) continue; | |||
2362 | ||||
2363 | if (strcmp(line, bndSectionKeyword) == 0 && bndSectionFound == (int) false0) { | |||
2364 | ||||
2365 | //printf("FOUND section\n"); | |||
2366 | bndSectionFound = (int) true1; | |||
2367 | continue; // Skip to next line | |||
2368 | } | |||
2369 | ||||
2370 | if (bndSubSectionKeyword != NULL((void*)0)) | |||
2371 | if (strcmp(line, bndSubSectionKeyword) == 0 && | |||
2372 | bndSectionFound == (int) true1 && bndSubSectionFound == (int) false0) { | |||
2373 | ||||
2374 | //printf("Found sub-sections\n"); | |||
2375 | bndSubSectionFound = (int) true1; | |||
2376 | continue; // Skipe to next line | |||
2377 | } | |||
2378 | ||||
2379 | if (bndSectionFound == (int) true1 && bndSubSectionFound == (int) true1){ | |||
2380 | ||||
2381 | strValue = strstr(line, strKeyword); | |||
2382 | ||||
2383 | if (strValue != NULL((void*)0)) { | |||
2384 | ||||
2385 | //printf("String value %s\n", strValue); | |||
2386 | ||||
2387 | // Found it -- get the value | |||
2388 | ||||
2389 | status = string_toDouble(&strValue[6], &val->vals.real); | |||
2390 | if (status != CAPS_SUCCESS0) goto cleanup; | |||
2391 | val->nullVal = NotNull; | |||
2392 | ||||
2393 | break; | |||
2394 | } | |||
2395 | } | |||
2396 | } | |||
2397 | ||||
2398 | if (strValue == NULL((void*)0)) { | |||
2399 | AIM_ERROR(aimInfo, "Failed to find %s in .forces file", bndSectionKeyword){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 2399, __func__ , "Failed to find %s in .forces file", bndSectionKeyword); }; | |||
2400 | status = CAPS_NOTFOUND-303; | |||
2401 | goto cleanup; | |||
2402 | } | |||
2403 | ||||
2404 | status = CAPS_SUCCESS0; | |||
2405 | ||||
2406 | cleanup: | |||
2407 | ||||
2408 | if (line != NULL((void*)0)) EG_free(line); | |||
2409 | ||||
2410 | return status; | |||
2411 | } | |||
2412 | ||||
2413 | ||||
2414 | // Calculate FUN3D output | |||
2415 | int aimCalcOutput(void *instStore, /*@unused@*/ void *aimInfo, int index, | |||
2416 | capsValue *val) | |||
2417 | { | |||
2418 | int status = CAPS_SUCCESS0; | |||
2419 | ||||
2420 | char filename[PATH_MAX4096]; // File to open | |||
2421 | char fileExtension[] = ".forces"; | |||
2422 | capsValue *ProjName=NULL((void*)0); | |||
2423 | const char *projectName =NULL((void*)0); | |||
2424 | ||||
2425 | FILE *fp = NULL((void*)0); // File pointer | |||
2426 | capsValue *design_functional=NULL((void*)0), *design_sensfile=NULL((void*)0); | |||
2427 | aimStorage *fun3dInstance; | |||
2428 | ||||
2429 | fun3dInstance = (aimStorage *) instStore; | |||
2430 | ||||
2431 | status = aim_getValue(aimInfo, Proj_Name, ANALYSISIN, &ProjName); | |||
2432 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 2432 , __func__, 0); goto cleanup; }; | |||
2433 | AIM_NOTNULL(ProjName, aimInfo, status){ if (ProjName == ((void*)0)) { status = -307; aim_status(aimInfo , status, "fun3dAIM.c", 2433, __func__, 1, "%s == NULL!", "ProjName" ); goto cleanup; } }; | |||
2434 | projectName = ProjName->vals.string; | |||
2435 | ||||
2436 | val->vals.real = 0.0; // Set default value | |||
2437 | ||||
2438 | if (index <= Forces) { | |||
2439 | // Open fun3d *.force file | |||
2440 | status = aim_getValue(aimInfo, Design_Functional, ANALYSISIN, &design_functional); | |||
2441 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 2441 , __func__, 0); goto cleanup; }; | |||
2442 | AIM_NOTNULL(design_functional, aimInfo, status){ if (design_functional == ((void*)0)) { status = -307; aim_status (aimInfo, status, "fun3dAIM.c", 2442, __func__, 1, "%s == NULL!" , "design_functional"); goto cleanup; } }; | |||
2443 | ||||
2444 | status = aim_getValue(aimInfo, Design_SensFile, ANALYSISIN, &design_sensfile); | |||
2445 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 2445 , __func__, 0); goto cleanup; }; | |||
2446 | AIM_NOTNULL(design_sensfile, aimInfo, status){ if (design_sensfile == ((void*)0)) { status = -307; aim_status (aimInfo, status, "fun3dAIM.c", 2446, __func__, 1, "%s == NULL!" , "design_sensfile"); goto cleanup; } }; | |||
2447 | ||||
2448 | if (design_functional->nullVal == NotNull || | |||
2449 | design_sensfile->vals.integer == (int) true1) { | |||
2450 | #ifdef WIN32 | |||
2451 | snprintf(filename, PATH_MAX4096, "Flow\\%s%s", projectName, fileExtension); | |||
2452 | #else | |||
2453 | snprintf(filename, PATH_MAX4096, "Flow/%s%s", projectName, fileExtension); | |||
2454 | #endif | |||
2455 | } else { | |||
2456 | snprintf(filename, PATH_MAX4096, "%s%s", projectName, fileExtension); | |||
2457 | } | |||
2458 | ||||
2459 | fp = aim_fopen(aimInfo, filename, "r"); | |||
2460 | if (fp == NULL((void*)0)) { | |||
2461 | AIM_ERROR(aimInfo, "Could not open file: %s", filename){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 2461, __func__ , "Could not open file: %s", filename); }; | |||
2462 | status = CAPS_IOERR-332; | |||
2463 | goto cleanup; | |||
2464 | } | |||
2465 | ||||
2466 | if (index < Forces) { | |||
2467 | status = fun3d_readForces(aimInfo, fp, index, val); | |||
2468 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 2468 , __func__, 0); goto cleanup; }; | |||
2469 | ||||
2470 | } else if (index == Forces) { | |||
2471 | status = fun3d_readForcesJSON(aimInfo, fp, &fun3dInstance->groupMap, val); | |||
2472 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "fun3dAIM.c", 2472 , __func__, 0); goto cleanup; }; | |||
2473 | } | |||
2474 | ||||
2475 | } else { | |||
2476 | AIM_ERROR(aimInfo, "Unknown output index %d", index){ aim_message(aimInfo, CERROR, 0 , "fun3dAIM.c", 2476, __func__ , "Unknown output index %d", index); }; | |||
2477 | status = CAPS_BADINDEX-304; | |||
2478 | goto cleanup; | |||
2479 | } | |||
2480 | ||||
2481 | status = CAPS_SUCCESS0; | |||
2482 | ||||
2483 | cleanup: | |||
2484 | ||||
2485 | if (fp != NULL((void*)0)) fclose(fp); | |||
2486 | ||||
2487 | return status; | |||
2488 | } | |||
2489 | ||||
2490 | ||||
2491 | void aimCleanup(void *instStore) | |||
2492 | { | |||
2493 | aimStorage *fun3dInstance; | |||
2494 | ||||
2495 | #ifdef DEBUG | |||
2496 | printf(" fun3dAIM/aimCleanup!\n"); | |||
2497 | ||||
2498 | #endif | |||
2499 | fun3dInstance = (aimStorage *) instStore; | |||
2500 | ||||
2501 | // Clean up fun3dInstance data | |||
2502 | ||||
2503 | // Attribute to index map | |||
2504 | (void) destroy_mapAttrToIndexStruct(&fun3dInstance->groupMap); | |||
2505 | //status = destroy_mapAttrToIndexStruct(&fun3dInstance->attrMap); | |||
2506 | //if (status != CAPS_SUCCESS) return status; | |||
2507 | ||||
2508 | // Pointer to caps input value for scaling pressure during data transfer | |||
2509 | fun3dInstance->pressureScaleFactor = NULL((void*)0); | |||
2510 | ||||
2511 | // Pointer to caps input value for offset pressure during data transfer | |||
2512 | fun3dInstance->pressureScaleOffset = NULL((void*)0); | |||
2513 | ||||
2514 | // Design information | |||
2515 | (void) destroy_cfdDesignStruct(&fun3dInstance->design); | |||
2516 | ||||
2517 | // Cleanup units | |||
2518 | destroy_cfdUnitsStruct(&fun3dInstance->units); | |||
2519 | ||||
2520 | EG_free(fun3dInstance); | |||
2521 | } | |||
2522 | ||||
2523 | ||||
2524 | /************************************************************************/ | |||
2525 | // CAPS transferring functions | |||
2526 | ||||
2527 | void aimFreeDiscrPtr(void *ptrm) | |||
2528 | { | |||
2529 | #ifdef DEBUG | |||
2530 | printf(" fun3dAIM/aimFreeDiscr!\n"); | |||
2531 | #endif | |||
2532 | ||||
2533 | /* free up this capsDiscr user pointer */ | |||
2534 | AIM_FREE(ptrm){ EG_free(ptrm); ptrm = ((void*)0); }; | |||
2535 | } | |||
2536 | ||||
2537 | ||||
2538 | int aimDiscr(char *tname, capsDiscr *discr) | |||
2539 | { | |||
2540 | ||||
2541 | int i; // Indexing | |||
2542 | ||||
2543 | int status; // Function return status | |||
2544 | ||||
2545 | int numBody; | |||
2546 | ||||
2547 | // EGADS objects | |||
2548 | ego *bodies = NULL((void*)0), *tess = NULL((void*)0); | |||
2549 | ||||
2550 | const char *intents; | |||
2551 | capsValue *meshVal; | |||
2552 | ||||
2553 | // Volume Mesh obtained from meshing AIM | |||
2554 | aimMeshRef *meshRef; | |||
2555 | ||||
2556 | aimStorage *fun3dInstance; | |||
2557 | ||||
2558 | fun3dInstance = (aimStorage *) discr->instStore; | |||
2559 | ||||
2560 | #ifdef DEBUG | |||
2561 | printf(" fun3dAIM/aimDiscr: tname = %s!\n", tname); | |||
2562 | #endif | |||
2563 | ||||
2564 | if (tname == NULL((void*)0)) return CAPS_NOTFOUND-303; | |||
2565 | ||||
2566 | // Currently this ONLY works if the capsTranfer lives on single body! | |||
2567 | status = aim_getBodies(discr->aInfo, &intents, &numBody, &bodies); | |||
2568 | if (status != CAPS_SUCCESS0) { | |||
2569 | printf(" fun3dAIM/aimDiscr: aim_getBodies = %d!\n", status); | |||
2570 | return status; | |||
2571 | } | |||
2572 | if (bodies == NULL((void*)0)) { | |||
2573 | AIM_ERROR(discr->aInfo, " fun3dAIM/aimDiscr: NULL Bodies!\n"){ aim_message(discr->aInfo, CERROR, 0 , "fun3dAIM.c", 2573 , __func__, " fun3dAIM/aimDiscr: NULL Bodies!\n"); }; | |||
2574 | return CAPS_NULLOBJ-309; | |||
2575 | } | |||
2576 | ||||
2577 | ||||
2578 | // Get the mesh Value | |||
2579 | status = aim_getValue(discr->aInfo, Mesh, ANALYSISIN, &meshVal); | |||
2580 | AIM_STATUS(discr->aInfo, status)if (status != 0) { aim_status(discr->aInfo, status, "fun3dAIM.c" , 2580, __func__, 0); goto cleanup; }; | |||
2581 | ||||
2582 | if (meshVal->nullVal == IsNull) { | |||
2583 | 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", 2583 , __func__, "'Mesh' input must be linked to an output 'Area_Mesh' or 'Volume_Mesh'" ); }; | |||
2584 | status = CAPS_BADVALUE-311; | |||
2585 | goto cleanup; | |||
2586 | } | |||
2587 | ||||
2588 | // Get mesh | |||
2589 | meshRef = (aimMeshRef *)meshVal->vals.AIMptr; | |||
2590 | AIM_NOTNULL(meshRef, discr->aInfo, status){ if (meshRef == ((void*)0)) { status = -307; aim_status(discr ->aInfo, status, "fun3dAIM.c", 2590, __func__, 1, "%s == NULL!" , "meshRef"); goto cleanup; } }; | |||
2591 | ||||
2592 | if (meshRef->nmap == 0) { | |||
2593 | AIM_ERROR(discr->aInfo, "No surface meshes in volume mesh - data transfer isn't possible.\n"){ aim_message(discr->aInfo, CERROR, 0 , "fun3dAIM.c", 2593 , __func__, "No surface meshes in volume mesh - data transfer isn't possible.\n" ); }; | |||
2594 | status = CAPS_BADVALUE-311; | |||
2595 | goto cleanup; | |||
2596 | } | |||
2597 | ||||
2598 | if (aim_newGeometry(discr->aInfo) == CAPS_SUCCESS0 && | |||
2599 | fun3dInstance->groupMap.numAttribute == 0) { | |||
2600 | // Get capsGroup name and index mapping to make sure all faces have a capsGroup value | |||
2601 | status = create_CAPSGroupAttrToIndexMap(numBody, | |||
2602 | bodies, | |||
2603 | 1, // Only search down to the face level of the EGADS body | |||
2604 | &fun3dInstance->groupMap); | |||
2605 | AIM_STATUS(discr->aInfo, status)if (status != 0) { aim_status(discr->aInfo, status, "fun3dAIM.c" , 2605, __func__, 0); goto cleanup; }; | |||
2606 | } | |||
2607 | ||||
2608 | // Lets check the volume mesh | |||
2609 | ||||
2610 | // Do we have an individual surface mesh for each body | |||
2611 | if (meshRef->nmap != numBody) { | |||
2612 | 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", 2612 , __func__, "Number of surface mesh in the linked volume mesh (%d) does not match the number" ); }; | |||
2613 | 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); }; | |||
2614 | status = CAPS_MISMATCH-324; | |||
2615 | goto cleanup; | |||
2616 | } | |||
2617 | ||||
2618 | // To this point is doesn't appear that the volume mesh has done anything bad to our surface mesh(es) | |||
2619 | ||||
2620 | // Lets store away our tessellation now | |||
2621 | AIM_ALLOC(tess, meshRef->nmap, ego, discr->aInfo, status){ if (tess != ((void*)0)) { status = -4; aim_status(discr-> aInfo, status, "fun3dAIM.c", 2621, __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", 2621, __func__, 3, "AIM_ALLOC: %s size %zu type %s" , "tess", memorysize, "ego"); goto cleanup; } }; | |||
2622 | for (i = 0; i < meshRef->nmap; i++) { | |||
2623 | tess[i] = meshRef->maps[i].tess; | |||
2624 | } | |||
2625 | ||||
2626 | status = mesh_fillDiscr(tname, &fun3dInstance->groupMap, meshRef->nmap, tess, discr); | |||
2627 | AIM_STATUS(discr->aInfo, status)if (status != 0) { aim_status(discr->aInfo, status, "fun3dAIM.c" , 2627, __func__, 0); goto cleanup; }; | |||
2628 | ||||
2629 | #ifdef DEBUG | |||
2630 | printf(" fun3dAIM/aimDiscr: Finished!!\n"); | |||
2631 | #endif | |||
2632 | ||||
2633 | status = CAPS_SUCCESS0; | |||
2634 | ||||
2635 | cleanup: | |||
2636 | AIM_FREE(tess){ EG_free(tess); tess = ((void*)0); }; | |||
2637 | return status; | |||
2638 | } | |||
2639 | ||||
2640 | ||||
2641 | int | |||
2642 | aimLocateElement(capsDiscr *discr, double *params, double *param, | |||
2643 | int *bIndex, int *eIndex, double *bary) | |||
2644 | { | |||
2645 | return aim_locateElement(discr, params, param, bIndex, eIndex, bary); | |||
2646 | } | |||
2647 | ||||
2648 | ||||
2649 | int aimTransfer(capsDiscr *discr, const char *dataName, int numPoint, | |||
2650 | int dataRank, double *dataVal, /*@unused@*/ char **units) | |||
2651 | { | |||
2652 | /*! \page dataTransferFUN3D FUN3D Data Transfer | |||
2653 | * | |||
2654 | * The FUN3D AIM has the ability to transfer surface data (e.g. pressure distributions) to and from the AIM | |||
2655 | * using the conservative and interpolative data transfer schemes in CAPS. Currently these transfers may only | |||
2656 | * take place on triangular meshes. | |||
2657 | * | |||
2658 | * \section dataFromFUN3D Data transfer from FUN3D (FieldOut) | |||
2659 | * | |||
2660 | * <ul> | |||
2661 | * <li> <B>"Pressure", "P", "Cp", or "CoefficientOfPressure"</B> </li> <br> | |||
2662 | * Loads the coefficient of pressure distribution from [project_name]_ddfdrive_bndry[#].dat file(s) | |||
2663 | * (as generate from a FUN3D command line option of -\-write_aero_loads_to_file) into the data | |||
2664 | * transfer scheme. This distribution may be scaled based on | |||
2665 | * Pressure = Pressure_Scale_Factor*Cp + Pressure_Scale_Offset, where "Pressure_Scale_Factor" | |||
2666 | * and "Pressure_Scale_Offset" are AIM inputs (\ref aimInputsFUN3D). | |||
2667 | * </ul> | |||
2668 | * | |||
2669 | */ // Rest of this block comes from fun3dUtil.c | |||
2670 | ||||
2671 | int status, status2; // Function return status | |||
2672 | int i, j, dataPoint, capsGroupIndex, bIndex; // Indexing | |||
2673 | aimStorage *fun3dInstance; | |||
2674 | ||||
2675 | // Aero-Load data variables | |||
2676 | int numVariable; | |||
| ||||
2677 | int numDataPoint; | |||
2678 | char **variableName = NULL((void*)0); | |||
2679 | double **dataMatrix = NULL((void*)0); | |||
2680 | double dataScaleFactor = 1.0; | |||
2681 | double dataScaleOffset = 0.0; | |||
2682 | //char *dataUnits = NULL; | |||
2683 | ||||
2684 | // Indexing in data variables | |||
2685 | int globalIDIndex = -99; | |||
2686 | int variableIndex = -99; | |||
2687 | ||||
2688 | // Variables used in global node mapping | |||
2689 | int *storage; | |||
2690 | int globalNodeID; | |||
2691 | int found = (int) false0; | |||
2692 | ||||
2693 | // Filename stuff | |||
2694 | int *capsGroupList; | |||
2695 | char *filename = NULL((void*)0); //"pyCAPS_FUN3D_Tetgen_ddfdrive_bndry1.dat"; | |||
2696 | capsValue *ProjName=NULL((void*)0); | |||
2697 | const char *projectName =NULL((void*)0); | |||
2698 | ||||
2699 | #ifdef DEBUG | |||
2700 | printf(" fun3dAIM/aimTransfer name = %s npts = %d/%d!\n", | |||
2701 | dataName, numPoint, dataRank); | |||
2702 | #endif | |||
2703 | ||||
2704 | fun3dInstance = (aimStorage *) discr->instStore; | |||
2705 | ||||
2706 | if (strcasecmp(dataName, "Pressure") != 0 && | |||
2707 | strcasecmp(dataName, "P") != 0 && | |||
2708 | strcasecmp(dataName, "Cp") != 0 && | |||
2709 | strcasecmp(dataName, "CoefficientOfPressure") != 0) { | |||
2710 | ||||
2711 | printf("Unrecognized data transfer variable - %s\n", dataName); | |||
2712 | return CAPS_NOTFOUND-303; | |||
2713 | } | |||
2714 | ||||
2715 | status = aim_getValue(discr->aInfo, Proj_Name, ANALYSISIN, &ProjName); | |||
2716 | AIM_STATUS(discr->aInfo, status)if (status != 0) { aim_status(discr->aInfo, status, "fun3dAIM.c" , 2716, __func__, 0); goto cleanup; }; | |||
2717 | AIM_NOTNULL(ProjName, discr->aInfo, status){ if (ProjName == ((void*)0)) { status = -307; aim_status(discr ->aInfo, status, "fun3dAIM.c", 2717, __func__, 1, "%s == NULL!" , "ProjName"); goto cleanup; } }; | |||
2718 | projectName = ProjName->vals.string; | |||
2719 | ||||
2720 | //Get the appropriate parts of the tessellation to data | |||
2721 | storage = (int *) discr->ptrm; | |||
2722 | capsGroupList = &storage[0]; // List of boundary ID (attrMap) in the transfer | |||
2723 | ||||
2724 | // Zero out data | |||
2725 | for (i = 0; i < numPoint; i++) { | |||
2726 | for (j = 0; j < dataRank; j++ ) { | |||
2727 | dataVal[dataRank*i+j] = 0; | |||
2728 | } | |||
2729 | } | |||
2730 | ||||
2731 | for (capsGroupIndex = 0; capsGroupIndex < capsGroupList[0]; capsGroupIndex++) { | |||
2732 | ||||
2733 | AIM_ALLOC(filename, strlen(projectName) +{ if (filename != ((void*)0)) { status = -4; aim_status(discr ->aInfo, status, "fun3dAIM.c", 2734, __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", 2734 , __func__, 3, "AIM_ALLOC: %s size %zu type %s", "filename", memorysize , "char"); goto cleanup; } } | |||
2734 | strlen("_ddfdrive_bndry.dat")+7, char, discr->aInfo, status){ if (filename != ((void*)0)) { status = -4; aim_status(discr ->aInfo, status, "fun3dAIM.c", 2734, __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", 2734 , __func__, 3, "AIM_ALLOC: %s size %zu type %s", "filename", memorysize , "char"); goto cleanup; } }; | |||
2735 | ||||
2736 | sprintf(filename,"%s%s%d%s",projectName, | |||
2737 | "_ddfdrive_bndry", | |||
2738 | capsGroupList[capsGroupIndex+1], | |||
2739 | ".dat"); | |||
2740 | ||||
2741 | status = fun3d_readAeroLoad(discr->aInfo, filename, | |||
2742 | &numVariable, | |||
2743 | &variableName, | |||
2744 | &numDataPoint, | |||
2745 | &dataMatrix); | |||
2746 | // Try body file | |||
2747 | if (status == CAPS_IOERR-332) { | |||
2748 | ||||
2749 | 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", 2750, __func__, 3, "AIM_REALL: %s size %zu type %s" , "filename", memorysize, "char"); goto cleanup; } } | |||
2750 | 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", 2750, __func__, 3, "AIM_REALL: %s size %zu type %s" , "filename", memorysize, "char"); goto cleanup; } }; | |||
2751 | ||||
2752 | sprintf(filename,"%s%s%s",projectName, | |||
2753 | "_ddfdrive_body1", | |||
2754 | ".dat"); | |||
2755 | ||||
2756 | printf("Instead trying file : %s\n", filename); | |||
2757 | ||||
2758 | status = fun3d_readAeroLoad(discr->aInfo, filename, | |||
2759 | &numVariable, | |||
2760 | &variableName, | |||
2761 | &numDataPoint, | |||
2762 | &dataMatrix); | |||
2763 | } | |||
2764 | ||||
2765 | AIM_FREE(filename){ EG_free(filename); filename = ((void*)0); }; | |||
2766 | AIM_STATUS(discr->aInfo, status)if (status != 0) { aim_status(discr->aInfo, status, "fun3dAIM.c" , 2766, __func__, 0); goto cleanup; }; | |||
2767 | ||||
2768 | printf("Number of variables %d\n", numVariable); | |||
2769 | // Output some of the first row of the data | |||
2770 | //for (i = 0; i < numVariable; i++) printf("Variable %d - %.6f\n", i, dataMatrix[i][0]); | |||
2771 | ||||
2772 | // Loop through the variable list to find which one is the global node ID variable | |||
2773 | for (i = 0; i < numVariable; i++) { | |||
2774 | AIM_NOTNULL(variableName, discr->aInfo, status){ if (variableName == ((void*)0)) { status = -307; aim_status (discr->aInfo, status, "fun3dAIM.c", 2774, __func__, 1, "%s == NULL!" , "variableName"); goto cleanup; } }; | |||
2775 | if (strcasecmp("id", variableName[i]) == 0) { | |||
2776 | globalIDIndex = i; | |||
2777 | break; | |||
2778 | } | |||
2779 | } | |||
2780 | ||||
2781 | if (globalIDIndex == -99) { | |||
2782 | AIM_ERROR(discr->aInfo, "Global node number variable not found in data file\n"){ aim_message(discr->aInfo, CERROR, 0 , "fun3dAIM.c", 2782 , __func__, "Global node number variable not found in data file\n" ); }; | |||
2783 | status = CAPS_NOTFOUND-303; | |||
2784 | goto cleanup; | |||
2785 | } | |||
2786 | ||||
2787 | // Loop through the variable list to see if we can find the transfer data name | |||
2788 | for (i = 0; i < numVariable; i++) { | |||
2789 | AIM_NOTNULL(variableName, discr->aInfo, status){ if (variableName == ((void*)0)) { status = -307; aim_status (discr->aInfo, status, "fun3dAIM.c", 2789, __func__, 1, "%s == NULL!" , "variableName"); goto cleanup; } }; | |||
2790 | ||||
2791 | if (strcasecmp(dataName, "Pressure") == 0 || | |||
2792 | strcasecmp(dataName, "P") == 0 || | |||
2793 | strcasecmp(dataName, "Cp") == 0 || | |||
2794 | strcasecmp(dataName, "CoefficientOfPressure") == 0) { | |||
2795 | ||||
2796 | if (dataRank != 1) { | |||
2797 | printf("Data transfer rank should be 1 not %d\n", dataRank); | |||
2798 | status = CAPS_BADRANK-301; | |||
2799 | goto cleanup; | |||
2800 | } | |||
2801 | ||||
2802 | dataScaleFactor = fun3dInstance->pressureScaleFactor->vals.real; | |||
2803 | dataScaleOffset = fun3dInstance->pressureScaleOffset->vals.real; | |||
2804 | ||||
2805 | //dataUnits = fun3dInstance->pressureScaleFactor->units; | |||
2806 | if (strcasecmp("cp", variableName[i]) == 0) { | |||
2807 | variableIndex = i; | |||
2808 | break; | |||
2809 | } | |||
2810 | } | |||
2811 | } | |||
2812 | ||||
2813 | if (variableIndex == -99) { | |||
2814 | AIM_ERROR(discr->aInfo, "Variable %s not found in data file\n", dataName){ aim_message(discr->aInfo, CERROR, 0 , "fun3dAIM.c", 2814 , __func__, "Variable %s not found in data file\n", dataName) ; }; | |||
2815 | status = CAPS_NOTFOUND-303; | |||
2816 | goto cleanup; | |||
2817 | } | |||
2818 | if (dataMatrix == NULL((void*)0)) { | |||
2819 | AIM_ERROR(discr->aInfo, "Variable %s daata mtrix is NULL!\n", dataName){ aim_message(discr->aInfo, CERROR, 0 , "fun3dAIM.c", 2819 , __func__, "Variable %s daata mtrix is NULL!\n", dataName); }; | |||
2820 | status = CAPS_NULLVALUE-307; | |||
2821 | goto cleanup; | |||
2822 | } | |||
2823 | ||||
2824 | for (i = 0; i < numPoint; i++) { | |||
2825 | ||||
2826 | bIndex = discr->tessGlobal[2*i ]; | |||
2827 | globalNodeID = discr->tessGlobal[2*i+1] + | |||
2828 | discr->bodys[bIndex-1].globalOffset; | |||
2829 | ||||
2830 | found = (int) false0; | |||
2831 | for (dataPoint = 0; dataPoint < numDataPoint; dataPoint++) { | |||
2832 | if ((int) dataMatrix[globalIDIndex][dataPoint] == globalNodeID) { | |||
2833 | found = (int) true1; | |||
2834 | break; | |||
2835 | } | |||
2836 | } | |||
2837 | ||||
2838 | if (found == (int) true1) { | |||
2839 | for (j = 0; j < dataRank; j++) { | |||
2840 | ||||
2841 | // Add something for units - aim_covert() | |||
2842 | ||||
2843 | dataVal[dataRank*i+j] = dataMatrix[variableIndex][dataPoint]*dataScaleFactor + | |||
2844 | dataScaleOffset; | |||
2845 | //printf("DataValue = %f\n",dataVal[dataRank*i+j]); | |||
2846 | //dataVal[dataRank*i+j] = 99; | |||
2847 | ||||
2848 | } | |||
2849 | } | |||
2850 | } | |||
2851 | ||||
2852 | // Free data matrix | |||
2853 | if (dataMatrix != NULL((void*)0)) { | |||
2854 | for (i = 0; i < numVariable; i++) { | |||
2855 | AIM_FREE(dataMatrix[i]){ EG_free(dataMatrix[i]); dataMatrix[i] = ((void*)0); }; | |||
2856 | } | |||
2857 | AIM_FREE(dataMatrix){ EG_free(dataMatrix); dataMatrix = ((void*)0); }; | |||
2858 | } | |||
2859 | ||||
2860 | // Free variable list | |||
2861 | status = string_freeArray(numVariable, &variableName); | |||
2862 | AIM_STATUS(discr->aInfo, status)if (status != 0) { aim_status(discr->aInfo, status, "fun3dAIM.c" , 2862, __func__, 0); goto cleanup; }; | |||
2863 | ||||
2864 | } | |||
2865 | ||||
2866 | status = CAPS_SUCCESS0; | |||
2867 | ||||
2868 | cleanup: | |||
2869 | // Free data matrix | |||
2870 | if (dataMatrix
| |||
2871 | for (i = 0; i < numVariable; i++) { | |||
2872 | AIM_FREE(dataMatrix[i]){ EG_free(dataMatrix[i]); dataMatrix[i] = ((void*)0); }; | |||
2873 | } | |||
2874 | AIM_FREE(dataMatrix){ EG_free(dataMatrix); dataMatrix = ((void*)0); }; | |||
2875 | } | |||
2876 | ||||
2877 | // Free variable list | |||
2878 | status2 = string_freeArray(numVariable, &variableName); | |||
| ||||
2879 | if (status2 != CAPS_SUCCESS0) return status2; | |||
2880 | ||||
2881 | return status; | |||
2882 | } | |||
2883 | ||||
2884 | ||||
2885 | int | |||
2886 | aimInterpolation(capsDiscr *discr, /*@unused@*/ const char *name, int bIndex, | |||
2887 | int eIndex, double *bary, int rank, | |||
2888 | double *data, double *result) | |||
2889 | { | |||
2890 | #ifdef DEBUG | |||
2891 | printf(" fun3dAIM/aimInterpolation %s!\n", name); | |||
2892 | #endif | |||
2893 | return aim_interpolation(discr, name, bIndex, eIndex, | |||
2894 | bary, rank, data, result); | |||
2895 | } | |||
2896 | ||||
2897 | ||||
2898 | int | |||
2899 | aimInterpolateBar(capsDiscr *discr, /*@unused@*/ const char *name, int bIndex, | |||
2900 | int eIndex, double *bary, int rank, | |||
2901 | double *r_bar, double *d_bar) | |||
2902 | { | |||
2903 | #ifdef DEBUG | |||
2904 | printf(" fun3dAIM/aimInterpolateBar %s!\n", name); | |||
2905 | #endif | |||
2906 | return aim_interpolateBar(discr, name, bIndex, eIndex, | |||
2907 | bary, rank, r_bar, d_bar); | |||
2908 | } | |||
2909 | ||||
2910 | ||||
2911 | int | |||
2912 | aimIntegration(capsDiscr *discr, /*@unused@*/ const char *name, int bIndex, | |||
2913 | int eIndex, int rank, double *data, double *result) | |||
2914 | { | |||
2915 | #ifdef DEBUG | |||
2916 | printf(" fun3dAIM/aimIntegration %s!\n", name); | |||
2917 | #endif | |||
2918 | return aim_integration(discr, name, bIndex, eIndex, rank, | |||
2919 | data, result); | |||
2920 | } | |||
2921 | ||||
2922 | ||||
2923 | int | |||
2924 | aimIntegrateBar(capsDiscr *discr, /*@unused@*/ const char *name, int bIndex, | |||
2925 | int eIndex, int rank, double *r_bar, double *d_bar) | |||
2926 | { | |||
2927 | #ifdef DEBUG | |||
2928 | printf(" fun3dAIM/aimIntegrateBar %s!\n", name); | |||
2929 | #endif | |||
2930 | return aim_integrateBar(discr, name, bIndex, eIndex, rank, | |||
2931 | r_bar, d_bar); | |||
2932 | } |