Bug Summary

File:zaeroAIM.c
Warning:line 817, column 3
Value stored to 'status' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name zaeroAIM.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -D REVISION=7.8 -I /home/jenkins/workspace/ESP_Stanalizer/LINUX64/CAPS/scan-build/ESP/LINUX64/include -I ../utils -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-dangling-else -Wno-parentheses -Wno-unused-result -Wno-format-truncation -fdebug-compilation-dir /home/jenkins/workspace/ESP_Stanalizer/LINUX64/CAPS/scan-build/CAPS/aim/zaero -ferror-limit 19 -fmessage-length 0 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/jenkins/workspace/ESP_Stanalizer/LINUX64/CAPS/scan-build/scanCAPS/2024-04-11-232925-105816-1 -x c zaeroAIM.c
1/*
2 * CAPS: Computational Aircraft Prototype Syntheses
3 *
4 * ZAERO AIM
5 *
6 * Copyright 2014-2024, Massachusetts Institute of Technology
7 * Licensed under The GNU Lesser General Public License, version 2.1
8 * See http://www.opensource.org/licenses/lgpl-2.1.php
9 *
10 */
11
12/*!\mainpage Introduction
13 * \tableofcontents
14 * \section overviewZAERO ZAero AIM Overview
15 * A module in the Computational Aircraft Prototype Syntheses (CAPS) has been developed to interact (primarily
16 * through input files) with Zona's <a href="https://www.zonatech.com/zaero.html">ZAero</a>.
17 * ZAero is designed to multiplie different aeroelastic analysis disciplines. Currently only a subset of ZAero's
18 * input options have been exposed in the analysis interface module (AIM), but features can easily be included
19 * as future needs arise.
20 *
21 * An outline of the AIM's inputs and outputs are provided in \ref aimInputsZAERO and \ref aimOutputsZAERO, respectively.
22 *
23 * Geometric attributes recognized by the AIM are provided in \ref attributeZAERO.
24 *
25 * The accepted and expected geometric representation are detailed in \ref geomRepIntentZAERO.
26 *
27 */
28
29 /*! \page attributeZAERO Attribution
30 *
31 * The following list of attributes drives the ZAero geometric definition.
32 *
33 * - <b> capsLength</b> This attribute defines the length units that the *.csm file is generated in. ZAero grids
34 * MUST be in units of meter, as such the geometry is scaled accordingly based on this value.
35 *
36 * - <b> capsReferenceArea</b> [Optional] This attribute may exist on any <em> Body</em>. Its
37 * value will be used as the reference area in ZAero's input file with its units assumed to be consistent with
38 * the attribute "capsLength". No conversion takes place if "capsLength" isn't set. This value may be alternatively set
39 * through an input value, "ReferenceArea" (see \ref aimInputsZAERO)
40 *
41 * - <b> capsReferenceChord</b> and <b> capsReferenceSpan</b> [Optional] These attribute may exist on any <em> Body</em>. Their
42 * value will be used as the reference moment lengths in ZAero's input file with their units assumed to be consistent with
43 * the attribute "capsLength". No conversion takes place if "capsLength" isn't set. These values may be alternatively set
44 * through an input value, "Moment_Length" (see \ref aimInputsZAERO)
45 *
46 * - <b> capsReferenceX</b>, <b> capsReferenceY</b>, and <b>capsReferenceZ</b> [Optional]
47 * These attribute may exist on any <em> Body</em>. Their
48 * value will be used as the center of gravity (CG) location in ZAero's input file with their units assumed to be consistent with
49 * the attribute "capsLength". No conversion takes place if "capsLength" isn't set. These values may be alternatively set
50 * through an input value, "Moment_Center" (see \ref aimInputsZAERO)
51 *
52 */
53
54#include <stdlib.h>
55#include <stdarg.h>
56#include <string.h>
57#include <math.h>
58#include <time.h>
59
60#include "aimUtil.h"
61#include "miscUtils.h"
62#include "jsonUtils.h"
63#include "feaUtils.h"
64#include "vlmUtils.h"
65#include "cfdUtils.h"
66
67
68#include "zaeroUtils.h"
69#include "zaeroGeneral.h"
70#include "zaeroDiscipline.h"
71#include "zaeroGraphical.h"
72
73#ifdef WIN32
74#define getcwd _getcwd
75#define snprintf _snprintf
76#define strcasecmp stricmp
77#define PATH_MAX4096 _MAX_PATH
78#else
79#include <unistd.h>
80#include <limits.h>
81#endif
82
83//#define DEBUG
84
85#define CROSS(a,b,c)a[0] = (b[1]*c[2]) - (b[2]*c[1]); a[1] = (b[2]*c[0]) - (b[0]*
c[2]); a[2] = (b[0]*c[1]) - (b[1]*c[0])
a[0] = (b[1]*c[2]) - (b[2]*c[1]);\
86 a[1] = (b[2]*c[0]) - (b[0]*c[2]);\
87 a[2] = (b[0]*c[1]) - (b[1]*c[0])
88#define DOT(a,b)(a[0]*b[0] + a[1]*b[1] + a[2]*b[2]) (a[0]*b[0] + a[1]*b[1] + a[2]*b[2])
89
90
91enum aimInputs
92{
93 inProj_Name = 1, /* index is 1-based */
94 inAnalysis,
95 inFile_Format,
96 inFEM_1,
97 inF06_1,
98 inFEM_2,
99 inF06_2,
100 inCPU,
101 inMemory,
102 inSmart_Restart,
103 inEcho,
104 inOutput,
105 inHFG,
106 inUAIC,
107 inSpline,
108 inVLM_Surface,
109 inVLM_Control,
110 inTrim_Variable,
111 inReferenceArea,
112 inReferenceChord,
113 inReferenceSpan,
114 inMoment_Center,
115 inMassPropLink,
116 NUMINPUT = inMassPropLink /* Total number of inputs */
117};
118
119enum aimOutputs
120{
121 //outBeta = 1, /* index is 1-based */
122 NUMOUTPUT = 0 /* Total number of outputs */
123};
124
125
126#define MAXCHAR255 255
127
128
129/* ZAERO storage */
130typedef struct {
131
132 // whether to use Smart Restart
133 int smartRestart;
134
135 // Attribute to index map
136 mapAttrToIndexStruct attrMap;
137
138 // Units structure
139 cfdUnitsStruct units;
140
141 // Output formating
142 feaFileTypeEnum feaFormatType;
143
144 // ZAERO problem data
145 zaeroProblemStruct zaeroProblem;
146
147 // ZAERO artifact filenames, relative to analysis dir.
148 zaeroArtifactsStruct artifacts;
149
150} aimStorage;
151
152// AIM storage constructor
153static int initiate_aimStorage(aimStorage *zaeroInstance) {
154
155 // Set initial values for zaeroInstances
156
157 zaeroInstance->smartRestart = 0;
158
159 zaeroInstance->feaFormatType = SmallField;
160
161 // Container for attribute to index map
162 (void)initiate_mapAttrToIndexStruct(&zaeroInstance->attrMap);
163
164 (void)initiate_cfdUnitsStruct(&zaeroInstance->units);
165
166 (void)initiate_zaeroProblemStruct(&zaeroInstance->zaeroProblem);
167
168 (void)initiate_zaeroArtifactsStruct(&zaeroInstance->artifacts);
169
170 return CAPS_SUCCESS0;
171}
172
173// AIM storage destructor
174static int destroy_aimStorage(aimStorage *zaeroInstances) {
175
176 int status;
177
178 // Attribute to index map
179 status = destroy_mapAttrToIndexStruct(&zaeroInstances->attrMap);
180 if (status != CAPS_SUCCESS0)
181 printf("Error: Status %d during destroy_mapAttrToIndexStruct!\n", status);
182
183 // Destroy units
184 status = destroy_cfdUnitsStruct(&zaeroInstances->units);
185 if (status != CAPS_SUCCESS0)
186 printf("Error: Status %d during destroy_cfdUnitsStruct!\n", status);
187
188 // Destroy ZAERO problem struct
189 status = destroy_zaeroProblemStruct(&zaeroInstances->zaeroProblem);
190 if (status != CAPS_SUCCESS0) {
191 printf("Error: Status %d during destroy_zaeroProblemStruct!\n", status);
192 }
193
194 // Destroy ZAERO artifacts struct
195 status = destroy_zaeroArtifactsStruct(&zaeroInstances->artifacts);
196 if (status != CAPS_SUCCESS0) {
197 printf("Error: Status %d during destroy_zaeroArtifactsStruct!\n", status);
198 }
199
200 initiate_aimStorage(zaeroInstances);
201
202 return CAPS_SUCCESS0;
203}
204
205static int
206_createVLM(void *aimInfo,
207 capsValue *aimInputs,
208 aimStorage *zaeroInstance)
209{
210 int status, status2; // Function return status
211
212 int i, j, k, surfaceIndex = 0, sectionIndex; // Indexing
213
214 // Bodies
215 const char *intents;
216 int numBody; // Number of Bodies
217 ego *bodies;
218
219 int foundSref=(int)false0, foundCref=(int)false0, foundBref=(int)false0;
220 int foundXref=(int)false0, foundYref=(int)false0, foundZref=(int)false0;
221
222 const char *lengthUnits=NULL((void*)0);
223 double scaleFactor = 1.0;
224
225 // EGADS return values
226 int atype, alen;
227 const int *ints;
228 const char *string;
229 const double *reals;
230
231 // Aeroelastic information
232 int numVLMSurface = 0;
233 vlmSurfaceStruct *vlmSurface = NULL((void*)0);
234 int numSpanWise;
235
236 int numVLMControl = 0;
237 vlmControlStruct *vlmControl = NULL((void*)0);
238
239 const char *Lunits=NULL((void*)0);
240 const cfdUnitsStruct *units = &zaeroInstance->units;
241
242 // Get AIM bodies
243 status = aim_getBodies(aimInfo, &intents, &numBody, &bodies);
244 if (status != CAPS_SUCCESS0) return status;
245
246#ifdef DEBUG
247 printf(" nastranAIM/createVLMMesh nbody = %d!\n", numBody);
248#endif
249
250 if ((numBody <= 0) || (bodies == NULL((void*)0))) {
251#ifdef DEBUG
252 printf(" nastranAIM/createVLMMesh No Bodies!\n");
253#endif
254 return CAPS_SOURCEERR-330;
255 }
256
257 if (units->length != NULL((void*)0))
258 Lunits = units->length;
259 else
260 Lunits = "m";
261
262 // Get aerodynamic reference quantities
263
264 status = aim_capsLength(aimInfo, &lengthUnits);
265 AIM_NOTFOUND(aimInfo, status)if (status != 0 && status != -303 && status !=
-1) { aim_status(aimInfo, status, "zaeroAIM.c", 265, __func__
, 0); goto cleanup; }
;
266 if (status == CAPS_NOTFOUND-303) {
267 AIM_ERROR(aimInfo, "capsLength attribute must be specified for ZAero"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 267, __func__
, "capsLength attribute must be specified for ZAero"); }
;
268 goto cleanup;
269 }
270 AIM_NOTNULL(lengthUnits, aimInfo, status){ if (lengthUnits == ((void*)0)) { status = -307; aim_status(
aimInfo, status, "zaeroAIM.c", 270, __func__, 1, "%s == NULL!"
, "lengthUnits"); goto cleanup; } }
;
271
272 status = aim_convert(aimInfo, 1, lengthUnits, &scaleFactor, Lunits, &scaleFactor);
273 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 273
, __func__, 0); goto cleanup; }
;
274
275 // Loop over bodies and look for reference quantity attributes
276 for (i=0; i < numBody; i++) {
277 status = EG_attributeRet(bodies[i], "capsReferenceArea",
278 &atype, &alen, &ints, &reals, &string);
279 if (status == EGADS_SUCCESS0) {
280 if (atype == ATTRREAL2 && alen == 1) {
281 zaeroInstance->zaeroProblem.hfg.refArea = reals[0] * scaleFactor * scaleFactor;
282 foundSref = (int)true1;
283 } else {
284 AIM_ERROR(aimInfo, "capsReferenceArea should be followed by a single real value!\n"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 284, __func__
, "capsReferenceArea should be followed by a single real value!\n"
); }
;
285 status = CAPS_BADVALUE-311;
286 goto cleanup;
287 }
288 }
289
290 status = EG_attributeRet(bodies[i], "capsReferenceChord",
291 &atype, &alen, &ints, &reals, &string);
292 if (status == EGADS_SUCCESS0) {
293 if (atype == ATTRREAL2 && alen == 1) {
294 zaeroInstance->zaeroProblem.hfg.refChord = reals[0] * scaleFactor;
295 foundCref = (int)true1;
296 } else {
297 AIM_ERROR(aimInfo, "capsReferenceChord should be followed by a single real value!\n"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 297, __func__
, "capsReferenceChord should be followed by a single real value!\n"
); }
;
298 status = CAPS_BADVALUE-311;
299 goto cleanup;
300 }
301 }
302
303 status = EG_attributeRet(bodies[i], "capsReferenceSpan",
304 &atype, &alen, &ints, &reals, &string);
305 if (status == EGADS_SUCCESS0) {
306 if (atype == ATTRREAL2 && alen == 1) {
307 zaeroInstance->zaeroProblem.hfg.refSpan = reals[0] * scaleFactor;
308 foundBref = (int)true1;
309 } else {
310 AIM_ERROR(aimInfo, "capsReferenceSpan should be followed by a single real value!\n"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 310, __func__
, "capsReferenceSpan should be followed by a single real value!\n"
); }
;
311 status = CAPS_BADVALUE-311;
312 goto cleanup;
313 }
314 }
315
316 status = EG_attributeRet(bodies[i], "capsReferenceX",
317 &atype, &alen, &ints, &reals, &string);
318 if (status == EGADS_SUCCESS0) {
319
320 if (atype == ATTRREAL2 && alen == 1) {
321 zaeroInstance->zaeroProblem.hfg.refCenter[0] = reals[0] * scaleFactor;
322 foundXref = (int)true1;
323 } else {
324 AIM_ERROR(aimInfo, "capsReferenceX should be followed by a single real value!\n"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 324, __func__
, "capsReferenceX should be followed by a single real value!\n"
); }
;
325 status = CAPS_BADVALUE-311;
326 goto cleanup;
327 }
328 }
329
330 status = EG_attributeRet(bodies[i], "capsReferenceY",
331 &atype, &alen, &ints, &reals, &string);
332 if (status == EGADS_SUCCESS0) {
333
334 if (atype == ATTRREAL2 && alen == 1) {
335 zaeroInstance->zaeroProblem.hfg.refCenter[1] = reals[0] * scaleFactor;
336 foundYref = (int)true1;
337 } else {
338 AIM_ERROR(aimInfo, "capsReferenceY should be followed by a single real value!\n"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 338, __func__
, "capsReferenceY should be followed by a single real value!\n"
); }
;
339 status = CAPS_BADVALUE-311;
340 goto cleanup;
341 }
342 }
343
344 status = EG_attributeRet(bodies[i], "capsReferenceZ",
345 &atype, &alen, &ints, &reals, &string);
346 if (status == EGADS_SUCCESS0){
347
348 if (atype == ATTRREAL2 && alen == 1) {
349 zaeroInstance->zaeroProblem.hfg.refCenter[2] = reals[0] * scaleFactor;
350 foundZref = (int)true1;
351 } else {
352 AIM_ERROR(aimInfo, "capsReferenceZ should be followed by a single real value!\n"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 352, __func__
, "capsReferenceZ should be followed by a single real value!\n"
); }
;
353 status = CAPS_BADVALUE-311;
354 goto cleanup;
355 }
356 }
357 }
358
359 if (aimInputs[inReferenceArea-1].nullVal == NotNull) {
360 zaeroInstance->zaeroProblem.hfg.refArea = aimInputs[inReferenceArea-1].vals.real;
361 foundSref = (int)true1;
362 }
363 if (aimInputs[inReferenceChord-1].nullVal == NotNull) {
364 zaeroInstance->zaeroProblem.hfg.refChord = aimInputs[inReferenceChord-1].vals.real;
365 foundCref = (int)true1;
366 }
367 if (aimInputs[inReferenceSpan-1].nullVal == NotNull) {
368 zaeroInstance->zaeroProblem.hfg.refSpan = aimInputs[inReferenceSpan-1].vals.real;
369 foundBref = (int)true1;
370 }
371
372 if (foundSref == (int)false0) {
373 AIM_ERROR(aimInfo, "capsReferenceArea is not set on any body and 'ReferenceArea' input not set!"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 373, __func__
, "capsReferenceArea is not set on any body and 'ReferenceArea' input not set!"
); }
;
374 status = CAPS_BADVALUE-311;
375 goto cleanup;
376 }
377 if (foundCref == (int)false0) {
378 AIM_ERROR(aimInfo, "capsReferenceChord is not set on any body and 'ReferenceChord' input not set!"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 378, __func__
, "capsReferenceChord is not set on any body and 'ReferenceChord' input not set!"
); }
;
379 status = CAPS_BADVALUE-311;
380 goto cleanup;
381 }
382 if (foundBref == (int)false0) {
383 AIM_ERROR(aimInfo, "capsReferenceSpan is not set on any body and 'ReferenceSpan' input not set!"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 383, __func__
, "capsReferenceSpan is not set on any body and 'ReferenceSpan' input not set!"
); }
;
384 status = CAPS_BADVALUE-311;
385 goto cleanup;
386 }
387
388 // Check for moment reference overwrites
389 if (aimInputs[inMoment_Center-1].nullVal == NotNull) {
390
391 zaeroInstance->zaeroProblem.hfg.refCenter[0] = aimInputs[inMoment_Center-1].vals.reals[0];
392 zaeroInstance->zaeroProblem.hfg.refCenter[1] = aimInputs[inMoment_Center-1].vals.reals[1];
393 zaeroInstance->zaeroProblem.hfg.refCenter[2] = aimInputs[inMoment_Center-1].vals.reals[2];
394 } else {
395 if (foundXref == (int)false0) {
396 AIM_ERROR(aimInfo, "capsReferenceX is not set on any body and 'Moment_Center' input not set!"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 396, __func__
, "capsReferenceX is not set on any body and 'Moment_Center' input not set!"
); }
;
397 status = CAPS_BADVALUE-311;
398 goto cleanup;
399 }
400 if (foundYref == (int)false0) {
401 AIM_ERROR(aimInfo, "capsReferenceY is not set on any body and 'Moment_Center' input not set!"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 401, __func__
, "capsReferenceY is not set on any body and 'Moment_Center' input not set!"
); }
;
402 status = CAPS_BADVALUE-311;
403 goto cleanup;
404 }
405 if (foundZref == (int)false0) {
406 AIM_ERROR(aimInfo, "capsReferenceZ is not set on any body and 'Moment_Center' input not set!"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 406, __func__
, "capsReferenceZ is not set on any body and 'Moment_Center' input not set!"
); }
;
407 status = CAPS_BADVALUE-311;
408 goto cleanup;
409 }
410 }
411
412
413 if (aim_newGeometry(aimInfo) == CAPS_SUCCESS0 ||
414 zaeroInstance->zaeroProblem.numAero == 0 ||
415 aim_newAnalysisIn(aimInfo, inVLM_Surface) == CAPS_SUCCESS0 ||
416 aim_newAnalysisIn(aimInfo, inVLM_Control) == CAPS_SUCCESS0) {
417
418 // Cleanup Aero storage first
419 if (zaeroInstance->zaeroProblem.feaAero != NULL((void*)0)) {
420 for (i = 0; i < zaeroInstance->zaeroProblem.numAero; i++) {
421 status = destroy_feaAeroStruct(&zaeroInstance->zaeroProblem.feaAero[i]);
422 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 422
, __func__, 0); goto cleanup; }
;
423 }
424 AIM_FREE(zaeroInstance->zaeroProblem.feaAero){ EG_free(zaeroInstance->zaeroProblem.feaAero); zaeroInstance
->zaeroProblem.feaAero = ((void*)0); }
;
425 }
426 zaeroInstance->zaeroProblem.numAero = 0;
427
428
429 // Get capsGroup name and index mapping
430 status = create_CAPSGroupAttrToIndexMap(numBody,
431 bodies,
432 3, //>2 - search the body, faces, edges, and all the nodes
433 &zaeroInstance->attrMap);
434 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 434
, __func__, 0); goto cleanup; }
;
435
436
437 // Get VLM surface information
438 if (aimInputs[inVLM_Surface-1].nullVal != IsNull) {
439
440 status = get_vlmSurface(aimInfo,
441 aimInputs[inVLM_Surface-1].length,
442 aimInputs[inVLM_Surface-1].vals.tuple,
443 &zaeroInstance->attrMap,
444 0.0, // default Cspace
445 &numVLMSurface,
446 &vlmSurface);
447 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 447
, __func__, 0); goto cleanup; }
;
448
449 } else {
450 AIM_ERROR(aimInfo, "No VLM_Surface tuple specified\n"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 450, __func__
, "No VLM_Surface tuple specified\n"); }
;
451 status = CAPS_NOTFOUND-303;
452 goto cleanup;
453 }
454
455 // Get VLM control surface information
456 if (aimInputs[inVLM_Control-1].nullVal == NotNull) {
457
458 status = get_vlmControl(aimInfo,
459 aimInputs[inVLM_Control-1].length,
460 aimInputs[inVLM_Control-1].vals.tuple,
461 &numVLMControl,
462 &vlmControl);
463
464 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 464
, __func__, 0); goto cleanup; }
;
465 }
466
467 printf("\nGetting FEA vortex lattice mesh\n");
468
469 status = vlm_getSections(aimInfo,
470 numBody,
471 bodies,
472 "Aerodynamic",
473 zaeroInstance->attrMap,
474 vlmGENERIC,
475 numVLMSurface,
476 &vlmSurface);
477 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 477
, __func__, 0); goto cleanup; }
;
478 if (vlmSurface == NULL((void*)0)) {
479 status = CAPS_NULLVALUE-307;
480 goto cleanup;
481 }
482
483 for (i = 0; i < numVLMSurface; i++) {
484
485 // Compute equal spacing
486 if (vlmSurface[i].NspanTotal > 0)
487 numSpanWise = vlmSurface[i].NspanTotal;
488 else if (vlmSurface[i].NspanSection > 0)
489 numSpanWise = (vlmSurface[i].numSection-1)*vlmSurface[i].NspanSection;
490 else {
491 AIM_ERROR(aimInfo , "Only one of numSpanTotal and numSpanPerSection can be non-zero!"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 491, __func__
, "Only one of numSpanTotal and numSpanPerSection can be non-zero!"
); }
;
492 AIM_ADDLINE(aimInfo, " numSpanTotal = %d", vlmSurface[i].NspanTotal){ aim_addLine(aimInfo, " numSpanTotal = %d", vlmSurface
[i].NspanTotal); }
;
493 AIM_ADDLINE(aimInfo, " numSpanPerSection = %d", vlmSurface[i].NspanSection){ aim_addLine(aimInfo, " numSpanPerSection = %d", vlmSurface
[i].NspanSection); }
;
494 status = CAPS_BADVALUE-311;
495 goto cleanup;
496 }
497
498 status = vlm_equalSpaceSpanPanels(aimInfo, numSpanWise,
499 vlmSurface[i].numSection,
500 vlmSurface[i].vlmSection);
501 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 501
, __func__, 0); goto cleanup; }
;
502 }
503
504 // Split the surfaces that have more than 2 sections into a new surface
505 for (i = 0; i < numVLMSurface; i++) {
506
507 if (vlmSurface->numSection < 2) {
508 AIM_ERROR(aimInfo, "Surface '%s' has less than two-sections!", vlmSurface[i].name){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 508, __func__
, "Surface '%s' has less than two-sections!", vlmSurface[i].name
); }
;
509 status = CAPS_BADVALUE-311;
510 goto cleanup;
511 }
512
513 for (j = 0; j < vlmSurface[i].numSection-1; j++) {
514
515 // Increment the number of Aero surfaces
516 zaeroInstance->zaeroProblem.numAero += 1;
517
518 surfaceIndex = zaeroInstance->zaeroProblem.numAero - 1;
519
520 // Allocate
521 AIM_REALL(zaeroInstance->zaeroProblem.feaAero, zaeroInstance->zaeroProblem.numAero, feaAeroStruct, aimInfo, status){ size_t memorysize = zaeroInstance->zaeroProblem.numAero;
zaeroInstance->zaeroProblem.feaAero = (feaAeroStruct *) EG_reall
(zaeroInstance->zaeroProblem.feaAero, memorysize*sizeof(feaAeroStruct
)); if (zaeroInstance->zaeroProblem.feaAero == ((void*)0))
{ status = -4; aim_status(aimInfo, status, "zaeroAIM.c", 521
, __func__, 3, "AIM_REALL: %s size %zu type %s", "zaeroInstance->zaeroProblem.feaAero"
, memorysize, "feaAeroStruct"); goto cleanup; } }
;
522
523 // Initiate feaAeroStruct
524 status = initiate_feaAeroStruct(&zaeroInstance->zaeroProblem.feaAero[surfaceIndex]);
525 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 525
, __func__, 0); goto cleanup; }
;
526
527 // Get surface Name - copy from original surface
528 AIM_STRDUP(zaeroInstance->zaeroProblem.feaAero[surfaceIndex].name, vlmSurface[i].name, aimInfo, status){ if (zaeroInstance->zaeroProblem.feaAero[surfaceIndex].name
!= ((void*)0)) { status = -4; aim_status(aimInfo, status, "zaeroAIM.c"
, 528, __func__, 1, "AIM_STRDUP: %s != NULL!", "zaeroInstance->zaeroProblem.feaAero[surfaceIndex].name"
); goto cleanup; } zaeroInstance->zaeroProblem.feaAero[surfaceIndex
].name = EG_strdup(vlmSurface[i].name); if (zaeroInstance->
zaeroProblem.feaAero[surfaceIndex].name == ((void*)0)) { status
= -4; aim_status(aimInfo, status, "zaeroAIM.c", 528, __func__
, 2, "AIM_STRDUP: %s %s", "zaeroInstance->zaeroProblem.feaAero[surfaceIndex].name"
, vlmSurface[i].name); goto cleanup; } }
;
529
530 // Get surface ID - Multiple by 1000 !!
531 zaeroInstance->zaeroProblem.feaAero[surfaceIndex].surfaceID =
532 1000*zaeroInstance->zaeroProblem.numAero;
533
534 // ADD something for coordinate systems
535
536 // Sections aren't necessarily stored in order coming out of vlm_getSections, however sectionIndex is!
537 sectionIndex = vlmSurface[i].vlmSection[j].sectionIndex;
538
539 // Populate vmlSurface structure
540 zaeroInstance->zaeroProblem.feaAero[surfaceIndex].vlmSurface.Cspace = vlmSurface[i].Cspace;
541 zaeroInstance->zaeroProblem.feaAero[surfaceIndex].vlmSurface.Sspace = vlmSurface[i].Sspace;
542
543 // use the section span count for the sub-surface
544 zaeroInstance->zaeroProblem.feaAero[surfaceIndex].vlmSurface.NspanTotal = vlmSurface[i].vlmSection[sectionIndex].Nspan;
545 zaeroInstance->zaeroProblem.feaAero[surfaceIndex].vlmSurface.Nchord = vlmSurface[i].Nchord;
546
547 // Copy section information
548 zaeroInstance->zaeroProblem.feaAero[surfaceIndex].vlmSurface.numSection = 2;
549
550 AIM_ALLOC(zaeroInstance->zaeroProblem.feaAero[surfaceIndex].vlmSurface.vlmSection, 2, vlmSectionStruct, aimInfo, status){ if (zaeroInstance->zaeroProblem.feaAero[surfaceIndex].vlmSurface
.vlmSection != ((void*)0)) { status = -4; aim_status(aimInfo,
status, "zaeroAIM.c", 550, __func__, 1, "AIM_ALLOC: %s != NULL"
, "zaeroInstance->zaeroProblem.feaAero[surfaceIndex].vlmSurface.vlmSection"
); goto cleanup; } size_t memorysize = 2; zaeroInstance->zaeroProblem
.feaAero[surfaceIndex].vlmSurface.vlmSection = (vlmSectionStruct
*) EG_alloc(memorysize*sizeof(vlmSectionStruct)); if (zaeroInstance
->zaeroProblem.feaAero[surfaceIndex].vlmSurface.vlmSection
== ((void*)0)) { status = -4; aim_status(aimInfo, status, "zaeroAIM.c"
, 550, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "zaeroInstance->zaeroProblem.feaAero[surfaceIndex].vlmSurface.vlmSection"
, memorysize, "vlmSectionStruct"); goto cleanup; } }
;
551
552 for (k = 0; k < zaeroInstance->zaeroProblem.feaAero[surfaceIndex].vlmSurface.numSection; k++) {
553
554 // Add k to section indexing variable j to get j and j+1 during iterations
555
556 // Sections aren't necessarily stored in order coming out of vlm_getSections, however sectionIndex is!
557 sectionIndex = vlmSurface[i].vlmSection[j+k].sectionIndex;
558
559 status = initiate_vlmSectionStruct(&zaeroInstance->zaeroProblem.feaAero[surfaceIndex].vlmSurface.vlmSection[k]);
560 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 560
, __func__, 0); goto cleanup; }
;
561
562 // Copy the section data - This also copies the control data for the section
563 status = copy_vlmSectionStruct(&vlmSurface[i].vlmSection[sectionIndex],
564 &zaeroInstance->zaeroProblem.feaAero[surfaceIndex].vlmSurface.vlmSection[k]);
565 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 565
, __func__, 0); goto cleanup; }
;
566
567 // Reset the sectionIndex that is keeping track of the section order.
568 zaeroInstance->zaeroProblem.feaAero[surfaceIndex].vlmSurface.vlmSection[k].sectionIndex = k;
569 }
570
571
572 if (numVLMControl > 0) {
573 AIM_NOTNULL(vlmControl, aimInfo, status){ if (vlmControl == ((void*)0)) { status = -307; aim_status(aimInfo
, status, "zaeroAIM.c", 573, __func__, 1, "%s == NULL!", "vlmControl"
); goto cleanup; } }
;
574 // transfer control surface data to sections
575 status = get_ControlSurface(bodies,
576 numVLMControl,
577 vlmControl,
578 &zaeroInstance->zaeroProblem.feaAero[surfaceIndex].vlmSurface);
579 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 579
, __func__, 0); goto cleanup; }
;
580 }
581 }
582 }
583
584 if (zaeroInstance->zaeroProblem.feaAero == NULL((void*)0)) {
585 status = CAPS_NULLVALUE-307;
586 goto cleanup;
587 }
588 }
589
590 status = CAPS_SUCCESS0;
591
592cleanup:
593
594 if (vlmSurface != NULL((void*)0)) {
595 for (i = 0; i < numVLMSurface; i++) {
596 status2 = destroy_vlmSurfaceStruct(&vlmSurface[i]);
597 if (status2 != CAPS_SUCCESS0)
598 printf("\tdestroy_vlmSurfaceStruct status = %d\n", status2);
599 }
600 }
601
602 AIM_FREE(vlmSurface){ EG_free(vlmSurface); vlmSurface = ((void*)0); };
603 numVLMSurface = 0;
604
605 // Destroy Control
606 if (vlmControl != NULL((void*)0)) {
607 for (i = 0; i < numVLMControl; i++) {
608 (void) destroy_vlmControlStruct(&vlmControl[i]);
609 }
610 AIM_FREE(vlmControl){ EG_free(vlmControl); vlmControl = ((void*)0); };
611 }
612 numVLMControl = 0;
613
614 return status;
615}
616
617
618static int
619_getFEMModule(void *aimInfo, capsValue *assign_fem, capsValue *f06Input, zaeroProblemStruct *zaeroProblem) {
620
621 /*! \page zaeroECS ZAero Executive Control Section
622 * The following lists the input for the Executive Control Section of the ZAero input file
623 */
624
625 int i, j, status;
626
627 int numSuports = 0;
628 int printFlag = 0, asetFlag = 0;
629 char *FEM = NULL((void*)0), *form = NULL((void*)0), *boundary=NULL((void*)0);
630 int *suports=NULL((void*)0);
631
632 feaSolFileStruct *f06 = NULL((void*)0);
633
634 if (assign_fem == NULL((void*)0)) return CAPS_NULLVALUE-307;
635
636 char relPath[PATH_MAX4096];
637
638 /*! \page zaeroECS
639 * \section zaeroASSIGNFEM FEM JSON String Dictionary
640 *
641 * FEM input must be a JSON string dictionary
642 * (e.g. {"boundary": "sym", "suport": [1,3], "print": 1}
643 * where the following keywords ( = default values) may be used:
644 */
645
646 for (i = 0; i < assign_fem->length; i++) {
647
648 /*! \page zaeroECS
649 *
650 * <ul>
651 * <li> <B>fem = "" </B> </li> <br>
652 * Optional Absolute file path to f06 file from a structural analysis. Cannot be specified
653 * if F06 is linked.
654 * </ul>
655 *
656 */
657 if (strcasecmp("fem", assign_fem->vals.tuple[i].name) == 0) {
658
659 if (f06Input->nullVal == NotNull) {
660 AIM_ERROR(aimInfo, "Both \"fem\" is in 'FEM_%d' input and 'F06_%d' cannot be specified", zaeroProblem->numFEMs+1, zaeroProblem->numFEMs+1){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 660, __func__
, "Both \"fem\" is in 'FEM_%d' input and 'F06_%d' cannot be specified"
, zaeroProblem->numFEMs+1, zaeroProblem->numFEMs+1); }
;
661 status = CAPS_BADVALUE-311;
662 goto cleanup;
663 }
664
665 FEM = string_removeQuotation(assign_fem->vals.tuple[i].value);
666
667 /*! \page zaeroECS
668 * <ul>
669 * <li> <B>form = "" </B> </li> <br>
670 * Optional string describing solver used to generate FEM file. If "fem" is specified then "form" must be one of: <br>
671 * 'MSC' generated by MSC.NASTRAN or NX.NASTRAN
672 * 'NE' generated by NE/NASTRAN
673 * 'ASTROS' generated by ASTROS
674 * 'IDEAS' generated by I-DEAS
675 * 'ELFINI' generated by ELFINI
676 * 'GENESIS' generated by GENESIS
677 * 'ABAQUS' generated by ABAQUS
678 * 'ALTAIR' generated by ALTAIR's RADIOSS
679 * 'FREE ' stored according to the input instruction described in Remark 9 of ZAero manual
680 * </ul>
681 */
682
683 for (j = 0; j < assign_fem->length; j++) {
684 if (strcasecmp("form", assign_fem->vals.tuple[j].name) == 0) {
685 form = string_removeQuotation(assign_fem->vals.tuple[i].value);
686 break;
687 }
688 }
689
690 if (form == NULL((void*)0)) {
691 AIM_ERROR(aimInfo, "Both \"fem\" and \"form\" must be specified", zaeroProblem->numFEMs+1, zaeroProblem->numFEMs+1){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 691, __func__
, "Both \"fem\" and \"form\" must be specified", zaeroProblem
->numFEMs+1, zaeroProblem->numFEMs+1); }
;
692 status = CAPS_BADVALUE-311;
693 goto cleanup;
694 }
695 }
696
697 /*! \page zaeroECS
698 *
699 * <ul>
700 * <li> <B>boundary = "SYM" </B> </li> <br>
701 * "boundary" indicates the boundary condition of the structural finite element model.<br>
702 * 'SYM' for symmetric boundary condition <br>
703 * 'ANTI' for anti-symmetric boundary condition <br>
704 * 'ASYM' for asymmetric boundary condition <br>
705 * </ul>
706 *
707 */
708 else if (strcasecmp("boundary", assign_fem->vals.tuple[i].name) == 0) {
709 boundary = string_removeQuotation(assign_fem->vals.tuple[i].value);
710 }
711
712 /*! \page zaeroECS
713 *
714 * <ul>
715 * <li> <B>support = [0, 0] </B> </li> <br>
716 * "support" up to length 2 array for the m/L ZAero support input. See ZAero manual for details.
717 * </ul>
718 *
719 */
720 else if (strcasecmp("suport", assign_fem->vals.tuple[i].name) == 0) {
721 status = string_toIntegerDynamicArray(assign_fem->vals.tuple[i].value, &numSuports, &suports);
722 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 722
, __func__, 0); goto cleanup; }
;
723 if (numSuports > 2) {
724 AIM_ERROR(aimInfo, "Only 2 suport numbers may be specified: numSuport = %d", numSuports){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 724, __func__
, "Only 2 suport numbers may be specified: numSuport = %d", numSuports
); }
;
725 status = CAPS_BADVALUE-311;
726 goto cleanup;
727 }
728 }
729
730 /*! \page zaeroECS
731 *
732 * <ul>
733 * <li> <B>print = 0 </B> </li> <br>
734 * Print options to the standard output file; where n is an integer. <br>
735 * n = 0 \t no printout of the imported structural free vibration solution. <br>
736 * | n | >= 1 \t print out the structural grid point locations in the aerodynamic coordinate system. <br>
737 * n >= 2 \t print out the modal data (mode shapes) at the structural grid points in the aerodynamic coordinate system. <br>
738 * n <= -2 \t print out the interpolated modal data at the control points of the aerodynamic boxes in the aerodynamic coordinate system. <br>
739 * n = 3 \t print all of the above
740 * </ul>
741 *
742 */
743 else if (strcasecmp("suport", assign_fem->vals.tuple[i].name) == 0) {
744 status = string_toInteger(assign_fem->vals.tuple[i].value, &printFlag);
745 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 745
, __func__, 0); goto cleanup; }
;
746 }
747
748 /*! \page zaeroECS
749 *
750 * <ul>
751 * <li> <B>print = 0 </B> </li> <br>
752 * Print options to the standard output file; where n is an integer. <br>
753 * n = 0 \t no printout of the imported structural free vibration solution. <br>
754 * | n | >= 1 \t print out the structural grid point locations in the aerodynamic coordinate system. <br>
755 * n >= 2 \t print out the modal data (mode shapes) at the structural grid points in the aerodynamic coordinate system. <br>
756 * n <= -2 \t print out the interpolated modal data at the control points of the aerodynamic boxes in the aerodynamic coordinate system. <br>
757 * n = 3 \t print all of the above
758 * </ul>
759 *
760 */
761 else if (strcasecmp("aset", assign_fem->vals.tuple[i].name) == 0) {
762 status = string_toInteger(assign_fem->vals.tuple[i].value, &asetFlag);
763 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 763
, __func__, 0); goto cleanup; }
;
764 }
765 }
766
767
768 if (f06Input->nullVal == NotNull && FEM == NULL((void*)0)) {
769
770 f06 = (feaSolFileStruct*) f06Input->vals.AIMptr;
771
772 status = aim_relPath(aimInfo, f06->filename, ".", relPath);
773 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 773
, __func__, 0); goto cleanup; }
;
774
775 AIM_STRDUP(FEM, relPath, aimInfo, status){ if (FEM != ((void*)0)) { status = -4; aim_status(aimInfo, status
, "zaeroAIM.c", 775, __func__, 1, "AIM_STRDUP: %s != NULL!", "FEM"
); goto cleanup; } FEM = EG_strdup(relPath); if (FEM == ((void
*)0)) { status = -4; aim_status(aimInfo, status, "zaeroAIM.c"
, 775, __func__, 2, "AIM_STRDUP: %s %s", "FEM", relPath); goto
cleanup; } }
;
776
777 switch (f06->fileForm) {
778 case MSC_NASTRAN:
779 AIM_STRDUP(form, "MSC", aimInfo, status){ if (form != ((void*)0)) { status = -4; aim_status(aimInfo, status
, "zaeroAIM.c", 779, __func__, 1, "AIM_STRDUP: %s != NULL!", "form"
); goto cleanup; } form = EG_strdup("MSC"); if (form == ((void
*)0)) { status = -4; aim_status(aimInfo, status, "zaeroAIM.c"
, 779, __func__, 2, "AIM_STRDUP: %s %s", "form", "MSC"); goto
cleanup; } }
;
780 break;
781 case NE_NASTRAN:
782 AIM_STRDUP(form, "NE", aimInfo, status){ if (form != ((void*)0)) { status = -4; aim_status(aimInfo, status
, "zaeroAIM.c", 782, __func__, 1, "AIM_STRDUP: %s != NULL!", "form"
); goto cleanup; } form = EG_strdup("NE"); if (form == ((void
*)0)) { status = -4; aim_status(aimInfo, status, "zaeroAIM.c"
, 782, __func__, 2, "AIM_STRDUP: %s %s", "form", "NE"); goto cleanup
; } }
;
783 break;
784 case ASTROS:
785 AIM_STRDUP(form, "ASTROS", aimInfo, status){ if (form != ((void*)0)) { status = -4; aim_status(aimInfo, status
, "zaeroAIM.c", 785, __func__, 1, "AIM_STRDUP: %s != NULL!", "form"
); goto cleanup; } form = EG_strdup("ASTROS"); if (form == ((
void*)0)) { status = -4; aim_status(aimInfo, status, "zaeroAIM.c"
, 785, __func__, 2, "AIM_STRDUP: %s %s", "form", "ASTROS"); goto
cleanup; } }
;
786 break;
787 case ABAQUS:
788 AIM_STRDUP(form, "ABAQUS", aimInfo, status){ if (form != ((void*)0)) { status = -4; aim_status(aimInfo, status
, "zaeroAIM.c", 788, __func__, 1, "AIM_STRDUP: %s != NULL!", "form"
); goto cleanup; } form = EG_strdup("ABAQUS"); if (form == ((
void*)0)) { status = -4; aim_status(aimInfo, status, "zaeroAIM.c"
, 788, __func__, 2, "AIM_STRDUP: %s %s", "form", "ABAQUS"); goto
cleanup; } }
;
789 break;
790 default:
791 AIM_ERROR(aimInfo, "Developer Error: Unknown fea solution file format %d", f06->fileForm){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 791, __func__
, "Developer Error: Unknown fea solution file format %d", f06
->fileForm); }
;
792 status = CAPS_NOTIMPLEMENT-334;
793 goto cleanup;
794 }
795 }
796
797 if (FEM == NULL((void*)0)) {
798 AIM_ERROR(aimInfo, "\"fem\" missing 'FEM_%d' input and 'F06_%d' is not linked", zaeroProblem->numFEMs+1, zaeroProblem->numFEMs+1){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 798, __func__
, "\"fem\" missing 'FEM_%d' input and 'F06_%d' is not linked"
, zaeroProblem->numFEMs+1, zaeroProblem->numFEMs+1); }
;
799 status = CAPS_BADVALUE-311;
800 goto cleanup;
801 }
802
803 if (boundary == NULL((void*)0)) {
804 AIM_STRDUP(boundary, "SYM", aimInfo, status){ if (boundary != ((void*)0)) { status = -4; aim_status(aimInfo
, status, "zaeroAIM.c", 804, __func__, 1, "AIM_STRDUP: %s != NULL!"
, "boundary"); goto cleanup; } boundary = EG_strdup("SYM"); if
(boundary == ((void*)0)) { status = -4; aim_status(aimInfo, status
, "zaeroAIM.c", 804, __func__, 2, "AIM_STRDUP: %s %s", "boundary"
, "SYM"); goto cleanup; } }
;
805 }
806
807 i = zaeroProblem->numFEMs;
808 zaeroProblem->FEMs[i].filename = FEM; FEM = NULL((void*)0);
809 zaeroProblem->FEMs[i].form = form; form = NULL((void*)0);
810 zaeroProblem->FEMs[i].boundary = boundary; boundary = NULL((void*)0);
811 for (j = 0; j < numSuports; j++)
812 zaeroProblem->FEMs[i].suport[j] = suports[j];
813 zaeroProblem->FEMs[i].printFlag = printFlag;
814 zaeroProblem->FEMs[i].asetFlag = asetFlag;
815 zaeroProblem->numFEMs++;
816
817 status = CAPS_SUCCESS0;
Value stored to 'status' is never read
818cleanup:
819 AIM_FREE(FEM){ EG_free(FEM); FEM = ((void*)0); };
820 AIM_FREE(form){ EG_free(form); form = ((void*)0); };
821 AIM_FREE(boundary){ EG_free(boundary); boundary = ((void*)0); };
822 AIM_FREE(suports){ EG_free(suports); suports = ((void*)0); };
823
824 return CAPS_SUCCESS0;
825}
826
827
828/* Get HFG module information from input */
829static int
830_getHFGModule(void *aimInfo,
831 capsValue *hfgInput,
832 zaeroProblemStruct *zaeroProblem)
833{
834
835 int i, status = CAPS_SUCCESS0; // Function return
836
837 if (hfgInput == NULL((void*)0)) return CAPS_NULLVALUE-307;
838
839 for (i = 0; i < hfgInput->length; i++) {
840
841 if (strcasecmp("XZSymmetric", hfgInput->vals.tuple[i].name) == 0) {
842 zaeroProblem->hfg.XZSymmetry = string_removeQuotation(hfgInput->vals.tuple[i].value);
843 string_toUpperCase(zaeroProblem->hfg.XZSymmetry);
844 }
845
846 else if (strcasecmp("flip", hfgInput->vals.tuple[i].name) == 0) {
847 zaeroProblem->hfg.flip = string_removeQuotation(hfgInput->vals.tuple[i].value);
848 string_toUpperCase(zaeroProblem->hfg.flip);
849 }
850 }
851
852 if (zaeroProblem->hfg.XZSymmetry == NULL((void*)0))
853 AIM_STRDUP(zaeroProblem->hfg.XZSymmetry, "YES", aimInfo, status){ if (zaeroProblem->hfg.XZSymmetry != ((void*)0)) { status
= -4; aim_status(aimInfo, status, "zaeroAIM.c", 853, __func__
, 1, "AIM_STRDUP: %s != NULL!", "zaeroProblem->hfg.XZSymmetry"
); goto cleanup; } zaeroProblem->hfg.XZSymmetry = EG_strdup
("YES"); if (zaeroProblem->hfg.XZSymmetry == ((void*)0)) {
status = -4; aim_status(aimInfo, status, "zaeroAIM.c", 853, __func__
, 2, "AIM_STRDUP: %s %s", "zaeroProblem->hfg.XZSymmetry", "YES"
); goto cleanup; } }
;
854
855 if (zaeroProblem->hfg.flip == NULL((void*)0))
856 AIM_STRDUP(zaeroProblem->hfg.flip, "NO", aimInfo, status){ if (zaeroProblem->hfg.flip != ((void*)0)) { status = -4;
aim_status(aimInfo, status, "zaeroAIM.c", 856, __func__, 1, "AIM_STRDUP: %s != NULL!"
, "zaeroProblem->hfg.flip"); goto cleanup; } zaeroProblem->
hfg.flip = EG_strdup("NO"); if (zaeroProblem->hfg.flip == (
(void*)0)) { status = -4; aim_status(aimInfo, status, "zaeroAIM.c"
, 856, __func__, 2, "AIM_STRDUP: %s %s", "zaeroProblem->hfg.flip"
, "NO"); goto cleanup; } }
;
857
858 status = CAPS_SUCCESS0;
859cleanup:
860 return status;
861}
862
863
864/* Get UAIC Module configurations from inputs */
865static int
866_getUAICModuleConfigs(void *aimInfo,
867 int numUAICTuple,
868 capsTuple UAICTuple[],
869 zaeroProblemStruct *zaeroProblem) {
870
871 /*! \page zaeroUAIC ZAero Unified Aerodynamic Influence Coefficients
872 * Structure for the UAIC tuple = ("UAIC Name", "Value").
873 * "UAIC Name" defines the reference name for the UAIC being specified.
874 * The "Value" must be a JSON String dictionary.
875 */
876
877 int i, status;
878
879 zaeroUAICStruct *uaic;
880
881 // Ensure we are starting with no subcases
882 if (zaeroProblem->UAICs != NULL((void*)0)) {
883 for (i = 0; i < zaeroProblem->numUAICs; i++) {
884 status = destroy_zaeroUAICStruct(&zaeroProblem->UAICs[i]);
885 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 885
, __func__, 0); goto cleanup; }
;
886 }
887 AIM_FREE(zaeroProblem->UAICs){ EG_free(zaeroProblem->UAICs); zaeroProblem->UAICs = (
(void*)0); }
;
888 }
889 zaeroProblem->numUAICs = 0;
890
891 printf("\nGetting ZAERO UAIC Configurations.......\n");
892
893 zaeroProblem->numUAICs = numUAICTuple;
894 printf("\tNumber of UAIC Configurations - %d\n", zaeroProblem->numUAICs);
895
896 if (zaeroProblem->numUAICs > 0) {
897
898 AIM_ALLOC(zaeroProblem->UAICs, zaeroProblem->numUAICs, zaeroUAICStruct, aimInfo, status){ if (zaeroProblem->UAICs != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "zaeroAIM.c", 898, __func__, 1, "AIM_ALLOC: %s != NULL"
, "zaeroProblem->UAICs"); goto cleanup; } size_t memorysize
= zaeroProblem->numUAICs; zaeroProblem->UAICs = (zaeroUAICStruct
*) EG_alloc(memorysize*sizeof(zaeroUAICStruct)); if (zaeroProblem
->UAICs == ((void*)0)) { status = -4; aim_status(aimInfo, status
, "zaeroAIM.c", 898, __func__, 3, "AIM_ALLOC: %s size %zu type %s"
, "zaeroProblem->UAICs", memorysize, "zaeroUAICStruct"); goto
cleanup; } }
;
899
900 // initiate UAIC structure
901 for (i = 0; i < zaeroProblem->numUAICs; i++) {
902 status = initiate_zaeroUAICStruct(&zaeroProblem->UAICs[i]);
903 AIM_STATUS(aimInfo,status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 903
, __func__, 0); goto cleanup; }
;
904 }
905
906 } else {
907 printf("\tNumber of analysis UAICs in Analysis tuple is %d\n",
908 zaeroProblem->numUAICs);
909 return CAPS_NOTFOUND-303;
910 }
911
912 // for each analysis UAIC tuple
913 for (i = 0; i < zaeroProblem->numUAICs; i++) {
914
915 uaic = &zaeroProblem->UAICs[i];
916
917 // set name
918 AIM_STRDUP(uaic->name, UAICTuple[i].name, aimInfo, status){ if (uaic->name != ((void*)0)) { status = -4; aim_status(
aimInfo, status, "zaeroAIM.c", 918, __func__, 1, "AIM_STRDUP: %s != NULL!"
, "uaic->name"); goto cleanup; } uaic->name = EG_strdup
(UAICTuple[i].name); if (uaic->name == ((void*)0)) { status
= -4; aim_status(aimInfo, status, "zaeroAIM.c", 918, __func__
, 2, "AIM_STRDUP: %s %s", "uaic->name", UAICTuple[i].name)
; goto cleanup; } }
;
919
920 // make sure UAIC tuple value is json string
921 if (!json_isDict(UAICTuple[i].value)) {
922 AIM_ERROR(aimInfo, "'UAIC' input must be a JSON dictionary"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 922, __func__
, "'UAIC' input must be a JSON dictionary"); }
;
923 return CAPS_BADVALUE-311;
924 }
925
926 // set UAIC ID
927 uaic->id = i+1;
928
929 // create the filename for the UAIC
930 snprintf(uaic->aicFilename, sizeof(uaic->aicFilename), "UAIC%d", uaic->id);
931
932 /*! \page zaeroUAIC
933 * \section jsonUAIC UAIC JSON String Dictionary
934 *
935 * For the JSON string "Value" dictionary
936 * (e.g. "Value" = {"machNumber": 0.5, "method": 120000.0, "poissonRatio": 0.5, "materialType": "isotropic"})
937 * \endif
938 * the following keywords ( = default values) may be used:
939 *
940 * <ul>
941 * <li> <B>machNumber</B> </li> <br>
942 * Mach number.
943 * </ul>
944 */
945
946 status = json_getDouble(UAICTuple[i].value, "machNumber", &uaic->machNumber);
947 if (status != CAPS_SUCCESS0) {
948 AIM_ERROR(aimInfo, "missing required entry \"machNumber\" in 'UAIC' input"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 948, __func__
, "missing required entry \"machNumber\" in 'UAIC' input"); }
;
949 status = CAPS_BADVALUE-311;
950 goto cleanup;
951 }
952
953 /*! \page zaeroUAIC
954 * <ul>
955 * <li> <B>method</B> </li> <br>
956 * Integer aerodynamic method <br>
957 * method = 0 for the ZONA6/ZONA7/ZSAP method <br>
958 * method = 1 for the ZTAIC method <br>
959 * method = +/- 2 for the ZONA7U method <br>
960 * method = 3 for the ZTRAN method <br>
961 * </ul>
962 */
963
964 status = json_getInteger(UAICTuple[i].value, "method", &uaic->methodFlag);
965 if (status != CAPS_SUCCESS0) {
966 AIM_ERROR(aimInfo, "missing required entry \"method\" in 'UAIC' input"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 966, __func__
, "missing required entry \"method\" in 'UAIC' input"); }
;
967 status = CAPS_BADVALUE-311;
968 goto cleanup;
969 }
970
971 /*! \page zaeroUAIC
972 * <ul>
973 * <li> <B>reducedFreq</B> </li> <br>
974 * List of real reduced frequencies
975 * </ul>
976 */
977 status = json_getDoubleDynamicArray(UAICTuple[i].value, "reducedFreq",
978 &uaic->numReducedFreq, &uaic->reducedFreq);
979 if (status != CAPS_SUCCESS0) {
980 AIM_ERROR(aimInfo, "missing required entry \"reducedFreq\" in 'UAIC' input"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 980, __func__
, "missing required entry \"reducedFreq\" in 'UAIC' input"); }
;
981 status = CAPS_BADVALUE-311;
982 goto cleanup;
983 }
984
985 /*! \page zaeroUAIC
986 * <ul>
987 * <li> <B>print = 0</B> </li> <br>
988 * Integer controlling print output
989 * </ul>
990 */
991 status = json_getInteger(UAICTuple[i].value, "print", &uaic->printFlag);
992 AIM_NOTFOUND(aimInfo,status)if (status != 0 && status != -303 && status !=
-1) { aim_status(aimInfo, status, "zaeroAIM.c", 992, __func__
, 0); goto cleanup; }
;
993
994 printf("\n\tUAIC Configuration: %s, id = %d\n", uaic->name, uaic->id);
995 printf("\t- Mach Number : %f\n", uaic->machNumber);
996 printf("\t- Reduced Freq: [");
997 if (uaic->numReducedFreq > 0)
998 printf("%f", uaic->reducedFreq[0]);
999 if (uaic->numReducedFreq > 1)
1000 printf(", ... , %f", uaic->reducedFreq[uaic->numReducedFreq-1]);
1001 printf("]\n");
1002
1003 }
1004
1005 status = CAPS_SUCCESS0;
1006
1007cleanup:
1008 return status;
1009}
1010
1011/* Get SPLINE module information from inputs */
1012static int
1013_getSplineModule(void *aimInfo, capsValue *splineInput, zaeroProblemStruct *zaeroProblem) {
1014
1015 /*! \page zaeroSpline ZAero Spline Module
1016 * Structure for the spline tuple is a tuple of key value pairs.
1017 *
1018 * The following keywords ( = default values) may be used:
1019 */
1020
1021 int i, status = CAPS_SUCCESS0; // Function return
1022
1023 if (splineInput == NULL((void*)0)) return CAPS_NULLVALUE-307;
1024 if (splineInput->nullVal == IsNull) return CAPS_SUCCESS0;
1025
1026 // Set default values
1027 zaeroProblem->spline.method = 1;
1028 zaeroProblem->spline.attachFlex = 0.0;
1029 zaeroProblem->spline.eps = 1.0e-6;
1030
1031 for (i = 0; i < splineInput->length; i++) {
1032
1033 /*! \page zaeroSpline
1034 * <ul>
1035 * <li> <B>method = 1</B> </li> <br>
1036 * 0 : Imposes zero-displacement condition on aerodynamic boxes.
1037 * 1 : Defines a surface spline method (Infinite Plate Spline method) for CAERO7.
1038 * 2 : Defines a beam spline method for CAERO7 / BODY7.
1039 * 3 : Defines a 3-D spline (Thin Plate Spline method) for CAERO7 / BODY7.
1040 * </ul>
1041 */
1042
1043 if (strcasecmp("method", splineInput->vals.tuple[i].name)) {
1044 status = string_toInteger(splineInput->vals.tuple[i].value, &zaeroProblem->spline.method);
1045 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1045
, __func__, 0); goto cleanup; }
;
1046 }
1047
1048 /*! \page zaeroSpline
1049 * <ul>
1050 * <li> <B>attachFlex = 0 </B> </li> <br>
1051 * Linear attachment flexibility (for spline method 1)
1052 * </ul>
1053 */
1054
1055 else if (strcasecmp("attachFlex", splineInput->vals.tuple[i].name)) {
1056 status = string_toDouble(splineInput->vals.tuple[i].value, &zaeroProblem->spline.attachFlex);
1057 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1057
, __func__, 0); goto cleanup; }
;
1058 }
1059
1060 /*! \page zaeroSpline
1061 * <ul>
1062 * <li> <B>eps = 1e-6 </B> </li> <br>
1063 * Multiplication factor to obtain a small tolerance to detect any duplicated location of
1064 * structural grid points. The tolerance is computed by EPS×REFC, where REFC is the
1065 * reference chord defined in the AEROZ bulk data card (for spline method 1 or 3)
1066 * </ul>
1067 */
1068
1069 else if (strcasecmp("eps", splineInput->vals.tuple[i].name)) {
1070 status = string_toDouble(splineInput->vals.tuple[i].value, &zaeroProblem->spline.eps);
1071 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1071
, __func__, 0); goto cleanup; }
;
1072 }
1073 }
1074
1075 status = CAPS_SUCCESS0;
1076cleanup:
1077 return status;
1078}
1079
1080static int
1081_getDisciplineType(void *aimInfo,
1082 const char *disciplineStr,
1083 zaeroDisciplineTypeEnum *disciplineType) {
1084
1085 if (
1086 (strcasecmp(disciplineStr, "LinearFlutter") == 0) ||
1087 (strcasecmp(disciplineStr, "Flutter") == 0)) {
1088 *disciplineType = LinearFlutter;
1089 } else if (
1090 (strcasecmp(disciplineStr, "ParamFlutter") == 0) ||
1091 (strcasecmp(disciplineStr, "fltpram") == 0)) {
1092 *disciplineType = ParamFlutter;
1093 } else if (
1094 (strcasecmp(disciplineStr, "Aeroservoelastic") == 0) ||
1095 (strcasecmp(disciplineStr, "ase") == 0)) {
1096 *disciplineType = Aeroservoelastic;
1097 } else if (
1098 (strcasecmp(disciplineStr, "StaticAeroelastic") == 0) ||
1099 (strcasecmp(disciplineStr, "Trim") == 0)) {
1100 *disciplineType = StaticAeroelastic;
1101 } else if (
1102 (strcasecmp(disciplineStr, "EjectionLoads") == 0) ||
1103 (strcasecmp(disciplineStr, "eloads") == 0)) {
1104 *disciplineType = EjectionLoads;
1105 } else if (
1106 (strcasecmp(disciplineStr, "ManeuverLoads") == 0) ||
1107 (strcasecmp(disciplineStr, "mloads") == 0)) {
1108 *disciplineType = ManeuverLoads;
1109 } else if (
1110 (strcasecmp(disciplineStr, "GustLoads") == 0) ||
1111 (strcasecmp(disciplineStr, "gloads") == 0)) {
1112 *disciplineType = GustLoads;
1113 } else if (
1114 (strcasecmp(disciplineStr, "MFTGustLoads") == 0) ||
1115 (strcasecmp(disciplineStr, "mftgust") == 0)) {
1116 *disciplineType = MFTGustLoads;
1117 } else if (
1118 (strcasecmp(disciplineStr, "NonLinearFlutter") == 0) ||
1119 (strcasecmp(disciplineStr, "nlfltr") == 0)) {
1120 *disciplineType = NonLinearFlutter;
1121 } else {
1122 *disciplineType = UnknownDiscipline;
1123 AIM_ERROR(aimInfo, "Unknown discipline: %s", disciplineStr){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 1123, __func__
, "Unknown discipline: %s", disciplineStr); }
;
1124 return CAPS_BADVALUE-311;
1125 }
1126
1127 return CAPS_SUCCESS0;
1128}
1129
1130/* Get analysis subcase information from inputs */
1131static int
1132_getAnalysisSubcases(void *aimInfo,
1133 const cfdUnitsStruct* units,
1134 int numAnalysisTuple,
1135 capsTuple analysisTuple[],
1136 zaeroProblemStruct *zaeroProblem) {
1137
1138 /*! \page zaeroAnalysis ZAero Analysis
1139 * Structure for the Analysis tuple = ("Case Name", "Value").
1140 * "Case Name" defines the reference name for the subcase being specified.
1141 * The "Value" must be a JSON String dictionary.
1142 */
1143
1144 int i, status;
1145 int maxchar = 72; // case control strings can be at most 72 chars
1146 char *disciplineStr = NULL((void*)0);
1147
1148 zaeroSubcaseStruct *subcase;
1149
1150 // Ensure we are starting with no subcases
1151 if (zaeroProblem->subcases != NULL((void*)0)) {
1152 for (i = 0; i < zaeroProblem->numSubcases; i++) {
1153 status = destroy_zaeroSubcaseStruct(&zaeroProblem->subcases[i]);
1154 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1154
, __func__, 0); goto cleanup; }
;
1155 }
1156 }
1157 AIM_FREE(zaeroProblem->subcases){ EG_free(zaeroProblem->subcases); zaeroProblem->subcases
= ((void*)0); }
;
1158 zaeroProblem->numSubcases = 0;
1159
1160 printf("\nGetting ZAERO Analysis Subcases.......\n");
1161
1162 zaeroProblem->numSubcases = numAnalysisTuple;
1163 printf("\tNumber of Analysis Subcases - %d\n", zaeroProblem->numSubcases);
1164
1165 if (zaeroProblem->numSubcases > 0) {
1166 AIM_ALLOC(zaeroProblem->subcases, zaeroProblem->numSubcases, zaeroSubcaseStruct, aimInfo, status){ if (zaeroProblem->subcases != ((void*)0)) { status = -4;
aim_status(aimInfo, status, "zaeroAIM.c", 1166, __func__, 1,
"AIM_ALLOC: %s != NULL", "zaeroProblem->subcases"); goto cleanup
; } size_t memorysize = zaeroProblem->numSubcases; zaeroProblem
->subcases = (zaeroSubcaseStruct *) EG_alloc(memorysize*sizeof
(zaeroSubcaseStruct)); if (zaeroProblem->subcases == ((void
*)0)) { status = -4; aim_status(aimInfo, status, "zaeroAIM.c"
, 1166, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "zaeroProblem->subcases"
, memorysize, "zaeroSubcaseStruct"); goto cleanup; } }
;
1167
1168 // initiate subcase structure
1169 for (i = 0; i < zaeroProblem->numSubcases; i++) {
1170 status = initiate_zaeroSubcaseStruct(&zaeroProblem->subcases[i]);
1171 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1171
, __func__, 0); goto cleanup; }
;
1172 }
1173 } else {
1174 AIM_ERROR(aimInfo, "Number of analysis subcases in 'Analysis' tuple is %d", zaeroProblem->numSubcases){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 1174, __func__
, "Number of analysis subcases in 'Analysis' tuple is %d", zaeroProblem
->numSubcases); }
;
1175 return CAPS_NOTFOUND-303;
1176 }
1177
1178 // for each analysis subcase tuple
1179 for (i = 0; i < zaeroProblem->numSubcases; i++) {
1180
1181 subcase = &zaeroProblem->subcases[i];
1182
1183 // set name
1184 subcase->name = EG_strdup(analysisTuple[i].name);
1185
1186 // make sure analysis tuple value is json string
1187 if (!json_isDict(analysisTuple[i].value)) {
1188 AIM_ERROR(aimInfo, "'Analysis' tuple value must be a JSON dictionary"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 1188, __func__
, "'Analysis' tuple value must be a JSON dictionary"); }
;
1189 return CAPS_BADVALUE-311;
1190 }
1191
1192 // set subcase ID
1193 subcase->subcaseID = i+1;
1194
1195 // set subcase analysis ID (at the moment
1196 // TODO: is there a better way to determine analysisID?
1197 subcase->analysisID = subcase->subcaseID * 100;
1198
1199 /*! \page zaeroAnalysis
1200 * \section jsonSubcase Analysis JSON String Dictionary
1201 *
1202 * For the JSON string "Value" dictionary
1203 * (e.g. "Value" = {"discipline": "LinearFlutter", "uaic": "cruise"})
1204 * \endif
1205 * the following keywords ( = default values) may be used:
1206 *
1207 * <ul>
1208 * <li> <B>discipline = ""</B> </li> <br>
1209 * Analysis discipline JSON string. Options : <br>
1210 * LinearFlutter or flutter - Linear flutter<br>
1211 * ParamFlutter or fltpram - Parametric flutter.<br>
1212 * Aeroservoelastic or ase - Asymmetric parametric flutter.<br>
1213 * StaticAeroelastic or trim - Static areoelastic (see \ref jsonTRIM).<br>
1214 * EjectionLoads or eloads - Transient ejection loads.<br>
1215 * ManeuverLoads or mloads - Transient manouver loads.<br>
1216 * GustLoads or gloads - Discrete gust load.<br>
1217 * MFTGustLoads or mftgust - Continuous gust load.<br>
1218 * NonLinearFlutter or nlfltr - Nonlinear flutter.<br>
1219 * </ul>
1220 */
1221
1222 // setup discipline according to "discipline" value
1223 status = json_getString( analysisTuple[i].value, "discipline", &disciplineStr);
1224 if (status != CAPS_SUCCESS0) {
1225 AIM_ERROR(aimInfo, "input for %s analysis is missing required entry"{ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 1226, __func__
, "input for %s analysis is missing required entry" "\"discipline\""
, subcase->name); }
1226 "\"discipline\"", subcase->name){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 1226, __func__
, "input for %s analysis is missing required entry" "\"discipline\""
, subcase->name); }
;
1227 status = CAPS_BADVALUE-311;
1228 goto cleanup;
1229 }
1230
1231 status = _getDisciplineType(aimInfo, disciplineStr, &subcase->disciplineType);
1232 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1232
, __func__, 0); goto cleanup; }
;
1233
1234 switch (subcase->disciplineType) {
1235 case LinearFlutter:
1236 status = zaero_getLinearFlutterDiscipline(aimInfo, analysisTuple[i].value, subcase);
1237 break;
1238 case ParamFlutter:
1239 status = CAPS_NOTIMPLEMENT-334;
1240 break;
1241 case Aeroservoelastic:
1242 status = CAPS_NOTIMPLEMENT-334;
1243 break;
1244 case StaticAeroelastic:
1245 status = zaero_getTrimDiscipline(aimInfo, analysisTuple[i].value, units, subcase);
1246 break;
1247 case ManeuverLoads:
1248 status = CAPS_NOTIMPLEMENT-334;
1249 break;
1250 case EjectionLoads:
1251 status = CAPS_NOTIMPLEMENT-334;
1252 break;
1253 case GustLoads:
1254 status = CAPS_NOTIMPLEMENT-334;
1255 break;
1256 case MFTGustLoads:
1257 status = CAPS_NOTIMPLEMENT-334;
1258 break;
1259 case NonLinearFlutter:
1260 status = CAPS_NOTIMPLEMENT-334;
1261 break;
1262 // should not be unknown at this point, including to avoid switch warning
1263 case UnknownDiscipline:
1264 break;
1265 status = CAPS_BADVALUE-311;
1266 }
1267 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1267
, __func__, 0); goto cleanup; }
;
1268
1269 /*! \page zaeroAnalysis
1270 * <ul>
1271 * <li> <B>uaic = ""</B> </li> <br>
1272 * Name of the UAIC module for the subcase
1273 * </ul>
1274 */
1275
1276 status = json_getString(analysisTuple[i].value, "uaic", &subcase->uaicName);
1277 if (status != CAPS_SUCCESS0) {
1278 AIM_ERROR(aimInfo, "Subcase '%s' is missing required \"uaic\"", subcase->name){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 1278, __func__
, "Subcase '%s' is missing required \"uaic\"", subcase->name
); }
;
1279 return status;
1280 }
1281
1282 AIM_ALLOC(subcase->subtitle, maxchar + 1, char, aimInfo, status){ if (subcase->subtitle != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "zaeroAIM.c", 1282, __func__, 1, "AIM_ALLOC: %s != NULL"
, "subcase->subtitle"); goto cleanup; } size_t memorysize =
maxchar + 1; subcase->subtitle = (char *) EG_alloc(memorysize
*sizeof(char)); if (subcase->subtitle == ((void*)0)) { status
= -4; aim_status(aimInfo, status, "zaeroAIM.c", 1282, __func__
, 3, "AIM_ALLOC: %s size %zu type %s", "subcase->subtitle"
, memorysize, "char"); goto cleanup; } }
;
1283 snprintf(subcase->subtitle, maxchar, "%s Analysis, using %s",
1284 disciplineStr, subcase->uaicName);
1285
1286 status = json_getString(analysisTuple[i].value, "label", &subcase->label);
1287 AIM_NOTFOUND(aimInfo, status)if (status != 0 && status != -303 && status !=
-1) { aim_status(aimInfo, status, "zaeroAIM.c", 1287, __func__
, 0); goto cleanup; }
;
1288
1289 printf("\n\tAnalysis Subcase: %s, id = %d\n",
1290 subcase->name, subcase->subcaseID);
1291 printf("\t- Discipline : %s\n", disciplineStr);
1292 printf("\t- UAIC : %s\n", subcase->uaicName);
1293 }
1294
1295 status = CAPS_SUCCESS0;
1296cleanup:
1297 return status;
1298}
1299
1300static void
1301_writeBanner(FILE *fp, char *msg) {
1302 fprintf(fp,
1303"$==============================================================================\n"
1304"$ %s\n"
1305"$==============================================================================\n",
1306 msg);
1307}
1308
1309static void
1310_writeCaseBanner(FILE *fp, char *msg) {
1311 fprintf(fp,
1312"$------------------------------------------------------------------------------\n"
1313"$ %s\n"
1314"$------------------------------------------------------------------------------\n",
1315 msg);
1316}
1317
1318/* Populate zaero problem struct with input information*/
1319static int
1320_getZaeroProblemData(void *aimInfo,
1321 capsValue *aimInputs,
1322 aimStorage *zaeroInstance) {
1323
1324 int status = CAPS_SUCCESS0;
1325
1326 capsValue *hfgInput, *uaicInput, *splineInput;
1327 capsValue *analysisInput, *trimVarInput;
1328
1329 const cfdUnitsStruct *units = &zaeroInstance->units;
1330 zaeroProblemStruct *zaeroProblem = &zaeroInstance->zaeroProblem;
1331
1332 hfgInput = &aimInputs[inHFG-1];
1333 uaicInput = &aimInputs[inUAIC-1];
1334 splineInput = &aimInputs[inSpline-1];
1335 analysisInput = &aimInputs[inAnalysis-1];
1336 trimVarInput = &aimInputs[inTrim_Variable-1];
1337
1338 if (aimInputs[inFEM_1-1].nullVal == IsNull) {
1339 AIM_ERROR(aimInfo, "'FEM_1' input is required"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 1339, __func__
, "'FEM_1' input is required"); }
;
1340 return CAPS_BADVALUE-311;
1341 }
1342
1343 status = _getFEMModule(aimInfo, &aimInputs[inFEM_1-1], &aimInputs[inF06_1-1], zaeroProblem);
1344 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1344
, __func__, 0); goto cleanup; }
;
1345
1346 if (aimInputs[inFEM_2-1].nullVal == NotNull) {
1347 status = _getFEMModule(aimInfo, &aimInputs[inFEM_2-1], &aimInputs[inF06_2-1], zaeroProblem);
1348 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1348
, __func__, 0); goto cleanup; }
;
1349 }
1350
1351 status = _getHFGModule(aimInfo, hfgInput, zaeroProblem);
1352 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1352
, __func__, 0); goto cleanup; }
;
1353
1354 if (uaicInput->nullVal == NotNull) {
1355 status = _getUAICModuleConfigs(aimInfo,
1356 uaicInput->length,
1357 uaicInput->vals.tuple,
1358 zaeroProblem);
1359 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1359
, __func__, 0); goto cleanup; }
;
1360 } else {
1361 printf("UAIC tuple is NULL - No UAIC configurations set");
1362 }
1363
1364 status = _getSplineModule(aimInfo, splineInput, zaeroProblem);
1365 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1365
, __func__, 0); goto cleanup; }
;
1366
1367 if (analysisInput->nullVal == NotNull) {
1368 status = _getAnalysisSubcases(aimInfo,
1369 units,
1370 analysisInput->length,
1371 analysisInput->vals.tuple,
1372 zaeroProblem);
1373 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1373
, __func__, 0); goto cleanup; }
;
1374 } else {
1375 printf("Analysis tuple is NULL - No analysis subcase set");
1376 }
1377
1378 if (trimVarInput->nullVal == NotNull) {
1379 status = zaero_getTrimVariables(aimInfo,
1380 trimVarInput->length,
1381 trimVarInput->vals.tuple,
1382 zaeroProblem);
1383 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1383
, __func__, 0); goto cleanup; }
;
1384 } else {
1385 printf("Trim_Variable tuple is NULL - No trim variables set\n");
1386 }
1387
1388 status = CAPS_SUCCESS0;
1389cleanup:
1390 return status;
1391}
1392
1393static int
1394_writeAssignFEM(void *aimInfo, FILE *fp, const zaeroFEMStruct *fem) {
1395
1396 int status = CAPS_SUCCESS0;
1397 char *tempString = NULL((void*)0);
1398
1399 // FEM filename
1400 fprintf(fp, "ASSIGN FEM = %s,\n", fem->filename);
1401
1402 // form, default is MSC
1403 if (fem->form == NULL((void*)0)) {
1404 AIM_STRDUP(tempString , "MSC", aimInfo, status){ if (tempString != ((void*)0)) { status = -4; aim_status(aimInfo
, status, "zaeroAIM.c", 1404, __func__, 1, "AIM_STRDUP: %s != NULL!"
, "tempString"); goto cleanup; } tempString = EG_strdup("MSC"
); if (tempString == ((void*)0)) { status = -4; aim_status(aimInfo
, status, "zaeroAIM.c", 1404, __func__, 2, "AIM_STRDUP: %s %s"
, "tempString", "MSC"); goto cleanup; } }
;
1405 }
1406 else {
1407 AIM_STRDUP(tempString, fem->form, aimInfo, status){ if (tempString != ((void*)0)) { status = -4; aim_status(aimInfo
, status, "zaeroAIM.c", 1407, __func__, 1, "AIM_STRDUP: %s != NULL!"
, "tempString"); goto cleanup; } tempString = EG_strdup(fem->
form); if (tempString == ((void*)0)) { status = -4; aim_status
(aimInfo, status, "zaeroAIM.c", 1407, __func__, 2, "AIM_STRDUP: %s %s"
, "tempString", fem->form); goto cleanup; } }
;
1408 string_toUpperCase(tempString);
1409 }
1410 fprintf(fp, "FORM = %s, ", tempString);
1411
1412 AIM_FREE(tempString){ EG_free(tempString); tempString = ((void*)0); };
1413
1414 // boundary condition, default is SYM
1415 if (fem->boundary == NULL((void*)0)) {
1416 AIM_STRDUP(tempString, "SYM", aimInfo, status){ if (tempString != ((void*)0)) { status = -4; aim_status(aimInfo
, status, "zaeroAIM.c", 1416, __func__, 1, "AIM_STRDUP: %s != NULL!"
, "tempString"); goto cleanup; } tempString = EG_strdup("SYM"
); if (tempString == ((void*)0)) { status = -4; aim_status(aimInfo
, status, "zaeroAIM.c", 1416, __func__, 2, "AIM_STRDUP: %s %s"
, "tempString", "SYM"); goto cleanup; } }
;
1417 }
1418 else {
1419 AIM_STRDUP(tempString, fem->boundary, aimInfo, status){ if (tempString != ((void*)0)) { status = -4; aim_status(aimInfo
, status, "zaeroAIM.c", 1419, __func__, 1, "AIM_STRDUP: %s != NULL!"
, "tempString"); goto cleanup; } tempString = EG_strdup(fem->
boundary); if (tempString == ((void*)0)) { status = -4; aim_status
(aimInfo, status, "zaeroAIM.c", 1419, __func__, 2, "AIM_STRDUP: %s %s"
, "tempString", fem->boundary); goto cleanup; } }
;
1420 string_toUpperCase(tempString);
1421 }
1422 fprintf(fp, "BOUNDARY = %s, ", tempString);
1423
1424 AIM_FREE(tempString){ EG_free(tempString); tempString = ((void*)0); };
1425
1426 // print
1427 fprintf(fp, "PRINT = %d, ", fem->printFlag);
1428
1429 // suport
1430 if (fem->suport[0] != 0 && fem->suport[1] != 0) {
1431 fprintf(fp, "SUPORT = %d/%d, ", fem->suport[0], fem->suport[1]);
1432 }
1433 else if (fem->suport[0] != 0) {
1434 fprintf(fp, "SUPORT = %d, ", fem->suport[0]);
1435 }
1436
1437 if (fem->asetFlag > 0) {
1438 fprintf(fp, "ASET = YES");
1439 }
1440 else {
1441 fprintf(fp, "ASET = NO");
1442 }
1443
1444 fprintf(fp, "\n");
1445
1446 status = CAPS_SUCCESS0;
1447cleanup:
1448 AIM_FREE(tempString){ EG_free(tempString); tempString = ((void*)0); };
1449 return status;
1450}
1451
1452/* Executive Control Section
1453 * From the manual:
1454 * """
1455 * The Executive Control Section must be located at the beginning of the input file.
1456 * Its major functions are:
1457 * * to define the filename that contains the free vibration output from the
1458 * structural finite element methods"
1459 * * to allow direct matrix input
1460 * * to turn on diagnostic routines
1461 * """
1462 */
1463static int
1464_writeExecutiveControlSection(void *aimInfo,
1465 FILE *fp,
1466 capsValue *aimInputs,
1467 const aimStorage *zaeroInstance) {
1468
1469 char *tempString = NULL((void*)0);
1470
1471 int i, tempInteger;
1472
1473 int status; // Function return
1474
1475 _writeBanner(fp, "Executive Control Section");
1476
1477 // ASSIGN FEM
1478 for (i = 0; i < zaeroInstance->zaeroProblem.numFEMs; i++) {
1479 status = _writeAssignFEM(aimInfo, fp, &zaeroInstance->zaeroProblem.FEMs[i]);
1480 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1480
, __func__, 0); goto cleanup; }
;
1481 }
1482
1483 // CPU
1484 tempInteger = aimInputs[inCPU-1].vals.integer;
1485 fprintf(fp, "CPU %d\n", tempInteger);
1486
1487 // MEMORY
1488 tempString = aimInputs[inMemory-1].vals.string;
1489 fprintf(fp, "MEMORY %s\n", tempString);
1490
1491 // DOUBLE
1492 fprintf(fp, "DOUBLE\n");
1493
1494 // CEND
1495 fprintf(fp, "CEND\n");
1496
1497 status = CAPS_SUCCESS0;
1498
1499cleanup:
1500
1501 return status;
1502}
1503
1504// write analysis subcase in Case Control Section
1505static int
1506_writeCase(void *aimInfo, FILE *fp, zaeroSubcaseStruct *subcase) {
1507
1508 fprintf(fp, "SUBCASE = %d\n", subcase->subcaseID);
1509
1510 fprintf(fp, "SUBTITLE = %s\n", subcase->subtitle);
1511
1512 if (subcase->label != NULL((void*)0))
1513 fprintf(fp, "LABEL = %s\n", subcase->label);
1514
1515 if (subcase->disciplineType == LinearFlutter) {
1516 fprintf(fp, "FLUTTER = %d\n", subcase->analysisID);
1517 }
1518 else if (subcase->disciplineType == ParamFlutter) {
1519 AIM_ERROR(aimInfo, "ParamFlutter discipline not implemented"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 1519, __func__
, "ParamFlutter discipline not implemented"); }
;
1520 return CAPS_NOTIMPLEMENT-334;
1521 }
1522 else if (subcase->disciplineType == Aeroservoelastic) {
1523 AIM_ERROR(aimInfo, "Aeroservoelastic discipline not implemented"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 1523, __func__
, "Aeroservoelastic discipline not implemented"); }
;
1524 return CAPS_NOTIMPLEMENT-334;
1525 }
1526 else if (subcase->disciplineType == StaticAeroelastic) {
1527 fprintf(fp, "TRIM = %d\n", subcase->analysisID);
1528 }
1529 else if (subcase->disciplineType == ManeuverLoads) {
1530 AIM_ERROR(aimInfo, "ManeuverLoads discipline not implemented"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 1530, __func__
, "ManeuverLoads discipline not implemented"); }
;
1531 return CAPS_NOTIMPLEMENT-334;
1532 }
1533 else if (subcase->disciplineType == EjectionLoads) {
1534 AIM_ERROR(aimInfo, "EjectionLoads discipline not implemented"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 1534, __func__
, "EjectionLoads discipline not implemented"); }
;
1535 return CAPS_NOTIMPLEMENT-334;
1536 }
1537 else if (subcase->disciplineType == GustLoads) {
1538 AIM_ERROR(aimInfo, "GustLoads discipline not implemented"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 1538, __func__
, "GustLoads discipline not implemented"); }
;
1539 return CAPS_NOTIMPLEMENT-334;
1540 }
1541 else if (subcase->disciplineType == MFTGustLoads) {
1542 AIM_ERROR(aimInfo, "MFTGustLoads discipline not implemented"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 1542, __func__
, "MFTGustLoads discipline not implemented"); }
;
1543 return CAPS_NOTIMPLEMENT-334;
1544 }
1545 else if (subcase->disciplineType == NonLinearFlutter) {
1546 AIM_ERROR(aimInfo, "NonLinearFlutter discipline not implemented"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 1546, __func__
, "NonLinearFlutter discipline not implemented"); }
;
1547 return CAPS_NOTIMPLEMENT-334;
1548 }
1549 else {
1550 AIM_ERROR(aimInfo, "Unknown discipline"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 1550, __func__
, "Unknown discipline"); }
;
1551 return CAPS_BADVALUE-311;
1552 }
1553
1554 return CAPS_SUCCESS0;
1555}
1556
1557/* Case Control Section
1558 * From the manual:
1559 * """
1560 * The Case Control Section must be located after the Executive Control Section and
1561 * before the Bulk Data Section. Its major functions are:
1562 * * to input title cards that describe the ZAERO analysis
1563 * * to select the disciplines (FLUTTER, FLTPRAM, ASE, TRIM, MLOADS, ELOADS, GLOADS
1564 * or NLFLTR) for the analysis
1565 * """
1566 */
1567static int
1568_writeCaseControlSection(void *aimInfo,
1569 FILE *fp,
1570 capsValue *aimInputs,
1571 const aimStorage *zaeroInstance) {
1572 int status = CAPS_SUCCESS0;
1573
1574 char *tempString = NULL((void*)0);
1575
1576 _writeBanner(fp, "Case Control Section");
1577
1578 // TITLE
1579 tempString = aimInputs[inProj_Name-1].vals.string;
1580 fprintf(fp, "TITLE = %s\n", tempString);
1581
1582 // ECHO
1583 tempString = aimInputs[inEcho-1].vals.string;
1584 fprintf(fp, "ECHO = %s\n", tempString);
1585
1586 // write each analysis subcase
1587 for (int i = 0; i < zaeroInstance->zaeroProblem.numSubcases; i++) {
1588 status = _writeCase(aimInfo, fp, &zaeroInstance->zaeroProblem.subcases[i]);
1589 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1589
, __func__, 0); goto cleanup; }
;
1590 }
1591
1592cleanup:
1593 return status;
1594}
1595
1596/* Flight Condition Definition */
1597static int
1598_writeFlightConditionCards(void *aimInfo,
1599 FILE *fp,
1600 capsValue *aimInputs,
1601 const aimStorage *zaeroInstance) {
1602
1603 int status;
1604
1605 _writeCaseBanner(fp, "Flight Condition Definition");
1606 // printf("FLIGHT CONDITION DEFINITION\n");
1607
1608 status = zaero_modelPhysicalData( aimInfo,
1609 fp,
1610 &zaeroInstance->zaeroProblem.hfg,
1611 &zaeroInstance->units,
1612 zaeroInstance->feaFormatType);
1613 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1613
, __func__, 0); goto cleanup; }
;
1614
1615 // write cards for each UAIC configuration
1616 for (int i = 0; i < zaeroInstance->zaeroProblem.numUAICs; i++) {
1617
1618 status = zaero_unsteadyAerodynamicsGenerator(aimInfo,
1619 fp,
1620 &zaeroInstance->zaeroProblem.UAICs[i],
1621 zaeroInstance->feaFormatType);
1622 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1622
, __func__, 0); goto cleanup; }
;
1623
1624 }
1625
1626 status = CAPS_SUCCESS0;
1627cleanup:
1628 return status;
1629}
1630
1631/* Aerodynamic Model Definition */
1632static int
1633_writeAerodynamicModelCards(void *aimInfo,
1634 FILE *fp,
1635 capsValue *aimInputs,
1636 const aimStorage *zaeroInstance) {
1637 int status, i;
1638
1639 _writeCaseBanner(fp, "Aerodynamic Model Definition");
1640
1641 for (i = 0; i < zaeroInstance->zaeroProblem.numAero; i++) {
1642 status = zaero_aerodynamicWingComponent(aimInfo,
1643 fp,
1644 &zaeroInstance->zaeroProblem.feaAero[i],
1645 i,
1646 zaeroInstance->feaFormatType);
1647 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1647
, __func__, 0); goto cleanup; }
;
1648 }
1649
1650 status = CAPS_SUCCESS0;
1651cleanup:
1652 return status;
1653}
1654
1655/* Spline */
1656static int
1657_writeSplineCards(void *aimInfo,
1658 FILE *fp,
1659 capsValue *aimInputs,
1660 const aimStorage *zaeroInstance) {
1661 int status, i;
1662
1663 _writeCaseBanner(fp, "Spline Definition");
1664
1665 for (i = 0; i < zaeroInstance->zaeroProblem.numAero; i++) {
1666 status = zaero_splineMethod(aimInfo,
1667 fp,
1668 &zaeroInstance->zaeroProblem.feaAero[i],
1669 &zaeroInstance->zaeroProblem.spline,
1670 zaeroInstance->feaFormatType);
1671 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1671
, __func__, 0); goto cleanup; }
;
1672 }
1673
1674 status = CAPS_SUCCESS0;
1675cleanup:
1676 return status;
1677}
1678
1679/* Analysis Definition */
1680static int
1681_writeAnalysisCards(void *aimInfo,
1682 FILE *fp,
1683 capsValue *aimInputs,
1684 const aimStorage *zaeroInstance) {
1685
1686 int status;
1687
1688 zaeroSubcaseStruct *subcase = NULL((void*)0);
1689
1690 // write analysis cards for each subcase
1691 for (int i = 0; i < zaeroInstance->zaeroProblem.numSubcases; i++) {
1692
1693 subcase = &zaeroInstance->zaeroProblem.subcases[i];
1694
1695 if (subcase->disciplineType == LinearFlutter) {
1696
1697 _writeCaseBanner(fp, "Linear Flutter Analysis");
1698
1699 status = zaero_flutterAnalysis(aimInfo,
1700 fp,
1701 subcase,
1702 &zaeroInstance->zaeroProblem,
1703 &zaeroInstance->units,
1704 zaeroInstance->feaFormatType);
1705 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1705
, __func__, 0); goto cleanup; }
;
1706 }
1707 else if (subcase->disciplineType == StaticAeroelastic) {
1708
1709 _writeCaseBanner(fp, "Static Aeroelastic/Trim Analysis");
1710
1711 status = zaero_trimAnalysis(aimInfo,
1712 fp,
1713 subcase,
1714 &zaeroInstance->zaeroProblem,
1715 zaeroInstance->feaFormatType);
1716 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1716
, __func__, 0); goto cleanup; }
;
1717 }
1718 else {
1719 AIM_ERROR(aimInfo, "Unknown subcase disciplineType."){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 1719, __func__
, "Unknown subcase disciplineType."); }
;
1720 return CAPS_BADVALUE-311;
1721 }
1722 }
1723
1724 status = CAPS_SUCCESS0;
1725cleanup:
1726 return status;
1727}
1728
1729/* Output */
1730static int
1731_writeOutputCards(void *aimInfo,
1732 FILE *fp,
1733 const int numOutputTuple,
1734 const capsTuple outputTuple[],
1735 const aimStorage *zaeroInstance)
1736{
1737 int status, setID=9000;
1738
1739 for (int i = 0; i < numOutputTuple; i++) {
1740
1741 if (strcmp(outputTuple[i].name, "Aero") == 0) {
1742
1743 status = zaero_textFileGenerationAero(aimInfo,
1744 fp,
1745 outputTuple[i].value,
1746 &zaeroInstance->zaeroProblem,
1747 zaeroInstance->feaFormatType,
1748 &setID);
1749 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1749
, __func__, 0); goto cleanup; }
;
1750
1751 } else if (strcmp(outputTuple[i].name, "Flutter") == 0) {
1752
1753 status = zaero_textFileGenerationFlutter(aimInfo,
1754 fp,
1755 outputTuple[i].value,
1756 &zaeroInstance->zaeroProblem,
1757 zaeroInstance->feaFormatType,
1758 &setID);
1759 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1759
, __func__, 0); goto cleanup; }
;
1760
1761 } else if (strcmp(outputTuple[i].name, "Mode") == 0) {
1762
1763 status = zaero_textFileGenerationMode(aimInfo,
1764 fp,
1765 outputTuple[i].value,
1766 &zaeroInstance->zaeroProblem,
1767 zaeroInstance->feaFormatType,
1768 &setID);
1769 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1769
, __func__, 0); goto cleanup; }
;
1770
1771 } else if (strcmp(outputTuple[i].name, "Trim") == 0) {
1772
1773 status = zaero_textFileGenerationTrim(aimInfo,
1774 fp,
1775 outputTuple[i].value,
1776 &zaeroInstance->zaeroProblem,
1777 zaeroInstance->feaFormatType,
1778 &setID);
1779 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1779
, __func__, 0); goto cleanup; }
;
1780
1781 } else if (strcmp(outputTuple[i].name, "VG") == 0) {
1782
1783 status = zaero_textFileGenerationVG(aimInfo,
1784 fp,
1785 outputTuple[i].value,
1786 &zaeroInstance->zaeroProblem,
1787 zaeroInstance->feaFormatType,
1788 &setID);
1789 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1789
, __func__, 0); goto cleanup; }
;
1790 }
1791 }
1792
1793 status = CAPS_SUCCESS0;
1794cleanup:
1795 return status;
1796}
1797
1798static int
1799_writeOutputCardsIfRequested(void *aimInfo,
1800 FILE *fp,
1801 capsValue *aimInputs,
1802 const aimStorage *zaeroInstance) {
1803 int status;
1804
1805 capsValue *outputInput;
1806
1807 outputInput = &aimInputs[inOutput-1];
1808
1809 // if output generation requested
1810 if (outputInput->nullVal == NotNull) {
1811
1812 _writeBanner(fp, "OUTPUT");
1813
1814 status = _writeOutputCards(aimInfo,
1815 fp,
1816 outputInput->length,
1817 outputInput->vals.tuple,
1818 zaeroInstance);
1819 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1819
, __func__, 0); goto cleanup; }
;
1820
1821 } else {
1822 printf("No graphical outputs requested.\n");
1823 }
1824
1825 status = CAPS_SUCCESS0;
1826cleanup:
1827 return status;
1828}
1829
1830/* Bulk Data Section
1831 * From the manual:
1832 * """
1833 * The Bulk Data Section begins right after the BEGIN BULK Case Control Command and
1834 * ends at a bulk data card ENDDATA. The Bulk Data Section contains data cards that
1835 * specify:
1836 * * the geometry of the aerodynamic model
1837 * * spline for displacement and force transversal between the structural finite
1838 * element grid points and aerodynamic boxes
1839 * * the Mach numbers, natural frequencies and aerodynamic methods for unsteady
1840 * aerodynamic data generation
1841 * * disciplines (FLUTTER, ASE, FLTPRAM, static aerolastic/TRIM, MLOADS, ELOADS,
1842 * GLOADS, or NLFLTR) to be analyzed
1843 * * other miscellaneous inputs
1844 * """
1845*/
1846static int
1847_writeBulkDataSection(void *aimInfo,
1848 FILE *fp,
1849 capsValue *aimInputs,
1850 const aimStorage *zaeroInstance) {
1851
1852 int status;
1853
1854 _writeBanner(fp, "$ Begin Bulk Data Section");
1855
1856 fprintf(fp, "BEGIN BULK\n");
1857
1858 status = _writeFlightConditionCards(aimInfo, fp, aimInputs, zaeroInstance);
1859 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1859
, __func__, 0); goto cleanup; }
;
1860
1861 status = _writeAerodynamicModelCards(aimInfo, fp, aimInputs, zaeroInstance);
1862 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1862
, __func__, 0); goto cleanup; }
;
1863
1864 status = _writeSplineCards(aimInfo, fp, aimInputs, zaeroInstance);
1865 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1865
, __func__, 0); goto cleanup; }
;
1866
1867 status = _writeAnalysisCards(aimInfo, fp, aimInputs, zaeroInstance);
1868 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1868
, __func__, 0); goto cleanup; }
;
1869
1870 status = _writeOutputCardsIfRequested(aimInfo, fp, aimInputs, zaeroInstance);
1871 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 1871
, __func__, 0); goto cleanup; }
;
1872
1873 fprintf(fp, "ENDDATA\n");
1874
1875 status = CAPS_SUCCESS0;
1876cleanup:
1877 return status;
1878}
1879
1880
1881static int
1882_setupArtifacts(aimInfo *aimStruct, capsValue *aimInputs,
1883 aimStorage *zaeroInstance) {
1884
1885 int i, status;
1886
1887 char *inpExt = ".inp", *outExt = ".out";
1888 zaeroUAICStruct *uaic = NULL((void*)0);
1889 zaeroArtifactsStruct *artifacts = &zaeroInstance->artifacts;
1890
1891 // ensure starting with fresh zaeroArtifactsStruct
1892 if (artifacts != NULL((void*)0)) {
1893 status = destroy_zaeroArtifactsStruct(artifacts);
1894 if (status != CAPS_SUCCESS0) {
1895 return status;
1896 }
1897 }
1898
1899 // setup input filename
1900 artifacts->input = string_format("%s%s", aimInputs[inProj_Name-1].vals.string, inpExt, NULL((void*)0));
1901
1902 // setup output filename
1903 artifacts->output = string_format("%s%s", aimInputs[inProj_Name-1].vals.string, outExt, NULL((void*)0));
1904
1905 // TODO: setup modal FEM filename(s) ?
1906
1907 // setup AIC filename for each UAIC configuration
1908
1909 artifacts->numAIC = zaeroInstance->zaeroProblem.numUAICs;
1910 artifacts->aic = EG_alloc(sizeof(capsTuple) * artifacts->numAIC);
1911
1912 for (i = 0; i < artifacts->numAIC; i++) {
1913 uaic = &zaeroInstance->zaeroProblem.UAICs[i];
1914 artifacts->aic[i].name = EG_strdup(uaic->name);
1915 artifacts->aic[i].value = EG_strdup(uaic->aicFilename);
1916 }
1917
1918 return CAPS_SUCCESS0;
1919}
1920
1921
1922static int
1923_propagateExtractedFEMVariables(void *aimInfo,
1924 zaeroProblemStruct *zaeroProblem,
1925 double mass,
1926 double centerGravity[3],
1927 double inertia[6]) {
1928
1929 int i, j;//, status;
1930
1931 zaeroSubcaseStruct *subcase;
1932 zaeroTrimStruct *trim;
1933
1934 for (i = 0; i < zaeroProblem->numSubcases; i ++) {
1935
1936 subcase = &zaeroProblem->subcases[i];
1937
1938 if (subcase->disciplineType == StaticAeroelastic) {
1939
1940 if (subcase->discipline == NULL((void*)0)) {
1941 AIM_ERROR(aimInfo, "subcase discipline is NULL"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 1941, __func__
, "subcase discipline is NULL"); }
;
1942 return CAPS_NULLVALUE-307;
1943 }
1944
1945 trim = (zaeroTrimStruct *) subcase->discipline;
1946 printf("\n\tUpdating StaticAeroelastic subcase: %s\n", subcase->name);
1947
1948 // calculate vectorToCG from aero moment center and center of gravity
1949 for (j = 0; j < 3; j++) {
1950 // only set if user did not already set this value
1951 if (trim->vectorToCG[j] != -1.0) {
1952 trim->vectorToCG[j] = (
1953 centerGravity[j] - zaeroProblem->hfg.refCenter[j]);
1954 }
1955 }
1956 printf("\t- vectorToCG -> [%lf, %lf, %lf]\n",
1957 trim->vectorToCG[0], trim->vectorToCG[1], trim->vectorToCG[2]);
1958
1959 // set weight, if xzsymmetric then double
1960 // if (trim->gravityAcceleration == 0.0) {
1961 // AIM_ERROR(aimInfo, "gravityAcceleration is 0.0 in subcase: %s", subcase->name);
1962 // }
1963 trim->weight = mass;// * trim->gravityAcceleration;
1964 if (strcasecmp(zaeroProblem->hfg.XZSymmetry, "YES") == 0) {
1965 trim->weight *= 2;
1966 }
1967 printf("\t- weight -> %f\n", trim->weight);
1968
1969 // set weight moment of inertia, copy extracted inertia matrix
1970 for (j = 0; j < 6; j++) {
1971 trim->weightMomentOfInertia[j] = inertia[j];
1972 }
1973 printf("\t- weightMomentOfInertia -> [%lf, %lf, %lf, %lf, %lf, %lf]\n",
1974 trim->weightMomentOfInertia[0], trim->weightMomentOfInertia[1],
1975 trim->weightMomentOfInertia[2], trim->weightMomentOfInertia[3],
1976 trim->weightMomentOfInertia[4], trim->weightMomentOfInertia[5]);
1977 }
1978 }
1979
1980 return CAPS_SUCCESS0;
1981}
1982
1983
1984static int
1985_getMassProp(void *aimInfo,
1986 capsValue *aimInputs,
1987 aimStorage *zaeroInstance)
1988{
1989 int i, status;
1990
1991 double mass = 0.0;
1992 double CG[3];
1993 double inertia[6];
1994
1995 double Lunit=1.0;
1996 const char *Lunits, *Munits;
1997 char *Iunits = NULL((void*)0), *tmpUnits = NULL((void*)0);
1998
1999 feaMassPropStruct *feaMassProp=NULL((void*)0);
2000
2001 const char *bodyLunits = NULL((void*)0);
2002 const cfdUnitsStruct *units = &zaeroInstance->units;
2003
2004 // initialize matrices to zero
2005 for (i = 0; i < 3; i++)
2006 CG[i] = 0.0;
2007
2008 for (i = 0; i < 6; i++)
2009 inertia[i] = 0.0;
2010
2011 if (units->length != NULL((void*)0))
2012 Lunits = units->length;
2013 else
2014 Lunits = "m";
2015
2016 if (units->mass != NULL((void*)0))
2017 Munits = units->mass;
2018 else
2019 Munits = "kg";
2020
2021 if (units->length != NULL((void*)0))
2022 {
2023 // Get length units
2024 status = aim_capsLength(aimInfo, &bodyLunits);
2025 if (status != CAPS_SUCCESS0) {
2026 AIM_ERROR(aimInfo, "No units assigned *** capsLength is not set in *.csm file!"){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 2026, __func__
, "No units assigned *** capsLength is not set in *.csm file!"
); }
;
2027 status = CAPS_BADVALUE-311;
2028 goto cleanup;
2029 }
2030
2031 // conversion of the csm model units into units of Lunits
2032 Lunit = 1.0;
2033 status = aim_convert(aimInfo, 1, bodyLunits, &Lunit, Lunits, &Lunit);
2034 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 2034
, __func__, 0); goto cleanup; }
;
2035
2036 status = aim_unitRaise(aimInfo, Lunits, 2, &tmpUnits ); // length^2
2037 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 2037
, __func__, 0); goto cleanup; }
;
2038 status = aim_unitMultiply(aimInfo, Munits, tmpUnits, &Iunits ); // mass*length^2, e.g moment of inertia
2039 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 2039
, __func__, 0); goto cleanup; }
;
2040 AIM_FREE(tmpUnits){ EG_free(tmpUnits); tmpUnits = ((void*)0); };
2041 AIM_NOTNULL(Iunits, aimInfo, status){ if (Iunits == ((void*)0)) { status = -307; aim_status(aimInfo
, status, "zaeroAIM.c", 2041, __func__, 1, "%s == NULL!", "Iunits"
); goto cleanup; } }
;
2042 }
2043
2044 if (aimInputs[inMassPropLink-1].nullVal == NotNull) {
2045 feaMassProp = (feaMassPropStruct *) aimInputs[inMassPropLink-1].vals.AIMptr;
2046
2047 // Mass
2048 mass = feaMassProp->mass;
2049
2050 if (units->mass != NULL((void*)0)) {
2051 status = aim_convert(aimInfo, 1, feaMassProp->massUnit, &mass, Munits, &mass);
2052 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 2052
, __func__, 0); goto cleanup; }
;
2053 }
2054
2055 // Center of gravity
2056 CG[0] = feaMassProp->CG[0];
2057 CG[1] = feaMassProp->CG[1];
2058 CG[2] = feaMassProp->CG[2];
2059
2060 if (units->length != NULL((void*)0)) {
2061 status = aim_convert(aimInfo, 3, feaMassProp->lengthUnit, CG, Lunits, CG);
2062 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 2062
, __func__, 0); goto cleanup; }
;
2063 }
2064
2065 // Inertia order = Ixx, Iyy, Izz, Ixy, Ixz, Iyz
2066 inertia[I11] = feaMassProp->massInertia[I11];
2067 inertia[I22] = feaMassProp->massInertia[I22];
2068 inertia[I33] = feaMassProp->massInertia[I33];
2069 inertia[I21] = feaMassProp->massInertia[I21];
2070 inertia[I31] = feaMassProp->massInertia[I31];
2071 inertia[I32] = feaMassProp->massInertia[I32];
2072
2073 if (units->length != NULL((void*)0)) {
2074 status = aim_convert(aimInfo, 6, feaMassProp->momentOfInertiaUnit, inertia, Iunits, inertia);
2075 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 2075
, __func__, 0); goto cleanup; }
;
2076 }
2077 }
2078
2079 status = _propagateExtractedFEMVariables(aimInfo,
2080 &zaeroInstance->zaeroProblem,
2081 mass, CG, inertia);
2082 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 2082
, __func__, 0); goto cleanup; }
;
2083
2084 status = CAPS_SUCCESS0;
2085
2086cleanup:
2087
2088 return status;
2089}
2090
2091
2092static int
2093_openInputFile(void *aimInfo, const char *inputFilename,
2094 const char *mode, FILE **fp) {
2095
2096 int status;
2097 char filepath[PATH_MAX4096];
2098 const char *_mode = NULL((void*)0);
2099
2100 if (mode != NULL((void*)0)) _mode = mode;
2101 else _mode = "w"; // "w" mode by default
2102
2103 snprintf(filepath, PATH_MAX4096, "%s%s", PATH_SEP"/", inputFilename);
2104
2105 *fp = aim_fopen(aimInfo, filepath, _mode);
2106 if (*fp == NULL((void*)0)) {
2107 AIM_ERROR(aimInfo, "Unable to open file: %s", filepath){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 2107, __func__
, "Unable to open file: %s", filepath); }
;
2108 status = CAPS_IOERR-332;
2109 goto cleanup;
2110 }
2111
2112 status = CAPS_SUCCESS0;
2113
2114cleanup:
2115 return status;
2116}
2117
2118
2119/****************** exposed AIM entry points -- Analysis **********************/
2120
2121/* aimInitialize: Initialization Information for the AIM */
2122int aimInitialize(int inst, /*@unused@*/ const char *unitSys, void *aimInfo,
2123 /*@unused@*/ void **instStore, /*@unused@*/ int *major,
2124 /*@unused@*/ int *minor, int *nIn, int *nOut,
2125 int *nFields, char ***fnames, int **franks, int **fInOut)
2126{
2127 int status;
2128 aimStorage *zaeroInstance = NULL((void*)0);
2129
2130 const char *keyWord;
2131 char *keyValue = NULL((void*)0);
2132 double real = 1;
2133 cfdUnitsStruct *units=NULL((void*)0);
2134
2135#ifdef DEBUG
2136 printf("\n zaeroAIM/aimInitialize inst = %d!\n", inst);
2137#endif
2138
2139 /* specify the number of analysis inputs defined in aimInputs
2140 * and the number of analysis outputs defined in aimOutputs */
2141 *nIn = NUMINPUT;
2142 *nOut = NUMOUTPUT;
2143 if (inst == -1) return CAPS_SUCCESS0;
2144
2145 /* specify the field variables this analysis can generate */
2146 *nFields = 0;
2147 *franks = NULL((void*)0);
2148 *fnames = NULL((void*)0);
2149 *fInOut = NULL((void*)0);
2150
2151 // Allocate zaeroInstance
2152 AIM_ALLOC(zaeroInstance, 1, aimStorage, aimInfo, status){ if (zaeroInstance != ((void*)0)) { status = -4; aim_status(
aimInfo, status, "zaeroAIM.c", 2152, __func__, 1, "AIM_ALLOC: %s != NULL"
, "zaeroInstance"); goto cleanup; } size_t memorysize = 1; zaeroInstance
= (aimStorage *) EG_alloc(memorysize*sizeof(aimStorage)); if
(zaeroInstance == ((void*)0)) { status = -4; aim_status(aimInfo
, status, "zaeroAIM.c", 2152, __func__, 3, "AIM_ALLOC: %s size %zu type %s"
, "zaeroInstance", memorysize, "aimStorage"); goto cleanup; }
}
;
2153
2154 // Initialize instance storage
2155 initiate_aimStorage(zaeroInstance);
2156
2157 /*! \page aimUnitsZAERO AIM Units
2158 * A unit system may be optionally specified during AIM instance initiation. If
2159 * a unit system is provided, all AIM input values which have associated units must be specified as well.
2160 * If no unit system is used, AIM inputs, which otherwise would require units, will be assumed
2161 * unit consistent. A unit system may be specified via a JSON string dictionary for example:
2162 * unitSys = "{"mass": "kg", "length": "m", "time":"seconds", "temperature": "K"}"
2163 */
2164 if (unitSys != NULL((void*)0)) {
2165 units = &zaeroInstance->units;
2166
2167 // Do we have a json string?
2168 if (strncmp( unitSys, "{", 1) != 0) {
2169 AIM_ERROR(aimInfo, "unitSys ('%s') is expected to be a JSON string dictionary", unitSys){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 2169, __func__
, "unitSys ('%s') is expected to be a JSON string dictionary"
, unitSys); }
;
2170 return CAPS_BADVALUE-311;
2171 }
2172
2173 /*! \page aimUnitsZAERO
2174 * \section jsonStringZAERO JSON String Dictionary
2175 * The key arguments of the dictionary are described in the following:
2176 *
2177 * <ul>
2178 * <li> <B>mass = "None"</B> </li> <br>
2179 * Mass units - e.g. "kilogram", "k", "slug", ...
2180 * </ul>
2181 */
2182 keyWord = "mass";
2183 status = search_jsonDictionary(unitSys, keyWord, &keyValue);
2184 if (status == CAPS_SUCCESS0) {
2185 units->mass = string_removeQuotation(keyValue);
2186 AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); };
2187 real = 1;
2188 status = aim_convert(aimInfo, 1, units->mass, &real, "kg", &real);
2189 AIM_STATUS(aimInfo, status, "unitSys ('%s'): %s is not a %s unit", unitSys, units->mass, keyWord)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 2189
, __func__, 4, "unitSys ('%s'): %s is not a %s unit", unitSys
, units->mass, keyWord); goto cleanup; }
;
2190 } else {
2191 AIM_ERROR(aimInfo, "unitSys ('%s') does not contain '%s'", unitSys, keyWord){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 2191, __func__
, "unitSys ('%s') does not contain '%s'", unitSys, keyWord); }
;
2192 status = CAPS_BADVALUE-311;
2193 goto cleanup;
2194 }
2195
2196 /*! \page aimUnitsZAERO
2197 * <ul>
2198 * <li> <B>length = "None"</B> </li> <br>
2199 * Length units - e.g. "meter", "m", "inch", "in", "mile", ...
2200 * </ul>
2201 */
2202 keyWord = "length";
2203 status = search_jsonDictionary(unitSys, keyWord, &keyValue);
2204 if (status == CAPS_SUCCESS0) {
2205 units->length = string_removeQuotation(keyValue);
2206 AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); };
2207 real = 1;
2208 status = aim_convert(aimInfo, 1, units->length, &real, "m", &real);
2209 AIM_STATUS(aimInfo, status, "unitSys ('%s'): %s is not a %s unit", unitSys, units->length, keyWord)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 2209
, __func__, 4, "unitSys ('%s'): %s is not a %s unit", unitSys
, units->length, keyWord); goto cleanup; }
;
2210 } else {
2211 AIM_ERROR(aimInfo, "unitSys ('%s') does not contain '%s'", unitSys, keyWord){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 2211, __func__
, "unitSys ('%s') does not contain '%s'", unitSys, keyWord); }
;
2212 status = CAPS_BADVALUE-311;
2213 goto cleanup;
2214 }
2215
2216 /*! \page aimUnitsZAERO
2217 * <ul>
2218 * <li> <B>time = "None"</B> </li> <br>
2219 * Time units - e.g. "second", "s", "minute", ...
2220 * </ul>
2221 */
2222 keyWord = "time";
2223 status = search_jsonDictionary(unitSys, keyWord, &keyValue);
2224 if (status == CAPS_SUCCESS0) {
2225 units->time = string_removeQuotation(keyValue);
2226 AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); };
2227 real = 1;
2228 status = aim_convert(aimInfo, 1, units->time, &real, "s", &real);
2229 AIM_STATUS(aimInfo, status, "unitSys ('%s'): %s is not a %s unit", unitSys, units->time, keyWord)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 2229
, __func__, 4, "unitSys ('%s'): %s is not a %s unit", unitSys
, units->time, keyWord); goto cleanup; }
;
2230 } else {
2231 AIM_ERROR(aimInfo, "unitSys ('%s') does not contain '%s'", unitSys, keyWord){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 2231, __func__
, "unitSys ('%s') does not contain '%s'", unitSys, keyWord); }
;
2232 status = CAPS_BADVALUE-311;
2233 goto cleanup;
2234 }
2235
2236 /*! \page aimUnitsZAERO
2237 * <ul>
2238 * <li> <B>temperature = "None"</B> </li> <br>
2239 * Temperature units - e.g. "Kelvin", "K", "degC", ...
2240 * </ul>
2241 */
2242 keyWord = "temperature";
2243 status = search_jsonDictionary(unitSys, keyWord, &keyValue);
2244 if (status == CAPS_SUCCESS0) {
2245 units->temperature = string_removeQuotation(keyValue);
2246 AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); };
2247 real = 1;
2248 status = aim_convert(aimInfo, 1, units->temperature, &real, "K", &real);
2249 AIM_STATUS(aimInfo, status, "unitSys ('%s'): %s is not a %s unit", unitSys, units->temperature, keyWord)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 2249
, __func__, 4, "unitSys ('%s'): %s is not a %s unit", unitSys
, units->temperature, keyWord); goto cleanup; }
;
2250 } else {
2251 AIM_ERROR(aimInfo, "unitSys ('%s') does not contain '%s'", unitSys, keyWord){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 2251, __func__
, "unitSys ('%s') does not contain '%s'", unitSys, keyWord); }
;
2252 status = CAPS_BADVALUE-311;
2253 goto cleanup;
2254 }
2255
2256 status = cfd_cfdDerivedUnits(aimInfo, units);
2257 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 2257
, __func__, 0); goto cleanup; }
;
2258 }
2259
2260 *instStore = zaeroInstance;
2261
2262 status = CAPS_SUCCESS0;
2263
2264cleanup:
2265 return status;
2266}
2267
2268
2269// ********************** AIM Function Break *****************************
2270/* aimInputs: Input Information for the AIM */
2271int aimInputs(/*@unused@*/ void *instStore, /*@unused@*/ void *aimInfo,
2272 int index, char **ainame, capsValue *defval)
2273{
2274 /*! \page aimInputsZAERO AIM Inputs
2275 * The following list outlines the Zaero inputs along with their default value available
2276 * through the AIM interface.
2277 */
2278 int status = CAPS_SUCCESS0;
2279 aimStorage *zaeroInstance;
2280 cfdUnitsStruct *units=NULL((void*)0);
2281
2282 *ainame = NULL((void*)0);
2283
2284 zaeroInstance = (aimStorage *) instStore;
2285 if (zaeroInstance == NULL((void*)0)) AIM_STATUS(aimInfo, CAPS_NULLVALUE)if (-307 != 0) { aim_status(aimInfo, -307, "zaeroAIM.c", 2285
, __func__, 0); goto cleanup; }
;
2286
2287 if (zaeroInstance != NULL((void*)0)) units = &zaeroInstance->units;
2288
2289// #ifdef DEBUG
2290// printf(" zaeroAIM/aimInputs zaeroInstances = %d index = %d!\n", iIndex, index);
2291// #endif
2292
2293 // Zaero Inputs
2294 if (index == inProj_Name) {
2295 *ainame = EG_strdup("Proj_Name");
2296 defval->type = String;
2297 defval->nullVal = NotNull;
2298 defval->vals.string = EG_strdup("zaero_CAPS");
2299 defval->lfixed = Change;
2300
2301 /*! \page aimInputsZAERO
2302 * - <B> Proj_Name = "zaero_CAPS"</B> <br>
2303 * This corresponds to the project name used for file naming.
2304 */
2305
2306 } else if (index == inAnalysis) {
2307 *ainame = EG_strdup("Analysis");
2308 defval->type = Tuple;
2309 defval->nullVal = IsNull;
2310 defval->lfixed = Change;
2311 defval->vals.tuple = NULL((void*)0);
2312 defval->dim = Vector;
2313
2314 /*! \page aimInputsZAERO
2315 * - <B> Analysis = NULL</B> <br>
2316 * Analysis tuple used to input analysis/case information for the model.
2317 */
2318
2319 } else if (index == inFile_Format) {
2320 *ainame = EG_strdup("File_Format");
2321 defval->type = String;
2322 defval->vals.string = EG_strdup("Small"); // Small, Free
2323
2324 /*! \page aimInputsZAERO/
2325 * - <B> File_Format = "Small"</B> <br>
2326 * Formatting type for the bulk file. Options: "Small", "Large", "Free".
2327 */
2328
2329 } else if (index == inFEM_1) {
2330 *ainame = EG_strdup("FEM_1");
2331 defval->type = Tuple;
2332 defval->nullVal = IsNull;
2333 defval->lfixed = Change;
2334 defval->dim = Vector;
2335
2336 /*! \page aimInputsZAERO
2337 * - <B> FEM_1 = NULL </B> <br>
2338 * JSON dictionary for first ZAero ASSIGN FEM inputs in Executive Control Section (See \ref zaeroECS)
2339 */
2340
2341 } else if (index == inF06_1) {
2342 *ainame = EG_strdup("F06_1");
2343 defval->type = Pointer;
2344 defval->nullVal = IsNull;
2345 AIM_STRDUP(defval->units, "feaSolFileStruct", aimInfo, status){ if (defval->units != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "zaeroAIM.c", 2345, __func__, 1, "AIM_STRDUP: %s != NULL!"
, "defval->units"); goto cleanup; } defval->units = EG_strdup
("feaSolFileStruct"); if (defval->units == ((void*)0)) { status
= -4; aim_status(aimInfo, status, "zaeroAIM.c", 2345, __func__
, 2, "AIM_STRDUP: %s %s", "defval->units", "feaSolFileStruct"
); goto cleanup; } }
;
2346
2347 /*! \page aimInputsZAERO
2348 * - <B> F06_1 = NULL </B> <br>
2349 * Link for F06 file from from a structural analysis AIM for first ZAero ASSIGN FEM.
2350 * zaeroAIM will attempt to extract / determine as many analysis parameters from the F06 file as possible.
2351 */
2352
2353 } else if (index == inFEM_2) {
2354 *ainame = EG_strdup("FEM_2");
2355 defval->type = Tuple;
2356 defval->nullVal = IsNull;
2357 defval->lfixed = Change;
2358 defval->dim = Vector;
2359
2360 /*! \page aimInputsZAERO
2361 * - <B> FEM_2 = NULL </B> <br>
2362 * JSON dictionary for first ZAero ASSIGN FEM inputs in Executive Control Section (See \ref zaeroECS)
2363 */
2364
2365 } else if (index == inF06_2) {
2366 *ainame = EG_strdup("F06_2");
2367 defval->type = Pointer;
2368 defval->nullVal = IsNull;
2369 AIM_STRDUP(defval->units, "feaSolFileStruct", aimInfo, status){ if (defval->units != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "zaeroAIM.c", 2369, __func__, 1, "AIM_STRDUP: %s != NULL!"
, "defval->units"); goto cleanup; } defval->units = EG_strdup
("feaSolFileStruct"); if (defval->units == ((void*)0)) { status
= -4; aim_status(aimInfo, status, "zaeroAIM.c", 2369, __func__
, 2, "AIM_STRDUP: %s %s", "defval->units", "feaSolFileStruct"
); goto cleanup; } }
;
2370
2371 /*! \page aimInputsZAERO
2372 * - <B> F06_2 = NULL </B> <br>
2373 * Link for F06 file from from a structural analysis AIM for second ZAero ASSIGN FEM.
2374 * zaeroAIM will attempt to extract / determine as many analysis parameters from the F06 file as possible.
2375 */
2376
2377 } else if (index == inCPU) {
2378 *ainame = EG_strdup("CPU");
2379 defval->type = Integer;
2380 defval->vals.integer = 1;
2381
2382 /*! \page aimInputsZAERO
2383 * - <B> CPU = 1 </B> <br>
2384 * Defines the number of processors for parallel computation.
2385 */
2386
2387 } else if (index == inMemory) {
2388 *ainame = EG_strdup("Memory");
2389 defval->type = String;
2390 defval->vals.string = EG_strdup("1600MB");
2391 defval->lfixed = Change;
2392
2393 /*! \page aimInputsZAERO
2394 * - <B> Memory = "1600MB" </B> <br>
2395 * Maximum memory in terms of megabytes that is allocable by ZAERO from
2396 * the heap space.
2397 */
2398
2399 } else if (index == inSmart_Restart) {
2400 *ainame = EG_strdup("Smart_Restart");
2401 defval->type = Boolean;
2402 defval->vals.integer = (int) true1;
2403
2404 /*! \page aimInputsZAERO
2405 * - <B> Smart_Restart = True </B> <br>
2406 * If True, zaeroAIM will try to detect whether the ZAERO restart capability
2407 * can be used and configure the ZAERO input to load existing AIC matrices.
2408 * If False, new AIC matrices are always generated.
2409 */
2410
2411 } else if (index == inEcho) {
2412 *ainame = EG_strdup("Echo");
2413 defval->type = String;
2414 defval->vals.string = EG_strdup("sort");
2415 defval->lfixed = Change;
2416
2417 /*! \page aimInputsZAERO
2418 * - <B> Echo = "sort" </B> <br>
2419 * Controls echo (printout) of the Bulk Data Section
2420 */
2421
2422 } else if (index == inOutput) {
2423 *ainame = EG_strdup("Output");
2424 defval->type = Tuple;
2425 defval->nullVal = IsNull;
2426 defval->lfixed = Change;
2427 defval->vals.tuple = NULL((void*)0);
2428 defval->dim = Vector;
2429
2430 /*! \page aimInputsZAERO
2431 * - <B> Output </B> <br>
2432 * Output tuple used to define analysis/case outputs for plotting, etc.
2433 */
2434
2435 } else if (index == inHFG) {
2436 *ainame = EG_strdup("HFG");
2437 defval->type = Tuple;
2438 defval->nullVal = IsNull;
2439 defval->lfixed = Change;
2440 defval->dim = Vector;
2441
2442 /*! \page aimInputsZAERO
2443 * - <B> HFG </B> <br>
2444 * JSON dictionary used to define HFG module data
2445 */
2446
2447 } else if (index == inUAIC) {
2448 *ainame = EG_strdup("UAIC");
2449 defval->type = Tuple;
2450 defval->nullVal = IsNull;
2451 defval->lfixed = Change;
2452 defval->vals.tuple = NULL((void*)0);
2453 defval->dim = Vector;
2454
2455 /*! \page aimInputsZAERO
2456 * - <B> UAIC </B> <br>
2457 * UAIC tuple used to define UAIC configurations for unsteady aerodynamics data generation, see \ref zaeroUAIC for additional details.
2458 */
2459
2460 } else if (index == inSpline) {
2461 *ainame = EG_strdup("Spline");
2462 defval->type = Tuple;
2463 defval->nullVal = IsNull;
2464 defval->lfixed = Change;
2465 defval->vals.tuple = NULL((void*)0);
2466 defval->dim = Vector;
2467
2468 /*! \page aimInputsZAERO
2469 * - <B> Spline </B> <br>
2470 * JSON dictionary used to define SPLINE module data, see \ref zaeroSpline for additional details.
2471 */
2472
2473 } else if (index == inVLM_Surface) {
2474 *ainame = EG_strdup("VLM_Surface");
2475 defval->type = Tuple;
2476 defval->nullVal = IsNull;
2477 //defval->units = NULL;
2478 defval->dim = Vector;
2479 defval->lfixed = Change;
2480 defval->vals.tuple = NULL((void*)0);
2481
2482 /*! \page aimInputsZAERO
2483 * - <B>VLM_Surface = NULL </B> <br>
2484 * Vortex lattice method tuple input, see \ref vlmSurface for additional details.
2485 */
2486
2487 } else if (index == inVLM_Control) {
2488 *ainame = EG_strdup("VLM_Control");
2489 defval->type = Tuple;
2490 defval->nullVal = IsNull;
2491 //defval->units = NULL;
2492 defval->dim = Vector;
2493 defval->lfixed = Change;
2494 defval->vals.tuple = NULL((void*)0);
2495
2496 /*! \page aimInputsZAERO
2497 * - <B>VLM_Control = NULL </B> <br>
2498 * Vortex lattice method control surface tuple input, see \ref vlmControl for additional details.
2499 */
2500
2501 } else if (index == inTrim_Variable) {
2502 *ainame = EG_strdup("Trim_Variable");
2503 defval->type = Tuple;
2504 defval->nullVal = IsNull;
2505 defval->lfixed = Change;
2506 defval->vals.tuple = NULL((void*)0);
2507 defval->dim = Vector;
2508
2509 /*! \page aimInputsZAERO
2510 * - <B> Trim_Variable </B> <br>
2511 * Trim_Variable tuple used to define Trim variables and/or constraints, see \ref zaeroTRIMVAR for additional details.
2512 */
2513
2514 } else if (index == inReferenceArea) {
2515 *ainame = EG_strdup("ReferenceArea");
2516 defval->type = Double;
2517 defval->nullVal = IsNull;
2518 defval->lfixed = Fixed;
2519 defval->dim = 0;
2520 defval->vals.real = 0.0;
2521 if (units != NULL((void*)0) && units->area != NULL((void*)0)) {
2522 AIM_STRDUP(defval->units, units->area, aimInfo, status){ if (defval->units != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "zaeroAIM.c", 2522, __func__, 1, "AIM_STRDUP: %s != NULL!"
, "defval->units"); goto cleanup; } defval->units = EG_strdup
(units->area); if (defval->units == ((void*)0)) { status
= -4; aim_status(aimInfo, status, "zaeroAIM.c", 2522, __func__
, 2, "AIM_STRDUP: %s %s", "defval->units", units->area)
; goto cleanup; } }
;
2523 }
2524
2525 /*! \page aimInputsZAERO
2526 * - <B>ReferenceArea = NULL </B> <br>
2527 * This sets the reference area for used in force and moment calculations.
2528 * Alternatively, the geometry (body) attribute (see \ref attributeZAERO) "capsReferenceArea" maybe used to specify this variable
2529 * (note: values set through the AIM input will supersede the attribution value).
2530 */
2531
2532 } else if (index == inReferenceChord) {
2533 *ainame = EG_strdup("ReferenceChord");
2534 defval->type = Double;
2535 defval->nullVal = IsNull;
2536 defval->lfixed = Fixed;
2537 defval->dim = 0;
2538 defval->vals.real = 0.0;
2539 if (units != NULL((void*)0) && units->length != NULL((void*)0)) {
2540 AIM_STRDUP(defval->units, units->length, aimInfo, status){ if (defval->units != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "zaeroAIM.c", 2540, __func__, 1, "AIM_STRDUP: %s != NULL!"
, "defval->units"); goto cleanup; } defval->units = EG_strdup
(units->length); if (defval->units == ((void*)0)) { status
= -4; aim_status(aimInfo, status, "zaeroAIM.c", 2540, __func__
, 2, "AIM_STRDUP: %s %s", "defval->units", units->length
); goto cleanup; } }
;
2541 }
2542
2543 /*! \page aimInputsZAERO
2544 * - <B>ReferenceChord = NULL </B> <br>
2545 * This sets the reference chord for used in force and moment calculations.
2546 * Alternatively, the geometry (body) attribute (see \ref attributeZAERO) "capsReferenceChord" maybe used to specify this variable
2547 * (note: values set through the AIM input will supersede the attribution value).
2548 */
2549
2550 } else if (index == inReferenceSpan) {
2551 *ainame = EG_strdup("ReferenceSpan");
2552 defval->type = Double;
2553 defval->nullVal = IsNull;
2554 defval->lfixed = Fixed;
2555 defval->dim = 0;
2556 defval->vals.real = 0.0;
2557 if (units != NULL((void*)0) && units->length != NULL((void*)0)) {
2558 AIM_STRDUP(defval->units, units->length, aimInfo, status){ if (defval->units != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "zaeroAIM.c", 2558, __func__, 1, "AIM_STRDUP: %s != NULL!"
, "defval->units"); goto cleanup; } defval->units = EG_strdup
(units->length); if (defval->units == ((void*)0)) { status
= -4; aim_status(aimInfo, status, "zaeroAIM.c", 2558, __func__
, 2, "AIM_STRDUP: %s %s", "defval->units", units->length
); goto cleanup; } }
;
2559 }
2560
2561 /*! \page aimInputsZAERO
2562 * - <B>ReferenceSpan = NULL </B> <br>
2563 * This sets the reference span for used in force and moment calculations.
2564 * Alternatively, the geometry (body) attribute (see \ref attributeZAERO) "capsReferenceSpan" maybe used to specify this variable
2565 * (note: values set through the AIM input will supersede the attribution value).
2566 */
2567
2568 } else if (index == inMoment_Center) {
2569 *ainame = EG_strdup("Moment_Center");
2570 defval->type = Double;
2571 defval->dim = 1;
2572 defval->length = 3;
2573 defval->nrow = 3;
2574 defval->ncol = 1;
2575 AIM_ALLOC(defval->vals.reals, defval->length, double, aimInfo, status){ if (defval->vals.reals != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "zaeroAIM.c", 2575, __func__, 1, "AIM_ALLOC: %s != NULL"
, "defval->vals.reals"); goto cleanup; } size_t memorysize
= defval->length; defval->vals.reals = (double *) EG_alloc
(memorysize*sizeof(double)); if (defval->vals.reals == ((void
*)0)) { status = -4; aim_status(aimInfo, status, "zaeroAIM.c"
, 2575, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "defval->vals.reals"
, memorysize, "double"); goto cleanup; } }
;
2576 defval->vals.reals[0] = 0.0;
2577 defval->vals.reals[1] = 0.0;
2578 defval->vals.reals[2] = 0.0;
2579 defval->nullVal = IsNull;
2580 defval->lfixed = Fixed;
2581 if (units != NULL((void*)0) && units->length != NULL((void*)0)) {
2582 AIM_STRDUP(defval->units, units->length, aimInfo, status){ if (defval->units != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "zaeroAIM.c", 2582, __func__, 1, "AIM_STRDUP: %s != NULL!"
, "defval->units"); goto cleanup; } defval->units = EG_strdup
(units->length); if (defval->units == ((void*)0)) { status
= -4; aim_status(aimInfo, status, "zaeroAIM.c", 2582, __func__
, 2, "AIM_STRDUP: %s %s", "defval->units", units->length
); goto cleanup; } }
;
2583 }
2584
2585 /*! \page aimInputsZAERO
2586 * - <B>Moment_Center = [0.0, 0.0, 0.0] (NULL)</B> <br>
2587 * Array values correspond to the x, y, and z center of gravity (CG) locations [meter].
2588 * Alternatively, the geometry (body) attributes (see \ref attributeZAERO) "capsReferenceX", "capsReferenceY",
2589 * and "capsReferenceZ" may be used to specify the center of gravity, respectively
2590 * (note: values set through the AIM input will supersede the attribution values).
2591 */
2592
2593 } else if (index == inMassPropLink) {
2594 *ainame = EG_strdup("MassPropLink");
2595 defval->type = Pointer;
2596 defval->nullVal = IsNull;
2597 AIM_STRDUP(defval->units, "feaMassPropStruct", aimInfo, status){ if (defval->units != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "zaeroAIM.c", 2597, __func__, 1, "AIM_STRDUP: %s != NULL!"
, "defval->units"); goto cleanup; } defval->units = EG_strdup
("feaMassPropStruct"); if (defval->units == ((void*)0)) { status
= -4; aim_status(aimInfo, status, "zaeroAIM.c", 2597, __func__
, 2, "AIM_STRDUP: %s %s", "defval->units", "feaMassPropStruct"
); goto cleanup; } }
;
2598
2599 /*! \page aimInputsZAERO
2600 * - <B>MassPropLink = NULL</B> <br>
2601 * Mass properties linked from structural analysis for eigen value analysis
2602 * Must be in units of kg, m, and kg*m^2 if unitSystem (see \ref aimUnitsZAERO) is not specified.
2603 */
2604
2605 } else {
2606 AIM_ERROR(aimInfo, "Unknown input index $%d", index){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 2606, __func__
, "Unknown input index $%d", index); }
;
2607 status = CAPS_RANGEERR-326;
2608 goto cleanup;
2609 }
2610
2611 AIM_NOTNULL(*ainame, aimInfo, status){ if (*ainame == ((void*)0)) { status = -307; aim_status(aimInfo
, status, "zaeroAIM.c", 2611, __func__, 1, "%s == NULL!", "*ainame"
); goto cleanup; } }
;
2612
2613cleanup:
2614 if (status != CAPS_SUCCESS0) AIM_FREE(*ainame){ EG_free(*ainame); *ainame = ((void*)0); };
2615 return CAPS_SUCCESS0;
2616
2617}
2618
2619
2620// ********************** AIM Function Break *****************************
2621int aimUpdateState(void *instStore, void *aimInfo,
2622 capsValue *aimInputs)
2623{
2624 // Function return flag
2625 int status = CAPS_SUCCESS0;
2626 int i;
2627 zaeroUAICStruct *uaic=NULL((void*)0);
2628
2629 aimStorage *zaeroInstance = (aimStorage *)instStore;
2630 AIM_NOTNULL(zaeroInstance, aimInfo, status){ if (zaeroInstance == ((void*)0)) { status = -307; aim_status
(aimInfo, status, "zaeroAIM.c", 2630, __func__, 1, "%s == NULL!"
, "zaeroInstance"); goto cleanup; } }
;
2631
2632 // Get project name
2633 zaeroInstance->smartRestart = aimInputs[inSmart_Restart-1].vals.integer;
2634
2635 if (zaeroInstance->smartRestart) {
2636 printf("\n'Smart_Restart' is ON\n");
2637 }
2638 else {
2639 printf("\n'Smart_Restart' is OFF\n");
2640 }
2641
2642 /* Per the manual:
2643 * "In the following conditions, the restart process becomes inapplicable and
2644 * the new AICs must be computed [...]
2645 * - Any changes in the CAERO7 and/or BODY7 and their associated
2646 * bulk data cards
2647 * - Any changes in the MKAEROZ bulk data card"
2648 *
2649 * Therefore aicFilename is removed if any of the following has changed:
2650 * - the MKAEROZ data (UAIC module)
2651 * - the CAERO7 data
2652 * - the BODY7
2653 */
2654 if (zaeroInstance->smartRestart == (int)false0 ||
2655 aim_newAnalysisIn(aimInfo, inUAIC) == CAPS_SUCCESS0 ||
2656 aim_newAnalysisIn(aimInfo, inVLM_Surface) == CAPS_SUCCESS0 ||
2657 aim_newAnalysisIn(aimInfo, inVLM_Control) == CAPS_SUCCESS0 ||
2658 aim_newGeometry(aimInfo) == CAPS_SUCCESS0) {
2659 for (i = 0; i < zaeroInstance->zaeroProblem.numUAICs; i++) {
2660
2661 uaic = &zaeroInstance->zaeroProblem.UAICs[i];
2662
2663 status = aim_rmFile(aimInfo, uaic->aicFilename);
2664 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 2664
, __func__, 0); goto cleanup; }
;
2665 }
2666 }
2667
2668 status = _createVLM(aimInfo, aimInputs, zaeroInstance);
2669 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 2669
, __func__, 0); goto cleanup; }
;
2670
2671 status = _getZaeroProblemData(aimInfo, aimInputs, zaeroInstance);
2672 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 2672
, __func__, 0); goto cleanup; }
;
2673
2674 status = _setupArtifacts(aimInfo, aimInputs, zaeroInstance);
2675 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 2675
, __func__, 0); goto cleanup; }
;
2676
2677 // Mass properties are propagated and must be done last
2678 status = _getMassProp(aimInfo, aimInputs, zaeroInstance);
2679 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 2679
, __func__, 0); goto cleanup; }
;
2680
2681 if (zaeroInstance->smartRestart == (int)true1) {
2682 for (i = 0; i < zaeroInstance->zaeroProblem.numUAICs; i++) {
2683 uaic = &zaeroInstance->zaeroProblem.UAICs[i];
2684 if (aim_isFile(aimInfo, uaic->aicFilename) == CAPS_SUCCESS0) {
2685 uaic->saveFlag = 1; // ACQUIRE
2686 }
2687 }
2688 }
2689
2690 // Set file format type
2691 if (strcasecmp(aimInputs[inFile_Format-1].vals.string, "Small") == 0) {
2692 zaeroInstance->feaFormatType = SmallField;
2693 } else if (strcasecmp(aimInputs[inFile_Format-1].vals.string, "Large") == 0) {
2694 zaeroInstance->feaFormatType = LargeField;
2695 } else if (strcasecmp(aimInputs[inFile_Format-1].vals.string, "Free") == 0) {
2696 zaeroInstance->feaFormatType = FreeField;
2697 } else {
2698 AIM_ERROR(aimInfo, "Unrecognized \"File_Format\", valid choices are [Small, Large, or Free]."){ aim_message(aimInfo, CERROR, 0 , "zaeroAIM.c", 2698, __func__
, "Unrecognized \"File_Format\", valid choices are [Small, Large, or Free]."
); }
;
2699 status = CAPS_BADVALUE-311;
2700 goto cleanup;
2701 }
2702
2703cleanup:
2704 return status;
2705}
2706
2707// ********************** AIM Function Break *****************************
2708/* aimPreAnalysis: Generate Input File(s) */
2709int aimPreAnalysis(const void *instStore, void *aimInfo, capsValue *aimInputs)
2710{
2711 int status; // Status return
2712
2713 FILE *inputFile = NULL((void*)0); // input file to be generated
2714
2715 const aimStorage *zaeroInstance = NULL((void*)0);
2716
2717 // Get pointer to current instance
2718 zaeroInstance = (const aimStorage*)instStore;
2719
2720// #ifdef DEBUG
2721// printf("\n zaeroAIM/aimPreAnalysis zaeroInstances = %d!\n", iIndex);
2722// #endif
2723
2724 // open input file to be generated
2725 status = _openInputFile(aimInfo,
2726 zaeroInstance->artifacts.input,
2727 "w",
2728 &inputFile);
2729 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 2729
, __func__, 0); goto cleanup; }
;
2730
2731 status = _writeExecutiveControlSection(aimInfo, inputFile, aimInputs, zaeroInstance);
2732 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 2732
, __func__, 0); goto cleanup; }
;
2733
2734 status = _writeCaseControlSection(aimInfo, inputFile, aimInputs, zaeroInstance);
2735 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 2735
, __func__, 0); goto cleanup; }
;
2736
2737 status = _writeBulkDataSection(aimInfo, inputFile, aimInputs, zaeroInstance);
2738 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "zaeroAIM.c", 2738
, __func__, 0); goto cleanup; }
;
2739
2740 status = CAPS_SUCCESS0;
2741
2742cleanup:
2743
2744 if (inputFile != NULL((void*)0)) {
2745 fclose(inputFile);
2746 }
2747
2748 return status;
2749}
2750
2751// ********************** AIM Function Break *****************************
2752/* aimPostAnalysis: Perform any processing after the Analysis is run */
2753int aimPostAnalysis(/*@unused@*/ void *instStore, /*@unused@*/ void *aimInfo,
2754 /*@unused@*/ int restart, /*@unused@*/ capsValue *inputs)
2755{
2756 int status = CAPS_SUCCESS0;
2757
2758 return status;
2759}
2760
2761// ********************** AIM Function Break *****************************
2762/* aimOutputs: Output Information for the AIM */
2763int aimOutputs(/*@unused@*/ void *instStore, /*@unused@*/ void *aimInfo,
2764 /*@unused@*/ int index, /*@unused@*/ char **aoname, /*@unused@*/ capsValue *form)
2765{
2766// #ifdef DEBUG
2767// printf(" zaeroAIM/aimOutputs zaeroInstances = %d index = %d!\n", iIndex, index);
2768// #endif
2769
2770// *aoname = EG_strdup("zaeroAIMout");
2771// if (*aoname == NULL) return EGADS_MALLOC;
2772// form->type = Double;
2773
2774 return CAPS_SUCCESS0;
2775}
2776
2777// ********************** AIM Function Break *****************************
2778/* aimCalcOutput: Calculate/Retrieve Output Information */
2779int aimCalcOutput(/*@unused@*/ void *instStore, /*@unused@*/ void *aimInfo, /*@unused@*/ int index,
2780 /*@unused@*/ capsValue *val)
2781{
2782// #ifdef DEBUG
2783// int status;
2784// const char *name;
2785//
2786// status = aim_getName(aimInfo, index, ANALYSISOUT, &name);
2787// printf(" zaeroAIM/aimCalcOutput zaeroInstances = %d index = %d %s %d!\n",
2788// iIndex, index, name, status);
2789// #endif
2790
2791// *errors = NULL;
2792// if ((iIndex < 0) || (iIndex >= numInstances)) return CAPS_BADINDEX;
2793// val->vals.real = 3.1415926;
2794
2795 return CAPS_SUCCESS0;
2796}
2797
2798// ********************** AIM Function Break *****************************
2799/* aimCleanup: Free up the AIMs storage */
2800void aimCleanup(void *instStore)
2801{
2802 // #ifdef DEBUG
2803 // printf(" zaeroAIM/aimCleanup!\n");
2804 // #endif
2805
2806 aimStorage *zaeroInstance = NULL((void*)0);
2807
2808 // Get pointer to current instance
2809 zaeroInstance = (aimStorage*)instStore;
2810
2811 // Clean up zaeroInstances data
2812 destroy_aimStorage(zaeroInstance);
2813
2814 AIM_FREE(zaeroInstance){ EG_free(zaeroInstance); zaeroInstance = ((void*)0); };
2815
2816}