Bug Summary

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