Bug Summary

File:astros/astrosAIM.c
Warning:line 2293, column 83
Dereference of null pointer

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 astrosAIM.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -D REVISION=7.6 -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/astros -ferror-limit 19 -fmessage-length 0 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/jenkins/workspace/ESP_Stanalizer/LINUX64/CAPS/scan-build/scanCAPS/2022-04-21-160214-102256-1 -x c astrosAIM.c
1/*
2 * CAPS: Computational Aircraft Prototype Syntheses
3 *
4 * ASTROS AIM
5 *
6 * Written by Dr. Ryan Durscher and Dr. Ed Alyanak AFRL/RQVC
7 *
8 * This software has been cleared for public release on 05 Nov 2020, case number 88ABW-2020-3462.
9 *
10 */
11
12/*! \mainpage Introduction
13 *
14 * \section overviewAstros Astros AIM Overview
15 * A module in the Computational Aircraft Prototype Syntheses (CAPS) has been developed to interact (primarily
16 * through input files) with the finite element structural solver ASTROS.
17 *
18 * Current issues include:
19 * - A thorough bug testing needs to be undertaken.
20 *
21 * An outline of the AIM's inputs, outputs and attributes are provided in \ref aimInputsAstros and
22 * \ref aimOutputsAstros and \ref attributeAstros, respectively.
23 *
24 * The Astros AIM can automatically execute Astros, with details provided in \ref aimExecuteAstros.
25 *
26 * Details of the AIM's automated data transfer capabilities are outlined in \ref dataTransferAstros
27 *
28 * \section clearanceAstros Clearance Statement
29 * This software has been cleared for public release on 05 Nov 2020, case number 88ABW-2020-3462.
30 *
31 */
32
33
34/*! \page attributeAstros Astros AIM attributes
35 * The following list of attributes are required for the Astros AIM inside the geometry input.
36 *
37 * - <b> capsDiscipline</b> This attribute is a requirement if doing aeroelastic analysis within Astros. capsDiscipline allows
38 * the AIM to determine which bodies are meant for structural analysis and which are used for aerodynamics. Options
39 * are: Structure and Aerodynamic (case insensitive).
40 *
41 * - <b> capsGroup</b> This is a name assigned to any geometric body. This body could be a solid, surface, face, wire, edge or node.
42 * Recall that a string in ESP starts with a $. For example, attribute <c>capsGroup $Wing</c>.
43 *
44 * - <b> capsLoad</b> This is a name assigned to any geometric body where a load is applied. This attribute was separated from the <c>capsGroup</c>
45 * attribute to allow the user to define a local area to apply a load on without adding multiple <c>capsGroup</c> attributes.
46 * Recall that a string in ESP starts with a $. For example, attribute <c>capsLoad $force</c>.
47 *
48 * - <b> capsConstraint</b> This is a name assigned to any geometric body where a constraint/boundary condition is applied.
49 * This attribute was separated from the <c>capsGroup</c> attribute to allow the user to define a local area to apply a boundary condition
50 * without adding multiple <c>capsGroup</c> attributes. Recall that a string in ESP starts with a $. For example, attribute <c>capsConstraint $fixed</c>.
51 *
52 * - <b> capsIgnore</b> It is possible that there is a geometric body (or entity) that you do not want the Astros AIM to pay attention to when creating
53 * a finite element model. The capsIgnore attribute allows a body (or entity) to be in the geometry and ignored by the AIM. For example,
54 * because of limitations in OpenCASCADE a situation where two edges are overlapping may occur; capsIgnore allows the user to only
55 * pay attention to one of the overlapping edges.
56 *
57 * - <b> capsConnect</b> This is a name assigned to any geometric body where the user wishes to create
58 * "fictitious" connections such as springs, dampers, and/or rigid body connections to. The user must manually specify
59 * the connection between two <c>capsConnect</c> entities using the "Connect" tuple (see \ref aimInputsAstros).
60 * Recall that a string in ESP starts with a $. For example, attribute <c>capsConnect $springStart</c>.
61 *
62 * - <b> capsConnectLink</b> Similar to <c>capsConnect</c>, this is a name assigned to any geometric body where
63 * the user wishes to create "fictitious" connections to. A connection is automatically made if a <c>capsConnectLink</c>
64 * matches a <c>capsConnect</c> group. Again, further specifics of the connection are input using the "Connect"
65 * tuple (see \ref aimInputsAstros). Recall that a string in ESP starts with a $.
66 * For example, attribute <c>capsConnectLink $springEnd</c>.
67 *
68 * - <b> capsBound </b> This is used to mark surfaces on the structural grid in which data transfer with an external
69 * solver will take place. See \ref dataTransferAstros for additional details.
70 *
71 * Internal Aeroelastic Analysis
72 *
73 * - <b> capsBound </b> This is used to mark surfaces on the structural grid in which a spline will be created between
74 * the structural and aero-loads.
75 *
76 * - <b> capsReferenceArea</b> [Optional: Default 1.0] Reference area to use when doing aeroelastic analysis.
77 * This attribute may exist on any aerodynamic cross-section.
78 *
79 * - <b> capsReferenceChord</b> [Optional: Default 1.0] Reference chord to use when doing aeroelastic analysis.
80 * This attribute may exist on any aerodynamic cross-section.
81 *
82 * - <b> capsReferenceSpan</b> [Optional: Default 1.0] Reference span to use when doing aeroelastic analysis.
83 * This attribute may exist on any aerodynamic cross-section.
84 *
85 */
86
87#include <string.h>
88#include <math.h>
89#include "capsTypes.h"
90#include "aimUtil.h"
91
92#include "meshUtils.h" // Meshing utilities
93#include "miscUtils.h" // Miscellaneous utilities
94#include "vlmUtils.h" // Vortex lattice method utilities
95#include "vlmSpanSpace.h" // Auto spanwise distribution for vortex lattice
96#include "feaUtils.h" // FEA utilities
97#include "nastranUtils.h" // Nastran utilities
98#include "astrosUtils.h" // Astros utilities
99
100#ifdef WIN32
101#define snprintf _snprintf
102#define strcasecmp stricmp
103#define SLASH'/' '\\'
104#else
105#define SLASH'/' '/'
106#endif
107
108#define MXCHAR255 255
109
110//#define DEBUG
111
112enum aimInputs
113{
114 Proj_Name = 1, /* index is 1-based */
115 Tess_Params,
116 Edge_Point_Min,
117 Edge_Point_Max,
118 Quad_Mesh,
119 Property,
120 Material,
121 Constraint,
122 Load,
123 Analysix,
124 Analysis_Type,
125 File_Format,
126 Mesh_File_Format,
127 Design_Variable,
128 Design_Variable_Relation,
129 Design_Constraint,
130 ObjectiveMinMax,
131 ObjectiveResponseType,
132 VLM_Surface,
133 Support,
134 Connect,
135 Parameter,
136 Mesh,
137 NUMINPUT = Mesh /* Total number of inputs */
138};
139
140enum aimOutputs
141{
142 EigenValue = 1, /* index is 1-based */
143 EigenRadian,
144 EigenFrequency,
145 EigenGeneralMass,
146 EigenGeneralStiffness,
147 Tmax,
148 T1max,
149 T2max,
150 T3max,
151 NUMOUTPUT = T3max /* Total number of outputs */
152};
153
154
155typedef struct {
156
157 // Project name
158 const char *projectName; // Project name
159
160 feaProblemStruct feaProblem;
161
162 feaUnitsStruct units; // units system
163
164 // Attribute to index map
165 mapAttrToIndexStruct attrMap;
166
167 // Attribute to constraint index map
168 mapAttrToIndexStruct constraintMap;
169
170 // Attribute to load index map
171 mapAttrToIndexStruct loadMap;
172
173 // Attribute to transfer map
174 mapAttrToIndexStruct transferMap;
175
176 // Attribute to connect map
177 mapAttrToIndexStruct connectMap;
178
179 // Attribute to response map
180 mapAttrToIndexStruct responseMap;
181
182 // Mesh holders
183 int numMesh;
184 meshStruct *feaMesh;
185
186} aimStorage;
187
188
189static int initiate_aimStorage(aimStorage *astrosInstance)
190{
191
192 int status;
193
194 // Set initial values for astrosInstance
195 astrosInstance->projectName = NULL((void*)0);
196
197 /*
198 // Check to make sure data transfer is ok
199 astrosInstance->dataTransferCheck = (int) true;
200 */
201
202 status = initiate_feaUnitsStruct(&astrosInstance->units);
203 if (status != CAPS_SUCCESS0) return status;
204
205 // Container for attribute to index map
206 status = initiate_mapAttrToIndexStruct(&astrosInstance->attrMap);
207 if (status != CAPS_SUCCESS0) return status;
208
209 // Container for attribute to constraint index map
210 status = initiate_mapAttrToIndexStruct(&astrosInstance->constraintMap);
211 if (status != CAPS_SUCCESS0) return status;
212
213 // Container for attribute to load index map
214 status = initiate_mapAttrToIndexStruct(&astrosInstance->loadMap);
215 if (status != CAPS_SUCCESS0) return status;
216
217 // Container for transfer to index map
218 status = initiate_mapAttrToIndexStruct(&astrosInstance->transferMap);
219 if (status != CAPS_SUCCESS0) return status;
220
221 // Container for connect to index map
222 status = initiate_mapAttrToIndexStruct(&astrosInstance->connectMap);
223 if (status != CAPS_SUCCESS0) return status;
224
225 // Container for response to index map
226 status = initiate_mapAttrToIndexStruct(&astrosInstance->responseMap);
227 if (status != CAPS_SUCCESS0) return status;
228
229 status = initiate_feaProblemStruct(&astrosInstance->feaProblem);
230 if (status != CAPS_SUCCESS0) return status;
231
232 // Mesh holders
233 astrosInstance->numMesh = 0;
234 astrosInstance->feaMesh = NULL((void*)0);
235
236 return CAPS_SUCCESS0;
237}
238
239
240static int destroy_aimStorage(aimStorage *astrosInstance)
241{
242
243 int status;
244 int i;
245
246 status = destroy_feaUnitsStruct(&astrosInstance->units);
247 if (status != CAPS_SUCCESS0)
248 printf("Error: Status %d during destroy_feaUnitsStruct!\n", status);
249
250 // Attribute to index map
251 status = destroy_mapAttrToIndexStruct(&astrosInstance->attrMap);
252 if (status != CAPS_SUCCESS0)
253 printf("Error: Status %d during destroy_mapAttrToIndexStruct!\n", status);
254
255 // Attribute to constraint index map
256 status = destroy_mapAttrToIndexStruct(&astrosInstance->constraintMap);
257 if (status != CAPS_SUCCESS0)
258 printf("Error: Status %d during destroy_mapAttrToIndexStruct!\n", status);
259
260 // Attribute to load index map
261 status = destroy_mapAttrToIndexStruct(&astrosInstance->loadMap);
262 if (status != CAPS_SUCCESS0)
263 printf("Error: Status %d during destroy_mapAttrToIndexStruct!\n", status);
264
265 // Transfer to index map
266 status = destroy_mapAttrToIndexStruct(&astrosInstance->transferMap);
267 if (status != CAPS_SUCCESS0)
268 printf("Error: Status %d during destroy_mapAttrToIndexStruct!\n", status);
269
270 // Connect to index map
271 status = destroy_mapAttrToIndexStruct(&astrosInstance->connectMap);
272 if (status != CAPS_SUCCESS0)
273 printf("Error: Status %d during destroy_mapAttrToIndexStruct!\n", status);
274
275 // Response to index map
276 status = destroy_mapAttrToIndexStruct(&astrosInstance->responseMap);
277 if (status != CAPS_SUCCESS0)
278 printf("Error: Status %d during destroy_mapAttrToIndexStruct!\n", status);
279
280 // Cleanup meshes
281 if (astrosInstance->feaMesh != NULL((void*)0)) {
282
283 for (i = 0; i < astrosInstance->numMesh; i++) {
284 status = destroy_meshStruct(&astrosInstance->feaMesh[i]);
285 if (status != CAPS_SUCCESS0)
286 printf("Error: Status %d during destroy_meshStruct!\n", status);
287 }
288
289 EG_free(astrosInstance->feaMesh);
290 }
291
292 astrosInstance->feaMesh = NULL((void*)0);
293 astrosInstance->numMesh = 0;
294
295 // Destroy FEA problem structure
296 status = destroy_feaProblemStruct(&astrosInstance->feaProblem);
297 if (status != CAPS_SUCCESS0)
298 printf("Error: Status %d during destroy_feaProblemStruct!\n", status);
299
300 // NULL projetName
301 astrosInstance->projectName = NULL((void*)0);
302
303 return CAPS_SUCCESS0;
304}
305
306
307static int checkAndCreateMesh(aimStorage *aimInfo, aimStorage *astrosInstance)
308{
309 // Function return flag
310 int status;
311 int i, remesh = (int)true1;
312
313 // Meshing related variables
314 double tessParam[3] = {0.025, 0.001, 15};
315 int edgePointMin = 2;
316 int edgePointMax = 50;
317 int quadMesh = (int) false0;
318
319 // analysis input values
320 capsValue *TessParams = NULL((void*)0);
321 capsValue *EdgePoint_Min = NULL((void*)0);
322 capsValue *EdgePoint_Max = NULL((void*)0);
323 capsValue *QuadMesh = NULL((void*)0);
324
325 for (i = 0; i < astrosInstance->numMesh; i++) {
326 remesh = remesh && (astrosInstance->feaMesh[i].egadsTess->oclass == EMPTY4);
327 }
328 if (remesh == (int) false0) return CAPS_SUCCESS0;
329
330 // retrieve or create the mesh from fea_createMesh
331 status = aim_getValue(aimInfo, Tess_Params, ANALYSISIN, &TessParams);
332 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
332, __func__, 0); goto cleanup; }
;
333
334 status = aim_getValue(aimInfo, Edge_Point_Min, ANALYSISIN, &EdgePoint_Min);
335 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
335, __func__, 0); goto cleanup; }
;
336
337 status = aim_getValue(aimInfo, Edge_Point_Max, ANALYSISIN, &EdgePoint_Max);
338 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
338, __func__, 0); goto cleanup; }
;
339
340 status = aim_getValue(aimInfo, Quad_Mesh, ANALYSISIN, &QuadMesh);
341 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
341, __func__, 0); goto cleanup; }
;
342
343 if (TessParams != NULL((void*)0)) {
344 tessParam[0] = TessParams->vals.reals[0]; // Gets multiplied by bounding box size
345 tessParam[1] = TessParams->vals.reals[1]; // Gets multiplied by bounding box size
346 tessParam[2] = TessParams->vals.reals[2];
347 }
348
349 // Max and min number of points
350 if (EdgePoint_Min != NULL((void*)0) && EdgePoint_Min->nullVal != IsNull) {
351 edgePointMin = EdgePoint_Min->vals.integer;
352 if (edgePointMin < 2) {
353 AIM_ANALYSISIN_ERROR(aimInfo, Edge_Point_Min, "Edge_Point_Min = %d must be greater or equal to 2\n", edgePointMin){ aim_message(aimInfo, CERROR, Edge_Point_Min, "astrosAIM.c",
353, __func__, "Edge_Point_Min = %d must be greater or equal to 2\n"
, edgePointMin); }
;
354 return CAPS_BADVALUE-311;
355 }
356 }
357
358 if (EdgePoint_Max != NULL((void*)0) && EdgePoint_Max->nullVal != IsNull) {
359 edgePointMax = EdgePoint_Max->vals.integer;
360 if (edgePointMax < 2) {
361 AIM_ANALYSISIN_ERROR(aimInfo, Edge_Point_Max, "Edge_Point_Max = %d must be greater or equal to 2\n", edgePointMax){ aim_message(aimInfo, CERROR, Edge_Point_Max, "astrosAIM.c",
361, __func__, "Edge_Point_Max = %d must be greater or equal to 2\n"
, edgePointMax); }
;
362 return CAPS_BADVALUE-311;
363 }
364 }
365
366 if (edgePointMin >= 2 && edgePointMax >= 2 && edgePointMin > edgePointMax) {
367 AIM_ERROR (aimInfo, "Edge_Point_Max must be greater or equal Edge_Point_Min"){ aim_message(aimInfo, CERROR, 0 , "astrosAIM.c", 367, __func__
, "Edge_Point_Max must be greater or equal Edge_Point_Min"); }
;
368 AIM_ADDLINE(aimInfo, "Edge_Point_Max = %d, Edge_Point_Min = %d\n",edgePointMax,edgePointMin){ aim_addLine(aimInfo, "Edge_Point_Max = %d, Edge_Point_Min = %d\n"
,edgePointMax,edgePointMin); }
;
369 return CAPS_BADVALUE-311;
370 }
371
372 if (QuadMesh != NULL((void*)0)) quadMesh = QuadMesh->vals.integer;
373
374 status = fea_createMesh(aimInfo,
375 tessParam,
376 edgePointMin,
377 edgePointMax,
378 quadMesh,
379 &astrosInstance->attrMap,
380 &astrosInstance->constraintMap,
381 &astrosInstance->loadMap,
382 &astrosInstance->transferMap,
383 &astrosInstance->connectMap,
384 &astrosInstance->responseMap,
385 &astrosInstance->numMesh,
386 &astrosInstance->feaMesh,
387 &astrosInstance->feaProblem );
388 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
388, __func__, 0); goto cleanup; }
;
389
390 status = CAPS_SUCCESS0;
391cleanup:
392 return status;
393}
394
395
396static int _combineVLM(char *type, int numfeaAero, feaAeroStruct feaAero[],
397 int combineID, feaAeroStruct *combine)
398{
399
400 int status;
401
402 int i, j, k;
403 int sectionIndex;
404 int found = (int) false0, skip;
405
406 vlmSectionStruct *tempSection;
407
408 for (i=0; i < numfeaAero; i++) {
409 if (strcasecmp(feaAero[i].vlmSurface.surfaceType, type) == 0) break;
410 }
411
412 if (i >= numfeaAero) {
413 printf("SurfaceType, %s, not found!\n", type);
414 status = CAPS_NOTFOUND-303;
415 goto cleanup;
416 }
417
418 combine->name = EG_strdup(feaAero[i].name);
419 if (combine->name == NULL((void*)0)) {
420 status = EGADS_MALLOC-4;
421 goto cleanup;
422 }
423 combine->vlmSurface.surfaceType = EG_strdup(feaAero[i].vlmSurface.surfaceType);
424 if (combine->vlmSurface.surfaceType == NULL((void*)0)) {
425 status = EGADS_MALLOC-4;
426 goto cleanup;
427 }
428
429 combine->surfaceID = combineID;
430
431 // ADD something for coordinate systems
432
433 // Populate vmlSurface structure
434 sectionIndex = 0;
435 for (i = 0; i < numfeaAero; i++) {
436
437 if (strcasecmp(feaAero[i].vlmSurface.surfaceType, type) != 0) continue;
438
439 if (found == (int) false0) {
440 combine->vlmSurface.Cspace = feaAero[i].vlmSurface.Cspace;
441 combine->vlmSurface.Sspace = feaAero[i].vlmSurface.Sspace;
442 combine->vlmSurface.Nchord = 0;
443 combine->vlmSurface.NspanTotal = 0;
444 found = (int) true1;
445 }
446
447 if (combine->vlmSurface.Nchord < feaAero[i].vlmSurface.Nchord) {
448 combine->vlmSurface.Nchord = feaAero[i].vlmSurface.Nchord;
449 }
450
451 combine->vlmSurface.NspanTotal += feaAero[i].vlmSurface.NspanTotal;
452
453 // Get grids
454 combine->numGridID += feaAero[i].numGridID;
455 combine->gridIDSet = (int *) EG_reall(combine->gridIDSet,
456 combine->numGridID*sizeof(int));
457 if (combine->gridIDSet == NULL((void*)0)) {
458 status = EGADS_MALLOC-4;
459 goto cleanup;
460 }
461
462 memcpy(&combine->gridIDSet[combine->numGridID -feaAero[i].numGridID],
463 feaAero[i].gridIDSet,
464 feaAero[i].numGridID*sizeof(int));
465
466 // Copy section information
467 for (j = 0; j < feaAero[i].vlmSurface.numSection; j++) {
468
469 skip = (int) false0;
470 for (k = 0; k < combine->vlmSurface.numSection; k++) {
471
472 // Check geometry
473 status = EG_isEquivalent(combine->vlmSurface.vlmSection[k].ebody,
474 feaAero[i].vlmSurface.vlmSection[j].ebody);
475 if (status == EGADS_SUCCESS0) {
476 skip = (int) true1;
477 break;
478 }
479
480 // Check geometry
481 status = EG_isSame(combine->vlmSurface.vlmSection[k].ebody,
482 feaAero[i].vlmSurface.vlmSection[j].ebody);
483 if (status == EGADS_SUCCESS0) {
484 skip = (int) true1;
485 break;
486 }
487 }
488
489 if (skip == (int) true1) continue;
490
491 combine->vlmSurface.numSection += 1;
492
493 tempSection = (vlmSectionStruct *) EG_reall(combine->vlmSurface.vlmSection,
494 combine->vlmSurface.numSection*sizeof(vlmSectionStruct));
495
496 if (tempSection == NULL((void*)0)) {
497 combine->vlmSurface.numSection -= 1;
498 status = EGADS_MALLOC-4;
499 goto cleanup;
500 }
501
502 combine->vlmSurface.vlmSection = tempSection;
503
504 status = initiate_vlmSectionStruct(&combine->vlmSurface.vlmSection[sectionIndex]);
505 if (status != CAPS_SUCCESS0) {
506 combine->vlmSurface.numSection -= 1;
507 goto cleanup;
508 }
509
510 // Copy the section data - This also copies the control data for the section
511 status = copy_vlmSectionStruct( &feaAero[i].vlmSurface.vlmSection[j],
512 &combine->vlmSurface.vlmSection[sectionIndex]);
513 if (status != CAPS_SUCCESS0) goto cleanup;
514
515 // Reset the sectionIndex that is keeping track of the section order.
516 combine->vlmSurface.vlmSection[sectionIndex].sectionIndex = sectionIndex;
517
518 sectionIndex += 1;
519 }
520 }
521
522 // Order cross sections for the surface - just in case
523 status = vlm_orderSections(combine->vlmSurface.numSection, combine->vlmSurface.vlmSection);
524 if (status != CAPS_SUCCESS0) goto cleanup;
525
526 status = CAPS_SUCCESS0;
527
528cleanup:
529
530 if (status != CAPS_SUCCESS0)
531 printf("\tPremature exit in _combineVLM, status = %d\n", status);
532 return status;
533 }
534
535
536static int createVLMMesh(void *instStore, void *aimInfo, capsValue *aimInputs)
537{
538
539 int projectionMethod = (int) true1;
540
541 int status, status2; // Function return status
542
543 int i, j, k, surfaceIndex = 0, sectionIndex, transferIndex; // Indexing
544
545 char *analysisType = NULL((void*)0);
546 aimStorage *astrosInstance;
547
548 // Bodies
549 const char *intents;
550 int numBody; // Number of Bodies
551 ego *bodies;
552
553 // Aeroelastic information
554 int numVLMSurface = 0;
555 vlmSurfaceStruct *vlmSurface = NULL((void*)0);
556 int numSpanWise = 0;
557
558 int wingCheck = (int) false0, finCheck = (int) false0, canardCheck = (int) false0;
559 int feaAeroTempCombineCount = 0, type=-1;
560 feaAeroStruct *feaAeroTemp = NULL((void*)0), *feaAeroTempCombine = NULL((void*)0);
561
562 // Vector variables
563 double A[3], B[3], C[3], D[3], P[3], p[3], N[3], n[3], d_proj[3];
564
565 double *a, *b, *c, *d;
566 double apbArea, apcArea, cpdArea, bpdArea, Area;
567
568 feaMeshDataStruct *feaData;
569
570 astrosInstance = (aimStorage *) instStore;
571
572 // Get AIM bodies
573 status = aim_getBodies(aimInfo, &intents, &numBody, &bodies);
574 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
574, __func__, 0); goto cleanup; }
;
575
576#ifdef DEBUG
577 printf(" astrosAIM/createVLMMesh nbody = %d!\n", numBody);
578#endif
579
580 if ((numBody <= 0) || (bodies == NULL((void*)0))) {
581#ifdef DEBUG
582 printf(" astrosAIM/createVLMMesh No Bodies!\n");
583#endif
584 return CAPS_SOURCEERR-330;
585 }
586
587 // Analysis type
588 analysisType = aimInputs[Analysis_Type-1].vals.string;
589
590 // Get aerodynamic reference quantities
591 status = fea_retrieveAeroRef(numBody, bodies, &astrosInstance->feaProblem.feaAeroRef);
592 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
592, __func__, 0); goto cleanup; }
;
593
594 // Cleanup Aero storage first
595 if (astrosInstance->feaProblem.feaAero != NULL((void*)0)) {
596
597 for (i = 0; i < astrosInstance->feaProblem.numAero; i++) {
598 status = destroy_feaAeroStruct(&astrosInstance->feaProblem.feaAero[i]);
599 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
599, __func__, 0); goto cleanup; }
;
600 }
601
602 AIM_FREE(astrosInstance->feaProblem.feaAero){ EG_free(astrosInstance->feaProblem.feaAero); astrosInstance
->feaProblem.feaAero = ((void*)0); }
;
603 }
604
605 astrosInstance->feaProblem.numAero = 0;
606
607 // Get AVL surface information
608 if (aimInputs[VLM_Surface-1].nullVal != IsNull) {
609
610 status = get_vlmSurface(aimInputs[VLM_Surface-1].length,
611 aimInputs[VLM_Surface-1].vals.tuple,
612 &astrosInstance->attrMap,
613 0.0, // default Cspace
614 &numVLMSurface,
615 &vlmSurface);
616 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
616, __func__, 0); goto cleanup; }
;
617
618 } else {
619 AIM_ERROR(aimInfo, "An analysis type of Aeroelastic set but no VLM_Surface tuple specified"){ aim_message(aimInfo, CERROR, 0 , "astrosAIM.c", 619, __func__
, "An analysis type of Aeroelastic set but no VLM_Surface tuple specified"
); }
;
620 status = CAPS_NOTFOUND-303;
621 goto cleanup;
622 }
623
624 printf("\nGetting FEA vortex lattice mesh\n");
625
626 status = vlm_getSections(aimInfo,
627 numBody,
628 bodies,
629 "Aerodynamic",
630 astrosInstance->attrMap,
631 vlmPLANEYZ,
632 numVLMSurface,
633 &vlmSurface);
634 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
634, __func__, 0); goto cleanup; }
;
635 AIM_NOTNULL(vlmSurface, aimInfo, status){ if (vlmSurface == ((void*)0)) { status = -307; aim_status(aimInfo
, status, "astrosAIM.c", 635, __func__, 1, "%s == NULL!", "vlmSurface"
); goto cleanup; } }
;
636
637 for (i = 0; i < numVLMSurface; i++) {
638
639 // Compute auto spacing
640 if (vlmSurface[i].NspanTotal > 0)
641 numSpanWise = vlmSurface[i].NspanTotal;
642 else if (vlmSurface[i].NspanSection > 0)
643 numSpanWise = (vlmSurface[i].numSection-1)*vlmSurface[i].NspanSection;
644 else {
645 AIM_ERROR(aimInfo , "Only one of numSpanTotal and numSpanPerSection can be non-zero!"){ aim_message(aimInfo, CERROR, 0 , "astrosAIM.c", 645, __func__
, "Only one of numSpanTotal and numSpanPerSection can be non-zero!"
); }
;
646 AIM_ADDLINE(aimInfo, " numSpanTotal = %d", vlmSurface[i].NspanTotal){ aim_addLine(aimInfo, " numSpanTotal = %d", vlmSurface
[i].NspanTotal); }
;
647 AIM_ADDLINE(aimInfo, " numSpanPerSection = %d", vlmSurface[i].NspanSection){ aim_addLine(aimInfo, " numSpanPerSection = %d", vlmSurface
[i].NspanSection); }
;
648 status = CAPS_BADVALUE-311;
649 goto cleanup;
650 }
651
652 status = vlm_equalSpaceSpanPanels(aimInfo, numSpanWise,
653 vlmSurface[i].numSection,
654 vlmSurface[i].vlmSection);
655 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
655, __func__, 0); goto cleanup; }
;
656 }
657
658 // Split the surfaces that have more than 2 sections into a new surface
659 for (i = 0; i < numVLMSurface; i++) {
660
661 if (vlmSurface->numSection < 2) {
662 AIM_ERROR(aimInfo, "Surface '%s' has less than two-sections!", vlmSurface[i].name){ aim_message(aimInfo, CERROR, 0 , "astrosAIM.c", 662, __func__
, "Surface '%s' has less than two-sections!", vlmSurface[i].name
); }
;
663 status = CAPS_BADVALUE-311;
664 goto cleanup;
665 }
666
667 status = get_mapAttrToIndexIndex(&astrosInstance->transferMap,
668 vlmSurface[i].name,
669 &transferIndex);
670 if (status == CAPS_NOTFOUND-303) {
671 printf("\tA corresponding capsBound name not found for \"%s\". Surface will be ignored!\n",
672 vlmSurface[i].name);
673 continue;
674 }
675 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
675, __func__, 0); goto cleanup; }
;
676
677 for (j = 0; j < vlmSurface[i].numSection-1; j++) {
678
679 // Increment the number of Aero surfaces
680 astrosInstance->feaProblem.numAero += 1;
681
682 surfaceIndex = astrosInstance->feaProblem.numAero - 1;
683
684 // Allocate
685 feaAeroTemp = (feaAeroStruct *) EG_reall(astrosInstance->feaProblem.feaAero,
686 astrosInstance->feaProblem.numAero*sizeof(feaAeroStruct));
687
688
689 if (feaAeroTemp == NULL((void*)0)) {
690 astrosInstance->feaProblem.numAero -= 1;
691
692 status = EGADS_MALLOC-4;
693 goto cleanup;
694 }
695
696 astrosInstance->feaProblem.feaAero = feaAeroTemp;
697
698 // Initiate feaAeroStruct
699 status = initiate_feaAeroStruct(&astrosInstance->feaProblem.feaAero[surfaceIndex]);
700 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
700, __func__, 0); goto cleanup; }
;
701
702 // Get surface Name - copy from original surface
703 AIM_STRDUP(astrosInstance->feaProblem.feaAero[surfaceIndex].name, vlmSurface[i].name, aimInfo, status){ if (astrosInstance->feaProblem.feaAero[surfaceIndex].name
!= ((void*)0)) { status = -4; aim_status(aimInfo, status, "astrosAIM.c"
, 703, __func__, 1, "AIM_STRDUP: %s != NULL!", "astrosInstance->feaProblem.feaAero[surfaceIndex].name"
); goto cleanup; } astrosInstance->feaProblem.feaAero[surfaceIndex
].name = EG_strdup(vlmSurface[i].name); if (astrosInstance->
feaProblem.feaAero[surfaceIndex].name == ((void*)0)) { status
= -4; aim_status(aimInfo, status, "astrosAIM.c", 703, __func__
, 2, "AIM_STRDUP: %s %s", "astrosInstance->feaProblem.feaAero[surfaceIndex].name"
, vlmSurface[i].name); goto cleanup; } }
;
704
705 // Get surface ID - Multiple by 1000 !!
706 astrosInstance->feaProblem.feaAero[surfaceIndex].surfaceID =
707 1000*astrosInstance->feaProblem.numAero;
708
709 // ADD something for coordinate systems
710
711 // Sections aren't necessarily stored in order coming out of vlm_getSections, however sectionIndex is!
712 sectionIndex = vlmSurface[i].vlmSection[j].sectionIndex;
713
714 // Populate vmlSurface structure
715 astrosInstance->feaProblem.feaAero[surfaceIndex].vlmSurface.Cspace = vlmSurface[i].Cspace;
716 astrosInstance->feaProblem.feaAero[surfaceIndex].vlmSurface.Sspace = vlmSurface[i].Sspace;
717
718 // use the section span count for the sub-surface
719 astrosInstance->feaProblem.feaAero[surfaceIndex].vlmSurface.NspanTotal = vlmSurface[i].vlmSection[sectionIndex].Nspan;
720 astrosInstance->feaProblem.feaAero[surfaceIndex].vlmSurface.Nchord = vlmSurface[i].Nchord;
721
722 // Copy surface type
723 astrosInstance->feaProblem.feaAero[surfaceIndex].vlmSurface.surfaceType = EG_strdup(vlmSurface[i].surfaceType);
724
725 // Copy section information
726 astrosInstance->feaProblem.feaAero[surfaceIndex].vlmSurface.numSection = 2;
727
728 astrosInstance->feaProblem.feaAero[surfaceIndex].vlmSurface.vlmSection = (vlmSectionStruct *) EG_alloc(2*sizeof(vlmSectionStruct));
729 if (astrosInstance->feaProblem.feaAero[surfaceIndex].vlmSurface.vlmSection == NULL((void*)0)) {
730 status = EGADS_MALLOC-4;
731 goto cleanup;
732 }
733
734 for (k = 0; k < astrosInstance->feaProblem.feaAero[surfaceIndex].vlmSurface.numSection; k++) {
735
736 // Add k to section indexing variable j to get j and j+1 during iterations
737
738 // Sections aren't necessarily stored in order coming out of vlm_getSections, however sectionIndex is!
739 sectionIndex = vlmSurface[i].vlmSection[j+k].sectionIndex;
740
741 status = initiate_vlmSectionStruct(&astrosInstance->feaProblem.feaAero[surfaceIndex].vlmSurface.vlmSection[k]);
742 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
742, __func__, 0); goto cleanup; }
;
743
744 // Copy the section data - This also copies the control data for the section
745 status = copy_vlmSectionStruct( &vlmSurface[i].vlmSection[sectionIndex],
746 &astrosInstance->feaProblem.feaAero[surfaceIndex].vlmSurface.vlmSection[k]);
747 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
747, __func__, 0); goto cleanup; }
;
748
749 // Reset the sectionIndex that is keeping track of the section order.
750 astrosInstance->feaProblem.feaAero[surfaceIndex].vlmSurface.vlmSection[k].sectionIndex = k;
751 }
752 }
753 }
754
755 // Determine which grid points are to be used for each spline
756 for (i = 0; i < astrosInstance->feaProblem.numAero; i++) {
757
758 // Debug
759 //printf("\tDetermining grid points\n");
760
761 // Get the transfer index for this surface - it has already been checked to make sure the name is in the
762 // transfer index map
763 AIM_NOTNULL(astrosInstance->feaProblem.feaAero, aimInfo, status){ if (astrosInstance->feaProblem.feaAero == ((void*)0)) { status
= -307; aim_status(aimInfo, status, "astrosAIM.c", 763, __func__
, 1, "%s == NULL!", "astrosInstance->feaProblem.feaAero");
goto cleanup; } }
;
764 status = get_mapAttrToIndexIndex(&astrosInstance->transferMap,
765 astrosInstance->feaProblem.feaAero[i].name,
766 &transferIndex);
767 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
767, __func__, 0); goto cleanup; }
;
768
769 if (projectionMethod == (int) false0) { // Look for attributes
770
771 for (j = 0; j < astrosInstance->feaProblem.feaMesh.numNode; j++) {
772
773 if (astrosInstance->feaProblem.feaMesh.node[j].analysisType == MeshStructure) {
774 feaData = (feaMeshDataStruct *) astrosInstance->feaProblem.feaMesh.node[j].analysisData;
775 } else {
776 continue;
777 }
778
779 if (feaData->transferIndex != transferIndex) continue;
780 if (feaData->transferIndex == CAPSMAGIC1234321) continue;
781
782
783 astrosInstance->feaProblem.feaAero[i].numGridID += 1;
784 k = astrosInstance->feaProblem.feaAero[i].numGridID;
785
786 astrosInstance->feaProblem.feaAero[i].gridIDSet = (int *)
787 EG_reall(astrosInstance->feaProblem.feaAero[i].gridIDSet,
788 k*sizeof(int));
789
790 if (astrosInstance->feaProblem.feaAero[i].gridIDSet == NULL((void*)0)) {
791 status = EGADS_MALLOC-4;
792 goto cleanup;
793 }
794
795 astrosInstance->feaProblem.feaAero[i].gridIDSet[k-1] =
796 astrosInstance->feaProblem.feaMesh.node[j].nodeID;
797 }
798
799 } else { // Projection method
800
801
802 /*
803 * n = A X B Create a normal vector/ plane between A and B
804 *
805 * d_proj = C - (C * n)*n/ ||n||^2 , projection of point d on plane created by AxB
806 *
807 * p = D - (D * n)*n/ ||n||^2 , projection of point p on plane created by AxB
808 *
809 * (section 2)
810 * LE(c)---------------->TE(d)
811 * Grid Point -^ ^ -|
812 * |^ - - - |
813 * | - A - C - d_proj
814 * | D - - -
815 * | - - - (section 1 -
816 * p LE(a)----------B------->TE(b)
817 */
818
819 // Vector between section 2 and 1
820 a = astrosInstance->feaProblem.feaAero[i].vlmSurface.vlmSection[0].xyzLE;
821 b = astrosInstance->feaProblem.feaAero[i].vlmSurface.vlmSection[0].xyzTE;
822 c = astrosInstance->feaProblem.feaAero[i].vlmSurface.vlmSection[1].xyzLE;
823 d = astrosInstance->feaProblem.feaAero[i].vlmSurface.vlmSection[1].xyzTE;
824
825 // Debug
826 //printf("a = %f %f %f\n", a[0], a[1], a[2]);
827 //printf("b = %f %f %f\n", b[0], b[1], b[2]);
828 //printf("c = %f %f %f\n", c[0], c[1], c[2]);
829 //printf("d = %f %f %f\n", d[0], d[1], d[2]);
830
831 // Vector between LE of section 1 and LE of section 2
832 A[0] = c[0] - a[0];
833 A[1] = c[1] - a[1];
834 A[2] = c[2] - a[2];
835
836 // Vector between LE and TE of section 1
837 B[0] = b[0] - a[0];
838 B[1] = b[1] - a[1];
839 B[2] = b[2] - a[2];
840
841 // Vector between LE of section 1 and TE of section 2
842 C[0] = d[0] - a[0];
843 C[1] = d[1] - a[1];
844 C[2] = d[2] - a[2];
845
846 // Normal vector between A and B
847 cross_DoubleVal(A, B, N);
848
849 // Normalize normal vector
850 n[0] = N[0]/sqrt(dot_DoubleVal(N, N));
851 n[1] = N[1]/sqrt(dot_DoubleVal(N, N));
852 n[2] = N[2]/sqrt(dot_DoubleVal(N, N));
853
854 //printf("n = %f %f %f\n", n[0], n[1], n[2]);
855
856 // Projection of vector C on plane created by AxB
857 d_proj[0] = C[0] - dot_DoubleVal(C, n)*n[0] + a[0];
858 d_proj[1] = C[1] - dot_DoubleVal(C, n)*n[1] + a[1];
859 d_proj[2] = C[2] - dot_DoubleVal(C, n)*n[2] + a[2];
860
861 //printf("d_proj = %f %f %f\n", d_proj[0], d_proj[1], d_proj[2]);
862
863 // Vector between LE of section 1 and TE of section 2 where the TE as been projected on A x B plane
864 C[0] = d_proj[0] - a[0];
865 C[1] = d_proj[1] - a[1];
866 C[2] = d_proj[2] - a[2];
867
868 // Area of the rectangle (first triangle)
869 cross_DoubleVal(A, C, N);
870 Area = 0.5*sqrt(N[0]*N[0] + N[1]*N[1] + N[2]*N[2]);
871
872 // Area of the rectangle (second triangle)
873 cross_DoubleVal(C, B, N);
874 Area = 0.5*sqrt(N[0]*N[0] + N[1]*N[1] + N[2]*N[2]) + Area;
875
876 // Debug
877 //printf("\tArea = %f\n",Area);
878
879 for (j = 0; j < astrosInstance->feaProblem.feaMesh.numNode; j++) {
880
881 if (astrosInstance->feaProblem.feaMesh.node[j].analysisType == MeshStructure) {
882 feaData = (feaMeshDataStruct *) astrosInstance->feaProblem.feaMesh.node[j].analysisData;
883 } else {
884 continue;
885 }
886
887 if (feaData->transferIndex != transferIndex) continue;
888 if (feaData->transferIndex == CAPSMAGIC1234321) continue;
889
890 D[0] = astrosInstance->feaProblem.feaMesh.node[j].xyz[0] - a[0];
891
892 D[1] = astrosInstance->feaProblem.feaMesh.node[j].xyz[1] - a[1];
893
894 D[2] = astrosInstance->feaProblem.feaMesh.node[j].xyz[2] - a[2];
895
896 // Projection of vector D on plane created by AxB
897 p[0] = D[0] - dot_DoubleVal(D, n)*n[0] + a[0];
898 p[1] = D[1] - dot_DoubleVal(D, n)*n[1] + a[1];
899 p[2] = D[2] - dot_DoubleVal(D, n)*n[2] + a[2];
900
901 // First triangle
902 A[0] = a[0] - p[0];
903 A[1] = a[1] - p[1];
904 A[2] = a[2] - p[2];
905
906 B[0] = b[0] - p[0];
907 B[1] = b[1] - p[1];
908 B[2] = b[2] - p[2];
909 cross_DoubleVal(A, B, P);
910 apbArea = 0.5*sqrt(P[0]*P[0] + P[1]*P[1] + P[2]*P[2]);
911
912 // Second triangle
913 A[0] = a[0] - p[0];
914 A[1] = a[1] - p[1];
915 A[2] = a[2] - p[2];
916
917 B[0] = c[0] - p[0];
918 B[1] = c[1] - p[1];
919 B[2] = c[2] - p[2];
920 cross_DoubleVal(A, B, P);
921 apcArea = 0.5*sqrt(P[0]*P[0] + P[1]*P[1] + P[2]*P[2]);
922
923 // Third triangle
924 A[0] = c[0] - p[0];
925 A[1] = c[1] - p[1];
926 A[2] = c[2] - p[2];
927
928 B[0] = d_proj[0] - p[0];
929 B[1] = d_proj[1] - p[1];
930 B[2] = d_proj[2] - p[2];
931 cross_DoubleVal(A, B, P);
932 cpdArea = 0.5*sqrt(P[0]*P[0] + P[1]*P[1] + P[2]*P[2]);
933
934 // Fourth triangle
935 A[0] = b[0] - p[0];
936 A[1] = b[1] - p[1];
937 A[2] = b[2] - p[2];
938
939 B[0] = d_proj[0] - p[0];
940 B[1] = d_proj[1] - p[1];
941 B[2] = d_proj[2] - p[2];
942 cross_DoubleVal(A, B, P);
943 bpdArea = 0.5*sqrt(P[0]*P[0] + P[1]*P[1] + P[2]*P[2]);
944
945 // Debug
946 //printf("Area of Triangle = %f\n", (apbArea + apcArea + cpdArea + bpdArea));
947 //if (fabs(apbArea + apcArea + cpdArea + bpdArea - Area) > 1E-5) {
948 // printf("Point index %d\n", j);
949 // printf("\tAreas don't match - %f vs %f!!\n", Area, (apbArea + apcArea + cpdArea + bpdArea));
950 // printf("\tPoint - %f %f %f\n", D[0] + a[0], D[1] + a[1], D[2] + a[2]);
951 // printf("\tPoint projection - %f %f %f\n", p[0], p[1], p[2]);
952 //}
953
954 if (fabs(apbArea + apcArea + cpdArea + bpdArea - Area) > 1E-5) continue;
955
956 astrosInstance->feaProblem.feaAero[i].numGridID += 1;
957
958 if (astrosInstance->feaProblem.feaAero[i].numGridID == 1) {
959 astrosInstance->feaProblem.feaAero[i].gridIDSet = (int *)
960 EG_alloc(astrosInstance->feaProblem.feaAero[i].numGridID*sizeof(int));
961 } else {
962 astrosInstance->feaProblem.feaAero[i].gridIDSet = (int *)
963 EG_reall(astrosInstance->feaProblem.feaAero[i].gridIDSet,
964 astrosInstance->feaProblem.feaAero[i].numGridID*sizeof(int));
965 }
966
967 if (astrosInstance->feaProblem.feaAero[i].gridIDSet == NULL((void*)0)) {
968 status = EGADS_MALLOC-4;
969 goto cleanup;
970 }
971
972 astrosInstance->feaProblem.feaAero[i].gridIDSet[
973 astrosInstance->feaProblem.feaAero[i].numGridID-1] =
974 astrosInstance->feaProblem.feaMesh.node[j].nodeID;
975 }
976 }
977
978 if (astrosInstance->feaProblem.feaAero[i].numGridID > 0) {
979 printf("\tSurface %d: Number of points found for aero-spline = %d\n",
980 i+1, astrosInstance->feaProblem.feaAero[i].numGridID );
981 }
982 else {
983 AIM_ERROR(aimInfo, "No points found for aero-spline for surface %d", i+1){ aim_message(aimInfo, CERROR, 0 , "astrosAIM.c", 983, __func__
, "No points found for aero-spline for surface %d", i+1); }
;
984 status = CAPS_NOTFOUND-303;
985 goto cleanup;
986 }
987 }
988
989 // Need to combine all aero surfaces into one for static, opt and trim analysis
990 if (strcasecmp(analysisType, "Aeroelastic") == 0 ||
991 strcasecmp(analysisType, "AeroelasticTrim") == 0 ||
992 strcasecmp(analysisType, "AeroelasticTrimOpt") == 0 ) {
993
994 printf("\t(Re-)Combining all aerodynamic surfaces into a 'Wing', 'Canard', and/or 'Fin' single surfaces !\n");
995
996 if (astrosInstance->feaProblem.feaAero == NULL((void*)0)) {
997 status = CAPS_NULLVALUE-307;
998 goto cleanup;
999 }
1000
1001 for (i = 0; i < astrosInstance->feaProblem.numAero; i++) {
1002 if (astrosInstance->feaProblem.feaAero[i].vlmSurface.surfaceType == NULL((void*)0)){
1003 printf("DEVELOPER ERROR: no surfaceType set (surfcae index %d)!\n", i);
1004 status = CAPS_BADVALUE-311;
1005 goto cleanup;
1006 }
1007// printf("Surface Type = |%s|\n",
1008// astrosInstance->feaProblem.feaAero[i].vlmSurface.surfaceType);
1009
1010 if (wingCheck == (int) false0 &&
1011 strcasecmp(astrosInstance->feaProblem.feaAero[i].vlmSurface.surfaceType,
1012 "Wing") == 0) {
1013 type = 0;
1014 wingCheck = (int) true1;
1015 } else if (canardCheck == (int) false0 &&
1016 strcasecmp(astrosInstance->feaProblem.feaAero[i].vlmSurface.surfaceType,
1017 "Canard") == 0) {
1018 type = 1;
1019 canardCheck = (int) true1;
1020 } else if (finCheck == (int) false0 &&
1021 strcasecmp(astrosInstance->feaProblem.feaAero[i].vlmSurface.surfaceType,
1022 "Fin") == 0) {
1023 type = 2;
1024 finCheck = (int) true1;
1025 } else {
1026// printf("Skipping, surface %d, %d %d %d, %d %d %d\n", i, wingCheck, canardCheck, finCheck,
1027// strcasecmp(astrosInstance->feaProblem.feaAero[i].vlmSurface.surfaceType, "Wing"),
1028// strcasecmp(astrosInstance->feaProblem.feaAero[i].vlmSurface.surfaceType, "Canard"),
1029// strcasecmp(astrosInstance->feaProblem.feaAero[i].vlmSurface.surfaceType, "Fin"));
1030 continue;
1031 }
1032
1033 feaAeroTemp = (feaAeroStruct *) EG_reall(feaAeroTempCombine,
1034 (feaAeroTempCombineCount+1)*
1035 sizeof(feaAeroStruct));
1036 if (feaAeroTemp == NULL((void*)0)) {
1037 status = EGADS_MALLOC-4;
1038 goto cleanup;
1039 }
1040
1041 feaAeroTempCombine = feaAeroTemp;
1042
1043 status = initiate_feaAeroStruct(&feaAeroTempCombine[feaAeroTempCombineCount]);
1044 if (status != CAPS_SUCCESS0) goto cleanup;
1045
1046// printf("TYPE %d\n", type);
1047
1048 switch (type) {
1049 case 0:
1050 status = _combineVLM("Wing",
1051 astrosInstance->feaProblem.numAero,
1052 astrosInstance->feaProblem.feaAero,
1053 1000*(feaAeroTempCombineCount+1),
1054 &feaAeroTempCombine[feaAeroTempCombineCount]);
1055 if (status != CAPS_SUCCESS0) goto cleanup;
1056 break;
1057 case 1:
1058 status = _combineVLM("Canard",
1059 astrosInstance->feaProblem.numAero,
1060 astrosInstance->feaProblem.feaAero,
1061 1000*(feaAeroTempCombineCount+1),
1062 &feaAeroTempCombine[feaAeroTempCombineCount]);
1063 if (status != CAPS_SUCCESS0) goto cleanup;
1064 break;
1065
1066 case 2:
1067 status = _combineVLM("Fin",
1068 astrosInstance->feaProblem.numAero,
1069 astrosInstance->feaProblem.feaAero,
1070 1000*(feaAeroTempCombineCount+1),
1071 &feaAeroTempCombine[feaAeroTempCombineCount]);
1072 if (status != CAPS_SUCCESS0) goto cleanup;
1073 break;
1074 }
1075
1076 feaAeroTempCombineCount += 1;
1077 }
1078
1079 // Free old feaProblem Aero
1080 if (astrosInstance->feaProblem.feaAero != NULL((void*)0)) {
1081
1082 for (i = 0; i < astrosInstance->feaProblem.numAero; i++) {
1083 status = destroy_feaAeroStruct(&astrosInstance->feaProblem.feaAero[i]);
1084 if (status != CAPS_SUCCESS0)
1085 printf("Status %d during destroy_feaAeroStruct\n", status);
1086 }
1087 }
1088
1089 if (astrosInstance->feaProblem.feaAero != NULL((void*)0))
1090 EG_free(astrosInstance->feaProblem.feaAero);
1091 astrosInstance->feaProblem.feaAero = NULL((void*)0);
1092 astrosInstance->feaProblem.numAero = 0;
1093
1094 // Point to new data
1095 astrosInstance->feaProblem.numAero = feaAeroTempCombineCount;
1096 astrosInstance->feaProblem.feaAero = feaAeroTempCombine;
1097 }
1098
1099 status = CAPS_SUCCESS0;
1100
1101cleanup:
1102
1103 if (status != CAPS_SUCCESS0)
1104 printf("\tPremature exit in createVLMMesh, status = %d\n", status);
1105
1106 if (status != CAPS_SUCCESS0 && feaAeroTempCombine != NULL((void*)0)) {
1107
1108 for (i = 0; i < feaAeroTempCombineCount+1; i++) {
1109 (void) destroy_feaAeroStruct(&feaAeroTempCombine[i]);
1110 }
1111/*@-kepttrans@*/
1112 EG_free(feaAeroTempCombine);
1113/*@+kepttrans@*/
1114 }
1115
1116 if (vlmSurface != NULL((void*)0)) {
1117
1118 for (i = 0; i < numVLMSurface; i++) {
1119 status2 = destroy_vlmSurfaceStruct(&vlmSurface[i]);
1120 if (status2 != CAPS_SUCCESS0)
1121 printf("\tPremature exit in destroy_vlmSurfaceStruct, status = %d\n",
1122 status2);
1123 }
1124 }
1125
1126 if (vlmSurface != NULL((void*)0)) EG_free(vlmSurface);
1127 numVLMSurface = 0;
1128
1129 return status;
1130}
1131
1132
1133/* ********************** Exposed AIM Functions ***************************** */
1134
1135int aimInitialize(int inst, /*@unused@*/ const char *unitSys, void *aimInfo,
1136 /*@unused@*/ void **instStore, /*@unused@*/ int *major,
1137 /*@unused@*/ int *minor, int *nIn, int *nOut,
1138 int *nFields, char ***fnames, int **franks, int **fInOut)
1139{
1140 int *ints=NULL((void*)0), i, status = CAPS_SUCCESS0;
1141 char **strs=NULL((void*)0);
1142
1143 aimStorage *astrosInstance=NULL((void*)0);
1144
1145#ifdef DEBUG
1146 printf("astrosAIM/aimInitialize instance = %d!\n", inst);
1147#endif
1148
1149 /* specify the number of analysis input and out "parameters" */
1150 *nIn = NUMINPUT;
1151 *nOut = NUMOUTPUT;
1152 if (inst == -1) return CAPS_SUCCESS0;
1153
1154 /* specify the field variables this analysis can generate and consume */
1155 *nFields = 4;
1156
1157 /* specify the name of each field variable */
1158 AIM_ALLOC(strs, *nFields, char *, aimInfo, status){ if (strs != ((void*)0)) { status = -4; aim_status(aimInfo, status
, "astrosAIM.c", 1158, __func__, 1, "AIM_ALLOC: %s != NULL", "strs"
); goto cleanup; } size_t memorysize = *nFields; strs = (char
* *) EG_alloc(memorysize*sizeof(char *)); if (strs == ((void
*)0)) { status = -4; aim_status(aimInfo, status, "astrosAIM.c"
, 1158, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "strs"
, memorysize, "char *"); goto cleanup; } }
;
1159
1160 strs[0] = EG_strdup("Displacement");
1161 strs[1] = EG_strdup("EigenVector");
1162 strs[2] = EG_strdup("EigenVector_#");
1163 strs[3] = EG_strdup("Pressure");
1164 for (i = 0; i < *nFields; i++)
1165 if (strs[i] == NULL((void*)0)) { status = EGADS_MALLOC-4; goto cleanup; }
1166 *fnames = strs;
1167
1168 /* specify the dimension of each field variable */
1169 AIM_ALLOC(ints, *nFields, int, aimInfo, status){ if (ints != ((void*)0)) { status = -4; aim_status(aimInfo, status
, "astrosAIM.c", 1169, __func__, 1, "AIM_ALLOC: %s != NULL", "ints"
); goto cleanup; } size_t memorysize = *nFields; ints = (int *
) EG_alloc(memorysize*sizeof(int)); if (ints == ((void*)0)) {
status = -4; aim_status(aimInfo, status, "astrosAIM.c", 1169
, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "ints", memorysize
, "int"); goto cleanup; } }
;
1170 ints[0] = 3;
1171 ints[1] = 3;
1172 ints[2] = 3;
1173 ints[3] = 1;
1174 *franks = ints;
1175 ints = NULL((void*)0);
1176
1177 /* specify if a field is an input field or output field */
1178 AIM_ALLOC(ints, *nFields, int, aimInfo, status){ if (ints != ((void*)0)) { status = -4; aim_status(aimInfo, status
, "astrosAIM.c", 1178, __func__, 1, "AIM_ALLOC: %s != NULL", "ints"
); goto cleanup; } size_t memorysize = *nFields; ints = (int *
) EG_alloc(memorysize*sizeof(int)); if (ints == ((void*)0)) {
status = -4; aim_status(aimInfo, status, "astrosAIM.c", 1178
, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "ints", memorysize
, "int"); goto cleanup; } }
;
1179
1180 ints[0] = FieldOut;
1181 ints[1] = FieldOut;
1182 ints[2] = FieldOut;
1183 ints[3] = FieldIn;
1184 *fInOut = ints;
1185 ints = NULL((void*)0);
1186
1187 // Allocate astrosInstance
1188 AIM_ALLOC(astrosInstance, 1, aimStorage, aimInfo, status){ if (astrosInstance != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "astrosAIM.c", 1188, __func__, 1, "AIM_ALLOC: %s != NULL"
, "astrosInstance"); goto cleanup; } size_t memorysize = 1; astrosInstance
= (aimStorage *) EG_alloc(memorysize*sizeof(aimStorage)); if
(astrosInstance == ((void*)0)) { status = -4; aim_status(aimInfo
, status, "astrosAIM.c", 1188, __func__, 3, "AIM_ALLOC: %s size %zu type %s"
, "astrosInstance", memorysize, "aimStorage"); goto cleanup; }
}
;
1189 *instStore = astrosInstance;
1190
1191 // Initialize instance storage
1192 (void) initiate_aimStorage(astrosInstance);
1193
1194cleanup:
1195 if (status != CAPS_SUCCESS0) {
1196 /* release all possibly allocated memory on error */
1197 if (*fnames != NULL((void*)0))
1198 for (i = 0; i < *nFields; i++) AIM_FREE((*fnames)[i]){ EG_free((*fnames)[i]); (*fnames)[i] = ((void*)0); };
1199 AIM_FREE(*franks){ EG_free(*franks); *franks = ((void*)0); };
1200 AIM_FREE(*fInOut){ EG_free(*fInOut); *fInOut = ((void*)0); };
1201 AIM_FREE(*fnames){ EG_free(*fnames); *fnames = ((void*)0); };
1202 AIM_FREE(*instStore){ EG_free(*instStore); *instStore = ((void*)0); };
1203 *nFields = 0;
1204 }
1205
1206 return status;
1207}
1208
1209
1210int aimInputs(/*@unused@*/ void *instStore, /*@unused@*/ void *aimInfo,
1211 int index, char **ainame, capsValue *defval)
1212{
1213
1214 /*! \page aimInputsAstros AIM Inputs
1215 * The following list outlines the Astros inputs along with their default value available
1216 * through the AIM interface. Unless noted these values will be not be linked to
1217 * any parent AIMs with variables of the same name.
1218 */
1219 int status = CAPS_SUCCESS0;
1220
1221#ifdef DEBUG
1222 printf(" astrosAIM/aimInputs index = %d!\n", index);
1223#endif
1224
1225 *ainame = NULL((void*)0);
1226
1227 // Astros Inputs
1228 if (index == Proj_Name) {
1229 *ainame = EG_strdup("Proj_Name");
1230 defval->type = String;
1231 defval->nullVal = NotNull;
1232 defval->vals.string = EG_strdup("astros_CAPS");
1233 defval->lfixed = Change;
1234
1235 /*! \page aimInputsAstros
1236 * - <B> Proj_Name = "astros_CAPS"</B> <br>
1237 * This corresponds to the project name used for file naming.
1238 */
1239
1240 } else if (index == Tess_Params) {
1241 *ainame = EG_strdup("Tess_Params");
1242 defval->type = Double;
1243 defval->dim = Vector;
1244 defval->nrow = 3;
1245 defval->ncol = 1;
1246 defval->units = NULL((void*)0);
1247 defval->lfixed = Fixed;
1248 defval->vals.reals = (double *) EG_alloc(defval->nrow*sizeof(double));
1249 if (defval->vals.reals != NULL((void*)0)) {
1250 defval->vals.reals[0] = 0.025;
1251 defval->vals.reals[1] = 0.001;
1252 defval->vals.reals[2] = 15.00;
1253 } else return EGADS_MALLOC-4;
1254
1255 /*! \page aimInputsAstros
1256 * - <B> Tess_Params = [0.025, 0.001, 15.0]</B> <br>
1257 * Body tessellation parameters used when creating a boundary element model.
1258 * Tess_Params[0] and Tess_Params[1] get scaled by the bounding
1259 * box of the body. (From the EGADS manual) A set of 3 parameters that drive the EDGE discretization
1260 * and the FACE triangulation. The first is the maximum length of an EDGE segment or triangle side
1261 * (in physical space). A zero is flag that allows for any length. The second is a curvature-based
1262 * value that looks locally at the deviation between the centroid of the discrete object and the
1263 * underlying geometry. Any deviation larger than the input value will cause the tessellation to
1264 * be enhanced in those regions. The third is the maximum interior dihedral angle (in degrees)
1265 * between triangle facets (or Edge segment tangents for a WIREBODY tessellation), note that a
1266 * zero ignores this phase.
1267 */
1268
1269 } else if (index == Edge_Point_Min) {
1270 *ainame = EG_strdup("Edge_Point_Min");
1271 defval->type = Integer;
1272 defval->vals.integer = 2;
1273 defval->lfixed = Fixed;
1274 defval->nrow = 1;
1275 defval->ncol = 1;
1276 defval->nullVal = NotNull;
1277
1278 /*! \page aimInputsAstros
1279 * - <B> aimInputsAstros = 2</B> <br>
1280 * Minimum number of points on an edge including end points to use when creating a surface mesh (min 2).
1281 */
1282
1283 } else if (index == Edge_Point_Max) {
1284 *ainame = EG_strdup("Edge_Point_Max");
1285 defval->type = Integer;
1286 defval->vals.integer = 50;
1287 defval->lfixed = Fixed;
1288 defval->nrow = 1;
1289 defval->ncol = 1;
1290 defval->nullVal = NotNull;
1291
1292 /*! \page aimInputsAstros
1293 * - <B> Edge_Point_Max = 50</B> <br>
1294 * Maximum number of points on an edge including end points to use when creating a surface mesh (min 2).
1295 */
1296
1297
1298 } else if (index == Quad_Mesh) {
1299 *ainame = EG_strdup("Quad_Mesh");
1300 defval->type = Boolean;
1301 defval->vals.integer = (int) false0;
1302
1303 /*! \page aimInputsAstros
1304 * - <B> Quad_Mesh = False</B> <br>
1305 * Create a quadratic mesh on four edge faces when creating the boundary element model.
1306 */
1307
1308 } else if (index == Property) {
1309 *ainame = EG_strdup("Property");
1310 defval->type = Tuple;
1311 defval->nullVal = IsNull;
1312 //defval->units = NULL;
1313 defval->lfixed = Change;
1314 defval->vals.tuple = NULL((void*)0);
1315 defval->dim = Vector;
1316
1317 /*! \page aimInputsAstros
1318 * - <B> Property = NULL</B> <br>
1319 * Property tuple used to input property information for the model, see \ref feaProperty for additional details.
1320 */
1321 } else if (index == Material) {
1322 *ainame = EG_strdup("Material");
1323 defval->type = Tuple;
1324 defval->nullVal = IsNull;
1325 //defval->units = NULL;
1326 defval->lfixed = Change;
1327 defval->vals.tuple = NULL((void*)0);
1328 defval->dim = Vector;
1329
1330 /*! \page aimInputsAstros
1331 * - <B> Material = NULL</B> <br>
1332 * Material tuple used to input material information for the model, see \ref feaMaterial for additional details.
1333 */
1334 } else if (index == Constraint) {
1335 *ainame = EG_strdup("Constraint");
1336 defval->type = Tuple;
1337 defval->nullVal = IsNull;
1338 //defval->units = NULL;
1339 defval->lfixed = Change;
1340 defval->vals.tuple = NULL((void*)0);
1341 defval->dim = Vector;
1342
1343 /*! \page aimInputsAstros
1344 * - <B> Constraint = NULL</B> <br>
1345 * Constraint tuple used to input constraint information for the model, see \ref feaConstraint for additional details.
1346 */
1347 } else if (index == Load) {
1348 *ainame = EG_strdup("Load");
1349 defval->type = Tuple;
1350 defval->nullVal = IsNull;
1351 //defval->units = NULL;
1352 defval->lfixed = Change;
1353 defval->vals.tuple = NULL((void*)0);
1354 defval->dim = Vector;
1355
1356 /*! \page aimInputsAstros
1357 * - <B> Load = NULL</B> <br>
1358 * Load tuple used to input load information for the model, see \ref feaLoad for additional details.
1359 */
1360 } else if (index == Analysix) {
1361 *ainame = EG_strdup("Analysis");
1362 defval->type = Tuple;
1363 defval->nullVal = IsNull;
1364 //defval->units = NULL;
1365 defval->lfixed = Change;
1366 defval->vals.tuple = NULL((void*)0);
1367 defval->dim = Vector;
1368
1369 /*! \page aimInputsAstros
1370 * - <B> Analysis = NULL</B> <br>
1371 * Analysis tuple used to input analysis/case information for the model, see \ref feaAnalysis for additional details.
1372 */
1373 } else if (index == Analysis_Type) {
1374 *ainame = EG_strdup("Analysis_Type");
1375 defval->type = String;
1376 defval->nullVal = NotNull;
1377 defval->vals.string = EG_strdup("Modal");
1378 defval->lfixed = Change;
1379
1380 /*! \page aimInputsAstros
1381 * - <B> Analysis_Type = "Modal"</B> <br>
1382 * Type of analysis to generate files for, options include "Modal", "Static", "AeroelasticTrim", "AeroelasticTrimOpt", "AeroelasticFlutter", and "Optimization".
1383 * Note: "Aeroelastic" and "StaticOpt" are still supported and refer to "AeroelasticTrim" and "Optimization".
1384 */
1385 } else if (index == File_Format) {
1386 *ainame = EG_strdup("File_Format");
1387 defval->type = String;
1388 defval->vals.string = EG_strdup("Small"); // Small, Large, Free
1389 defval->lfixed = Change;
1390
1391 /*! \page aimInputsAstros
1392 * - <B> File_Format = "Small"</B> <br>
1393 * Formatting type for the bulk file. Options: "Small", "Large", "Free".
1394 */
1395
1396 } else if (index == Mesh_File_Format) {
1397 *ainame = EG_strdup("Mesh_File_Format");
1398 defval->type = String;
1399 defval->vals.string = EG_strdup("Free"); // Small, Large, Free
1400 defval->lfixed = Change;
1401
1402 /*! \page aimInputsAstros
1403 * - <B> Mesh_File_Format = "Free"</B> <br>
1404 * Formatting type for the mesh file. Options: "Small", "Large", "Free".
1405 */
1406
1407 } else if (index == Design_Variable) {
1408 *ainame = EG_strdup("Design_Variable");
1409 defval->type = Tuple;
1410 defval->nullVal = IsNull;
1411 //defval->units = NULL;
1412 defval->lfixed = Change;
1413 defval->vals.tuple = NULL((void*)0);
1414 defval->dim = Vector;
1415
1416 /*! \page aimInputsAstros
1417 * - <B> Design_Variable = NULL</B> <br>
1418 * The design variable tuple used to input design variable information for the model optimization, see \ref feaDesignVariable for additional details.
1419 */
1420
1421 } else if (index == Design_Variable_Relation) {
1422 *ainame = EG_strdup("Design_Variable_Relation");
1423 defval->type = Tuple;
1424 defval->nullVal = IsNull;
1425 //defval->units = NULL;
1426 defval->lfixed = Change;
1427 defval->vals.tuple = NULL((void*)0);
1428 defval->dim = Vector;
1429
1430 /*! \page aimInputsAstros
1431 * - <B> Design_Variable_Relation = NULL</B> <br>
1432 * The design variable relation tuple is used to input design variable relation information for the model optimization, see \ref feaDesignVariableRelation for additional details.
1433 */
1434
1435 } else if (index == Design_Constraint) {
1436 *ainame = EG_strdup("Design_Constraint");
1437 defval->type = Tuple;
1438 defval->nullVal = IsNull;
1439 //defval->units = NULL;
1440 defval->lfixed = Change;
1441 defval->vals.tuple = NULL((void*)0);
1442 defval->dim = Vector;
1443
1444 /*! \page aimInputsAstros
1445 * - <B> Design_Constraint = NULL</B> <br>
1446 * The design constraint tuple used to input design constraint information for the model optimization, see \ref feaDesignConstraint for additional details.
1447 */
1448
1449 } else if (index == ObjectiveMinMax) {
1450 *ainame = EG_strdup("ObjectiveMinMax");
1451 defval->type = String;
1452 defval->nullVal = NotNull;
1453 defval->vals.string = EG_strdup("Max"); // Max, Min
1454 defval->lfixed = Change;
1455
1456 /*! \page aimInputsAstros
1457 * - <B> ObjectiveMinMax = "Max"</B> <br>
1458 * Maximize or minimize the design objective during an optimization. Option: "Max" or "Min".
1459 */
1460
1461 } else if (index == ObjectiveResponseType) {
1462 *ainame = EG_strdup("ObjectiveResponseType");
1463 defval->type = String;
1464 defval->nullVal = NotNull;
1465 defval->vals.string = EG_strdup("Weight"); // Weight
1466 defval->lfixed = Change;
1467
1468 /*! \page aimInputsAstros
1469 * - <B> ObjectiveResponseType = "Weight"</B> <br>
1470 * Object response type (see Astros manual).
1471 */
1472 } else if (index == VLM_Surface) {
1473 *ainame = EG_strdup("VLM_Surface");
1474 defval->type = Tuple;
1475 defval->nullVal = IsNull;
1476 //defval->units = NULL;
1477 defval->dim = Vector;
1478 defval->lfixed = Change;
1479 defval->vals.tuple = NULL((void*)0);
1480
1481 /*! \page aimInputsAstros
1482 * - <B>VLM_Surface = NULL </B> <br>
1483 * Vortex lattice method tuple input. See \ref vlmSurface for additional details.
1484 */
1485 } else if (index == Support) {
1486 *ainame = EG_strdup("Support");
1487 defval->type = Tuple;
1488 defval->nullVal = IsNull;
1489 //defval->units = NULL;
1490 defval->lfixed = Change;
1491 defval->vals.tuple = NULL((void*)0);
1492 defval->dim = Vector;
1493
1494 /*! \page aimInputsAstros
1495 * - <B> Support = NULL</B> <br>
1496 * Support tuple used to input support information for the model, see \ref feaSupport for additional details.
1497 */
1498 } else if (index == Connect) {
1499 *ainame = EG_strdup("Connect");
1500 defval->type = Tuple;
1501 defval->nullVal = IsNull;
1502 //defval->units = NULL;
1503 defval->lfixed = Change;
1504 defval->vals.tuple = NULL((void*)0);
1505 defval->dim = Vector;
1506
1507 /*! \page aimInputsAstros
1508 * - <B> Connect = NULL</B> <br>
1509 * Connect tuple used to define connection to be made in the, see \ref feaConnection for additional details.
1510 */
1511
1512 } else if (index == Parameter) {
1513 *ainame = EG_strdup("Parameter");
1514 defval->type = Tuple;
1515 defval->nullVal = IsNull;
1516 //defval->units = NULL;
1517 defval->lfixed = Change;
1518 defval->vals.tuple = NULL((void*)0);
1519 defval->dim = Vector;
1520
1521 /*! \page aimInputsAstros
1522 * - <B> Parameter = NULL</B> <br>
1523 * Parameter tuple used to define user entries. This can be used to input things to ASTROS such as CONVERT or MFORM etc.
1524 * The input is in Tuple form ("DATACARD", "DATAVALUE"). All inputs are strings. Example: ("CONVERT","MASS, 0.00254").
1525 * Note: Inputs assume a "," delimited entry. Notice the "," after MASS in the Example.
1526 */
1527
1528 } else if (index == Mesh) {
1529 *ainame = AIM_NAME(Mesh)EG_strdup("Mesh");
1530 defval->type = Pointer;
1531 defval->dim = Vector;
1532 defval->lfixed = Change;
1533 defval->sfixed = Change;
1534 defval->vals.AIMptr = NULL((void*)0);
1535 defval->nullVal = IsNull;
1536 AIM_STRDUP(defval->units, "meshStruct", aimInfo, status){ if (defval->units != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "astrosAIM.c", 1536, __func__, 1, "AIM_STRDUP: %s != NULL!"
, "defval->units"); goto cleanup; } defval->units = EG_strdup
("meshStruct"); if (defval->units == ((void*)0)) { status =
-4; aim_status(aimInfo, status, "astrosAIM.c", 1536, __func__
, 2, "AIM_STRDUP: %s %s", "defval->units", "meshStruct"); goto
cleanup; } }
;
1537
1538 /*! \page aimInputsAstros
1539 * - <B>Mesh = NULL</B> <br>
1540 * A Mesh link.
1541 */
1542 }
1543
1544 AIM_NOTNULL(*ainame, aimInfo, status){ if (*ainame == ((void*)0)) { status = -307; aim_status(aimInfo
, status, "astrosAIM.c", 1544, __func__, 1, "%s == NULL!", "*ainame"
); goto cleanup; } }
;
1545
1546cleanup:
1547 if (status != CAPS_SUCCESS0) AIM_FREE(*ainame){ EG_free(*ainame); *ainame = ((void*)0); };
1548 return status;
1549}
1550
1551
1552// ********************** AIM Function Break *****************************
1553int aimUpdateState(void *instStore, void *aimInfo,
1554 capsValue *aimInputs)
1555{
1556 int status; // Function return status
1557 int i;
1558
1559 // Analysis information
1560 const char *analysisType = NULL((void*)0);
1561
1562 aimStorage *astrosInstance;
1563
1564 astrosInstance = (aimStorage *) instStore;
1565 AIM_NOTNULL(aimInputs, aimInfo, status){ if (aimInputs == ((void*)0)) { status = -307; aim_status(aimInfo
, status, "astrosAIM.c", 1565, __func__, 1, "%s == NULL!", "aimInputs"
); goto cleanup; } }
;
1566
1567 // Get project name
1568 astrosInstance->projectName = aimInputs[Proj_Name-1].vals.string;
1569
1570 // Analysis type
1571 analysisType = aimInputs[Analysis_Type-1].vals.string;
1572
1573 // Get FEA mesh if we don't already have one
1574 if (astrosInstance->feaProblem.feaMesh.numNode == 0 ||
1575 aim_newGeometry(aimInfo) == CAPS_SUCCESS0) {
1576
1577 status = checkAndCreateMesh(aimInfo, astrosInstance);
1578 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
1578, __func__, 0); goto cleanup; }
;
1579
1580 // Get Aeroelastic mesh
1581 if( strcasecmp(analysisType, "Aeroelastic") == 0 ||
1582 strcasecmp(analysisType, "AeroelasticTrim") == 0 ||
1583 strcasecmp(analysisType, "AeroelasticTrimOpt") == 0 ||
1584 strcasecmp(analysisType, "AeroelasticFlutter") == 0) {
1585
1586 status = createVLMMesh(instStore, aimInfo, aimInputs);
1587 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
1587, __func__, 0); goto cleanup; }
;
1588 }
1589 }
1590
1591
1592 // Note: Setting order is important here.
1593 // 1. Materials should be set before properties.
1594 // 2. Coordinate system should be set before mesh and loads
1595 // 3. Mesh should be set before loads, constraints, and supports
1596 // 4. Constraints and loads should be set before analysis
1597 // 5. Optimization should be set after properties, but before analysis
1598
1599 // Set material properties
1600 if (aimInputs[Material-1].nullVal == NotNull) {
1601 status = fea_getMaterial(aimInfo,
1602 aimInputs[Material-1].length,
1603 aimInputs[Material-1].vals.tuple,
1604 &astrosInstance->units,
1605 &astrosInstance->feaProblem.numMaterial,
1606 &astrosInstance->feaProblem.feaMaterial);
1607 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
1607, __func__, 0); goto cleanup; }
;
1608 } else printf("Material tuple is NULL - No materials set\n");
1609
1610 // Set property properties
1611 if (aimInputs[Property-1].nullVal == NotNull) {
1612 status = fea_getProperty(aimInfo,
1613 aimInputs[Property-1].length,
1614 aimInputs[Property-1].vals.tuple,
1615 &astrosInstance->attrMap,
1616 &astrosInstance->units,
1617 &astrosInstance->feaProblem);
1618 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
1618, __func__, 0); goto cleanup; }
;
1619
1620 // Assign element "subtypes" based on properties set
1621 status = fea_assignElementSubType(astrosInstance->feaProblem.numProperty,
1622 astrosInstance->feaProblem.feaProperty,
1623 &astrosInstance->feaProblem.feaMesh);
1624 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
1624, __func__, 0); goto cleanup; }
;
1625 } else printf("Property tuple is NULL - No properties set\n");
1626
1627 // Set constraint properties
1628 if (aimInputs[Constraint-1].nullVal == NotNull) {
1629 status = fea_getConstraint(aimInputs[Constraint-1].length,
1630 aimInputs[Constraint-1].vals.tuple,
1631 &astrosInstance->constraintMap,
1632 &astrosInstance->feaProblem);
1633 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
1633, __func__, 0); goto cleanup; }
;
1634 } else printf("Constraint tuple is NULL - No constraints applied\n");
1635
1636 // Set support properties
1637 if (aimInputs[Support-1].nullVal == NotNull) {
1638 status = fea_getSupport(aimInputs[Support-1].length,
1639 aimInputs[Support-1].vals.tuple,
1640 &astrosInstance->constraintMap,
1641 &astrosInstance->feaProblem);
1642 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
1642, __func__, 0); goto cleanup; }
;
1643 } else printf("Support tuple is NULL - No supports applied\n");
1644
1645 // Set connection properties
1646 if (aimInputs[Connect-1].nullVal == NotNull) {
1647 status = fea_getConnection(aimInputs[Connect-1].length,
1648 aimInputs[Connect-1].vals.tuple,
1649 &astrosInstance->connectMap,
1650 &astrosInstance->feaProblem);
1651 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
1651, __func__, 0); goto cleanup; }
;
1652
1653
1654 // Unify all connectionID's for RBE2 cards sake to be used for MPC in case control
1655 for (i = 0; i < astrosInstance->feaProblem.numConnect; i++) {
1656
1657 if (astrosInstance->feaProblem.feaConnect[i].connectionType == RigidBody
1658 || astrosInstance->feaProblem.feaConnect[i].connectionType == RigidBodyInterpolate) {
1659
1660 astrosInstance->feaProblem.feaConnect[i].connectionID = astrosInstance->feaProblem.numConnect+1;
1661 }
1662 }
1663
1664 } else printf("Connect tuple is NULL - Using defaults\n");
1665
1666 // Set load properties
1667 if (aimInputs[Load-1].nullVal == NotNull) {
1668 status = fea_getLoad(aimInputs[Load-1].length,
1669 aimInputs[Load-1].vals.tuple,
1670 &astrosInstance->loadMap,
1671 &astrosInstance->feaProblem);
1672 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
1672, __func__, 0); goto cleanup; }
;
1673 } else printf("Load tuple is NULL - No loads applied\n");
1674
1675 // Set design variables
1676 if (aimInputs[Design_Variable-1].nullVal == NotNull) {
1677 status = fea_getDesignVariable(aimInfo,
1678 (int)true1,
1679 aimInputs[Design_Variable-1].length,
1680 aimInputs[Design_Variable-1].vals.tuple,
1681 aimInputs[Design_Variable_Relation-1].length,
1682 aimInputs[Design_Variable_Relation-1].vals.tuple,
1683 &astrosInstance->attrMap,
1684 &astrosInstance->feaProblem);
1685 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
1685, __func__, 0); goto cleanup; }
;
1686 } else printf("Design_Variable tuple is NULL - No design variables applied\n");
1687
1688 // Set design constraints
1689 if (aimInputs[Design_Constraint-1].nullVal == NotNull) {
1690 status = fea_getDesignConstraint(aimInputs[Design_Constraint-1].length,
1691 aimInputs[Design_Constraint-1].vals.tuple,
1692 &astrosInstance->feaProblem);
1693 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
1693, __func__, 0); goto cleanup; }
;
1694 } else printf("Design_Constraint tuple is NULL - No design constraints applied\n");
1695
1696 // Set analysis settings
1697 if (aimInputs[Analysix-1].nullVal == NotNull) {
1698 status = fea_getAnalysis(aimInputs[Analysix-1].length,
1699 aimInputs[Analysix-1].vals.tuple,
1700 &astrosInstance->feaProblem);
1701 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
1701, __func__, 0); goto cleanup; }
;
1702 } else {
1703 printf("Analysis tuple is NULL\n"); // Its ok to not have an analysis tuple we will just create one
1704
1705 status = fea_createDefaultAnalysis(&astrosInstance->feaProblem, analysisType);
1706 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
1706, __func__, 0); goto cleanup; }
;
1707 }
1708
1709
1710 // Set file format type
1711 if (strcasecmp(aimInputs[File_Format-1].vals.string, "Small") == 0) {
1712 astrosInstance->feaProblem.feaFileFormat.fileType = SmallField;
1713 } else if (strcasecmp(aimInputs[File_Format-1].vals.string, "Large") == 0) {
1714 astrosInstance->feaProblem.feaFileFormat.fileType = LargeField;
1715 } else if (strcasecmp(aimInputs[File_Format-1].vals.string, "Free") == 0) {
1716 astrosInstance->feaProblem.feaFileFormat.fileType = FreeField;
1717 } else {
1718 printf("Unrecognized \"File_Format\", valid choices are [Small, Large, or Free]. Reverting to default\n");
1719 }
1720
1721 // Set grid file format type
1722 if (strcasecmp(aimInputs[Mesh_File_Format-1].vals.string, "Small") == 0) {
1723 astrosInstance->feaProblem.feaFileFormat.gridFileType = SmallField;
1724 } else if (strcasecmp(aimInputs[Mesh_File_Format-1].vals.string, "Large") == 0) {
1725 astrosInstance->feaProblem.feaFileFormat.gridFileType = LargeField;
1726 } else if (strcasecmp(aimInputs[Mesh_File_Format-1].vals.string, "Free") == 0) {
1727 astrosInstance->feaProblem.feaFileFormat.gridFileType = FreeField;
1728 } else {
1729 printf("Unrecognized \"Mesh_File_Format\", valid choices are [Small, Large, or Free]. Reverting to default\n");
1730 }
1731
1732 status = CAPS_SUCCESS0;
1733cleanup:
1734 return status;
1735}
1736
1737
1738// ********************** AIM Function Break *****************************
1739int aimPreAnalysis(const void *instStore, void *aimInfo, capsValue *aimInputs)
1740{
1741
1742 int i, j, k, l; // Indexing
1743 int found;
1744
1745 int status; // Status return
1746
1747 //int found; // Boolean operator
1748
1749 int *tempIntegerArray = NULL((void*)0); // Temporary array to store a list of integers
1750 char *noQuoteString = NULL((void*)0);
1751
1752 // Analysis information
1753 const char *analysisType = NULL((void*)0);
1754 int optFlag; // 0 - ANALYSIS, 1 - OPTIMIZATION Set based on analysisType char input
1755
1756 // Optimization Information
1757 //char *objectiveResp = NULL;
1758 const char *geomInName;
1759
1760 // File IO
1761 char *filename = NULL((void*)0); // Output file name
1762 FILE *fp = NULL((void*)0); // Output file pointer
1763 int addComma = (int) false0; // Add comma between inputs
1764
1765 int numThermalLoad=0, numGravityLoad=0;
1766 int nGeomIn;
1767 capsValue *geomInVal;
1768 const aimStorage *astrosInstance;
1769
1770 // Load information
1771 feaLoadStruct *feaLoad = NULL((void*)0); // size = [numLoad]
1
'feaLoad' initialized to a null pointer value
1772
1773#ifdef DEBUG
1774 // Bodies
1775 const char *intents;
1776 int numBody; // Number of Bodies
1777 ego *bodies;
1778
1779 // Get AIM bodies
1780 status = aim_getBodies(aimInfo, &intents, &numBody, &bodies);
1781 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
1781, __func__, 0); goto cleanup; }
;
1782
1783 printf(" astrosAIM/aimPreAnalysis numBody = %d!\n", numBody);
1784#endif
1785 astrosInstance = (const aimStorage *) instStore;
1786 AIM_NOTNULL(aimInputs, aimInfo, status){ if (aimInputs == ((void*)0)) { status = -307; aim_status(aimInfo
, status, "astrosAIM.c", 1786, __func__, 1, "%s == NULL!", "aimInputs"
); goto cleanup; } }
;
2
Assuming 'aimInputs' is not equal to null
3
Taking false branch
1787
1788 if (astrosInstance->feaProblem.numLoad > 0) {
4
Assuming field 'numLoad' is <= 0
5
Taking false branch
1789 AIM_ALLOC(feaLoad, astrosInstance->feaProblem.numLoad, feaLoadStruct, aimInfo, status){ if (feaLoad != ((void*)0)) { status = -4; aim_status(aimInfo
, status, "astrosAIM.c", 1789, __func__, 1, "AIM_ALLOC: %s != NULL"
, "feaLoad"); goto cleanup; } size_t memorysize = astrosInstance
->feaProblem.numLoad; feaLoad = (feaLoadStruct *) EG_alloc
(memorysize*sizeof(feaLoadStruct)); if (feaLoad == ((void*)0)
) { status = -4; aim_status(aimInfo, status, "astrosAIM.c", 1789
, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "feaLoad", memorysize
, "feaLoadStruct"); goto cleanup; } }
;
1790 for (i = 0; i < astrosInstance->feaProblem.numLoad; i++) initiate_feaLoadStruct(&feaLoad[i]);
1791 for (i = 0; i < astrosInstance->feaProblem.numLoad; i++) {
1792 status = copy_feaLoadStruct(aimInfo, &astrosInstance->feaProblem.feaLoad[i], &feaLoad[i]);
1793 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
1793, __func__, 0); goto cleanup; }
;
1794
1795 if (feaLoad[i].loadType == PressureExternal) {
1796
1797 // Transfer external pressures from the AIM discrObj
1798 status = fea_transferExternalPressure(aimInfo,
1799 &astrosInstance->feaProblem.feaMesh,
1800 &feaLoad[i]);
1801 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
1801, __func__, 0); goto cleanup; }
;
1802 }
1803 }
1804 }
1805
1806 // Analysis type
1807 analysisType = aimInputs[Analysis_Type-1].vals.string;
1808
1809 // Write Astros Mesh
1810 filename = EG_alloc(MXCHAR255 +1);
1811 if (filename == NULL((void*)0)) return EGADS_MALLOC-4;
6
Assuming 'filename' is not equal to NULL
7
Taking false branch
1812 strcpy(filename, astrosInstance->projectName);
1813
1814 status = mesh_writeAstros(aimInfo,
1815 filename,
1816 1,
1817 &astrosInstance->feaProblem.feaMesh,
1818 astrosInstance->feaProblem.feaFileFormat.gridFileType,
1819 astrosInstance->feaProblem.numDesignVariable,
1820 astrosInstance->feaProblem.feaDesignVariable,
1821 1.0);
1822 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
1822, __func__, 0); goto cleanup; }
;
8
Assuming 'status' is equal to 0
9
Taking false branch
1823
1824 // Write Astros subElement types not supported by astros_writeMesh
1825 strcat(filename, ".bdf");
1826 fp = aim_fopen(aimInfo, filename, "a");
1827 if (fp == NULL((void*)0)) {
10
Assuming 'fp' is not equal to NULL
11
Taking false branch
1828 AIM_ERROR(aimInfo, "Unable to open file: %s", filename){ aim_message(aimInfo, CERROR, 0 , "astrosAIM.c", 1828, __func__
, "Unable to open file: %s", filename); }
;
1829 status = CAPS_IOERR-332;
1830 goto cleanup;
1831 }
1832 AIM_FREE(filename){ EG_free(filename); filename = ((void*)0); };
1833
1834 printf("Writing subElement types (if any) - appending mesh file\n");
1835 status = astros_writeSubElementCard(fp,
1836 &astrosInstance->feaProblem.feaMesh,
1837 astrosInstance->feaProblem.numProperty,
1838 astrosInstance->feaProblem.feaProperty,
1839 &astrosInstance->feaProblem.feaFileFormat);
1840 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
1840, __func__, 0); goto cleanup; }
;
12
Assuming 'status' is equal to 0
13
Taking false branch
1841
1842 // Connections
1843 for (i = 0; i < astrosInstance->feaProblem.numConnect; i++) {
14
Assuming 'i' is >= field 'numConnect'
15
Loop condition is false. Execution continues on line 1854
1844
1845 if (i == 0) {
1846 printf("Writing connection cards - appending mesh file\n");
1847 }
1848
1849 status = astros_writeConnectionCard(fp,
1850 &astrosInstance->feaProblem.feaConnect[i],
1851 &astrosInstance->feaProblem.feaFileFormat);
1852 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
1852, __func__, 0); goto cleanup; }
;
1853 }
1854 if (fp
15.1
'fp' is not equal to NULL
!= NULL((void*)0)) fclose(fp);
16
Taking true branch
1855 fp = NULL((void*)0);
1856
1857
1858 // Write astros input file
1859 filename = EG_alloc(MXCHAR255 +1);
1860 if (filename == NULL((void*)0)) return EGADS_MALLOC-4;
17
Assuming 'filename' is not equal to NULL
18
Taking false branch
1861 strcpy(filename, astrosInstance->projectName);
1862 strcat(filename, ".dat");
1863
1864
1865 printf("\nWriting Astros instruction file....\n");
1866 fp = aim_fopen(aimInfo, filename, "w");
1867 if (fp == NULL((void*)0)) {
19
Assuming 'fp' is not equal to NULL
20
Taking false branch
1868 AIM_ERROR(aimInfo, "Unable to open file: %s", filename){ aim_message(aimInfo, CERROR, 0 , "astrosAIM.c", 1868, __func__
, "Unable to open file: %s", filename); }
;
1869 status = CAPS_IOERR-332;
1870 goto cleanup;
1871 }
1872 AIM_FREE(filename){ EG_free(filename); filename = ((void*)0); };
1873
1874 // define file format delimiter type
1875 /*
1876 if (astrosInstance->feaProblem.feaFileFormat.fileType == FreeField) {
1877 delimiter = ",";
1878 } else {
1879 delimiter = " ";
1880 }
1881 */
1882
1883 //////////////// Executive control ////////////////
1884 fprintf(fp, "ASSIGN DATABASE CAPS PASS NEW\n");
1885
1886 //////////////// Case control ////////////////
1887 fprintf(fp, "SOLUTION\n");
1888 fprintf(fp, "TITLE = %s\n", astrosInstance->projectName);
1889 // Analysis type
1890 if (strcasecmp(analysisType, "Modal") == 0 ||
21
Assuming the condition is false
26
Taking false branch
1891 strcasecmp(analysisType, "Static") == 0 ||
22
Assuming the condition is false
1892 strcasecmp(analysisType, "AeroelasticTrim") == 0 ||
23
Assuming the condition is false
1893 strcasecmp(analysisType, "AeroelasticFlutter") == 0 ||
24
Assuming the condition is false
1894 strcasecmp(analysisType, "Aeroelastic") == 0) {
25
Assuming the condition is false
1895
1896 fprintf(fp, "ANALYZE\n");
1897 optFlag = 0;
1898 }
1899 else if(strcasecmp(analysisType, "StaticOpt") == 0 ||
1900 strcasecmp(analysisType, "Optimization") == 0 ||
1901 strcasecmp(analysisType, "AeroelasticTrimOpt") == 0) {
1902
1903 fprintf(fp, "OPTIMIZE STRATEGY=((FSD,10), (MP,20)), MAXITER=30, NRFAC=1.5,\n");
1904 fprintf(fp, "EPS= 1.00, MOVLIM=1.5\n");
1905 fprintf(fp, "PRINT DCON=ALL, GDES=ALL, GPWG=ALL\n");
1906 optFlag = 1;
1907 }
1908
1909 else {
1910 AIM_ERROR(aimInfo, "Unrecognized \"Analysis_Type\", %s\n", analysisType){ aim_message(aimInfo, CERROR, 0 , "astrosAIM.c", 1910, __func__
, "Unrecognized \"Analysis_Type\", %s\n", analysisType); }
;
1911 status = CAPS_BADVALUE-311;
1912 goto cleanup;
1913 }
1914
1915
1916 // Set up the case information
1917 if (astrosInstance->feaProblem.numAnalysis == 0) {
27
Assuming field 'numAnalysis' is not equal to 0
28
Taking false branch
1918 printf("Error: No analyses in the feaProblem! (this shouldn't be possible)\n");
1919 status = CAPS_BADVALUE-311;
1920 goto cleanup;
1921 }
1922
1923
1924 // Write sub-case information if multiple analysis tuples were provide - will always have at least 1
1925 for (i = 0; i < astrosInstance->feaProblem.numAnalysis; i++) {
29
Assuming 'i' is < field 'numAnalysis'
30
Loop condition is true. Entering loop body
47
Assuming 'i' is >= field 'numAnalysis'
48
Loop condition is false. Execution continues on line 2199
1926
1927 // Write boundary constraints/supports/etc.
1928 fprintf(fp, " BOUNDARY");
1929
1930 addComma = (int) false0;
1931 // Write support for sub-case
1932 if (astrosInstance->feaProblem.feaAnalysis[i].numSupport != 0) {
31
Assuming field 'numSupport' is equal to 0
32
Taking false branch
1933
1934 if (astrosInstance->feaProblem.feaAnalysis[i].numSupport > 1) {
1935 printf("\tWARNING: More than 1 support is not supported at this time for a given case!\n");
1936
1937 } else {
1938 fprintf(fp, " SUPPORT = %d ", astrosInstance->feaProblem.feaAnalysis[i].supportSetID[0]);
1939 addComma = (int) true1;
1940 }
1941 }
1942
1943 // Write constraint for sub-case - see warning statement below for behavior
1944 if (astrosInstance->feaProblem.numConstraint != 0) {
33
Assuming field 'numConstraint' is equal to 0
34
Taking false branch
1945 if (addComma == (int) true1) fprintf(fp,",");
1946
1947 fprintf(fp, " SPC = %d ", astrosInstance->feaProblem.numConstraint+i+1); //TODO - change to i+1 to just i
1948 addComma = (int) true1;
1949 }
1950
1951 // Issue some warnings regarding constraints if necessary
1952 if (astrosInstance->feaProblem.feaAnalysis[i].numConstraint == 0 && astrosInstance->feaProblem.numConstraint !=0) {
35
Assuming field 'numConstraint' is not equal to 0
1953
1954 printf("\tWarning: No constraints specified for case %s, assuming "
1955 "all constraints are applied!!!!\n", astrosInstance->feaProblem.feaAnalysis[i].name);
1956
1957 } else if (astrosInstance->feaProblem.numConstraint
35.1
Field 'numConstraint' is equal to 0
== 0) {
36
Taking true branch
1958
1959 printf("\tWarning: No constraints specified for case %s!!!!\n", astrosInstance->feaProblem.feaAnalysis[i].name);
1960 }
1961
1962 // Write MPC for sub-case - currently only supported when we have RBE2 elements - see above for unification - TODO - investigate
1963 for (j = 0; j
36.1
'j' is >= field 'numConnect'
< astrosInstance->feaProblem.numConnect; j++) {
37
Loop condition is false. Execution continues on line 1976
1964
1965 if (astrosInstance->feaProblem.feaConnect[j].connectionType == RigidBody
1966 || astrosInstance->feaProblem.feaConnect[i].connectionType == RigidBodyInterpolate) {
1967
1968 if (addComma == (int) true1) fprintf(fp,",");
1969
1970 fprintf(fp, " MPC = %d ", astrosInstance->feaProblem.feaConnect[j].connectionID);
1971 addComma = (int) true1;
1972 break;
1973 }
1974 }
1975
1976 if (astrosInstance->feaProblem.feaAnalysis[i].analysisType == Modal ||
38
Assuming field 'analysisType' is not equal to Modal
40
Taking false branch
1977 astrosInstance->feaProblem.feaAnalysis[i].analysisType == AeroelasticFlutter ) {
39
Assuming field 'analysisType' is not equal to AeroelasticFlutter
1978
1979 if (addComma == (int) true1) fprintf(fp,",");
1980 fprintf(fp," METHOD = %d ", astrosInstance->feaProblem.feaAnalysis[i].analysisID);
1981 //addComma = (int) true;
1982 }
1983
1984 fprintf(fp, "\n"); // End boundary line
1985
1986 fprintf(fp, " LABEL = %s\n", astrosInstance->feaProblem.feaAnalysis[i].name);
1987
1988 // Write discipline
1989 if (astrosInstance->feaProblem.feaAnalysis[i].analysisType == Static) { // Static
41
Assuming field 'analysisType' is not equal to Static
42
Taking false branch
1990
1991 fprintf(fp, " STATICS ");
1992
1993 // Issue some warnings regarding loads if necessary
1994 if (astrosInstance->feaProblem.feaAnalysis[i].numLoad == 0 && astrosInstance->feaProblem.numLoad !=0) {
1995 printf("\tWarning: No loads specified for static case %s, assuming "
1996 "all loads are applied!!!!\n", astrosInstance->feaProblem.feaAnalysis[i].name);
1997
1998 } else if (astrosInstance->feaProblem.numLoad == 0) {
1999 printf("\tWarning: No loads specified for static case %s!!!!\n", astrosInstance->feaProblem.feaAnalysis[i].name);
2000 }
2001
2002 addComma = (int) false0;
2003 found = (int) false0;
2004 numThermalLoad = 0;
2005 numGravityLoad = 0;
2006
2007 if (astrosInstance->feaProblem.numLoad !=0) {
2008 fprintf(fp, "(");
2009
2010 for (k = 0; k < astrosInstance->feaProblem.numLoad; k++) {
2011
2012 if (astrosInstance->feaProblem.feaAnalysis[i].numLoad != 0) { // if loads specified in analysis
2013
2014 for (j = 0; j < astrosInstance->feaProblem.feaAnalysis[i].numLoad; j++) { // See if the load is in the loadSet
2015
2016 if (feaLoad[k].loadID == astrosInstance->feaProblem.feaAnalysis[i].loadSetID[j] ) break;
2017 }
2018
2019 if (j >= astrosInstance->feaProblem.feaAnalysis[i].numLoad) continue; // If it isn't in the loadSet move on
2020 } else {
2021 //pass
2022 }
2023
2024 if (feaLoad[k].loadType == Thermal && numThermalLoad == 0) {
2025
2026 if (addComma == (int) true1) fprintf(fp, ",");
2027 fprintf(fp, " THERMAL = %d", feaLoad[k].loadID);
2028 addComma = (int) true1;
2029
2030 numThermalLoad += 1;
2031 if (numThermalLoad > 1) {
2032 printf("More than 1 Thermal load found - astrosAIM does NOT currently doesn't support multiple thermal loads in a given case!\n");
2033 }
2034
2035 continue;
2036 }
2037
2038 if (feaLoad[k].loadType == Gravity && numGravityLoad == 0) {
2039
2040 if (addComma == (int) true1) fprintf(fp, ",");
2041 fprintf(fp, " GRAVITY = %d", feaLoad[k].loadID);
2042 addComma = (int) true1;
2043
2044 numGravityLoad += 1;
2045 if (numGravityLoad > 1) {
2046 printf("More than 1 Gravity load found - astrosAIM does NOT currently doesn't support multiple gravity loads in a given case!\n");
2047 }
2048
2049 continue;
2050 }
2051
2052 found = (int) true1;
2053 }
2054
2055 if (found == (int) true1) {
2056 if (addComma == (int) true1) fprintf(fp, ",");
2057 fprintf(fp, " MECH = %d", astrosInstance->feaProblem.numLoad+i+1);
2058 }
2059
2060 fprintf(fp,")");
2061 }
2062
2063 if (optFlag == 0) {
2064 fprintf(fp, "\n");
2065 fprintf(fp, " PRINT DISP=ALL, STRESS=ALL\n");
2066 } else {
2067 fprintf(fp, ", CONST( STRESS = %d)\n", astrosInstance->feaProblem.numDesignConstraint+i+1);
2068 fprintf(fp, " PRINT DISP(ITER=LAST)=ALL, STRESS(ITER=LAST)=ALL\n");
2069 }
2070 }
2071
2072 if (astrosInstance->feaProblem.feaAnalysis[i].analysisType
42.1
Field 'analysisType' is not equal to Modal
== Modal) {// Modal
43
Taking false branch
2073 fprintf(fp, " MODES\n");
2074 fprintf(fp, " PRINT (MODES=ALL) DISP=ALL, ROOT=ALL\n");
2075 }
2076 if (astrosInstance->feaProblem.feaAnalysis[i].analysisType == AeroelasticTrim) {// Trim
44
Assuming field 'analysisType' is not equal to AeroelasticTrim
45
Taking false branch
2077 fprintf(fp, " SAERO SYMMETRIC (TRIM=%d)", astrosInstance->feaProblem.feaAnalysis[i].analysisID);
2078
2079 if (optFlag == 0) {
2080 fprintf(fp, "\n");
2081 fprintf(fp, " PRINT DISP=ALL, GPWG=ALL, TRIM, TPRE=ALL, STRESS=ALL\n");
2082 } else {
2083 fprintf(fp, ", CONST(STRESS = %d)\n", astrosInstance->feaProblem.numDesignConstraint+i+1);
2084 fprintf(fp, " PRINT (ITER=LAST) DISP=ALL, GPWG=ALL, TRIM, TPRE=ALL, STRESS=ALL\n");
2085 }
2086
2087 }
2088
2089 if (astrosInstance->feaProblem.feaAnalysis[i].analysisType
45.1
Field 'analysisType' is not equal to AeroelasticFlutter
== AeroelasticFlutter) {// Flutter
46
Taking false branch
2090 fprintf(fp, " MODES\n");
2091 fprintf(fp, " FLUTTER (FLCOND = %d)\n", astrosInstance->feaProblem.feaAnalysis[i].analysisID);
2092 fprintf(fp, " PRINT (MODES=ALL) DISP=ALL, ROOT=ALL\n");
2093 }
2094 }
2095
2096// } else { // If no sub-cases
2097//
2098// if (strcasecmp(analysisType, "Modal") == 0) {
2099// printf("Warning: No eigenvalue analysis information specified in \"Analysis\" tuple, through "
2100// "AIM input \"Analysis_Type\" is set to \"Modal\"!!!!\n");
2101// return CAPS_NOTFOUND;
2102// }
2103//
2104// fprintf(fp, " BOUNDARY");
2105//
2106// // Write support information
2107// addComma = (int) false;
2108// if (astrosInstance->feaProblem.numSupport != 0) {
2109// if (astrosInstance->feaProblem.numSupport > 1) {
2110// printf("\tWARNING: More than 1 support is not supported at this time for a given case!\n");
2111// } else {
2112// fprintf(fp, " SUPPORT = %d ", astrosInstance->feaProblem.numSupport+1);
2113// addComma = (int) true;
2114// }
2115// }
2116//
2117// // Write constraint information
2118// if (astrosInstance->feaProblem.numConstraint != 0) {
2119// if (addComma == (int) true) fprintf(fp, ",");
2120// fprintf(fp, " SPC = %d ", astrosInstance->feaProblem.numConstraint+1);
2121// } else {
2122// printf("\tWarning: No constraints specified for job!!!!\n");
2123// }
2124//
2125// // Write MPC for sub-case - currently only supported when we have RBE2 elements - see above for unification
2126// for (j = 0; j < astrosInstance->feaProblem.numConnect; j++) {
2127//
2128// if (astrosInstance->feaProblem.feaConnect[j].connectionType == RigidBody) {
2129//
2130// if (addComma == (int) true) fprintf(fp,",");
2131//
2132// fprintf(fp, " MPC = %d ", astrosInstance->feaProblem.feaConnect[j].connectionID);
2133// addComma = (int) true;
2134// break;
2135// }
2136// }
2137//
2138// fprintf(fp, "\n");
2139//
2140// // Write discipline
2141// if (strcasecmp(analysisType, "Static") == 0) { // Static loads
2142//
2143// fprintf(fp, " STATICS");
2144//
2145// // Write loads for sub-case
2146// if (astrosInstance->feaProblem.numLoad != 0) {
2147// fprintf(fp, "(");
2148//
2149// addComma = (int) false;
2150//
2151// k = 0;
2152// for (j = 0; j < astrosInstance->feaProblem.numLoad; j++) {
2153// if (feaLoad[j].loadType == Thermal) {
2154//
2155// if (addComma == (int) true) fprintf(fp, ",");
2156// fprintf(fp, " THERMAL = %d", feaLoad[j].loadID);
2157// addComma = (int) true;
2158//
2159// numThermalLoad += 1;
2160// if (numThermalLoad > 1) {
2161// printf("More than 1 Thermal load found - astrosAIM does NOT currently doesn't support multiple thermal loads!\n");
2162// }
2163//
2164// continue;
2165// }
2166//
2167// if (feaLoad[j].loadType == Gravity) {
2168// if (addComma == (int) true) fprintf(fp, ",");
2169// fprintf(fp, " GRAVITY = %d", feaLoad[j].loadID);
2170// addComma = (int) true;
2171// continue;
2172// }
2173//
2174// numGravityLoad += 1;
2175// if (numGravityLoad > 1) {
2176// printf("More than 1 Gravity load found - astrosAIM does NOT currently doesn't support multiple gravity loads!\n");
2177// }
2178//
2179// k += 1;
2180// }
2181//
2182// if (k != 0) {
2183// if (addComma == (int) true) fprintf(fp, ",");
2184// fprintf(fp, " MECH = %d", astrosInstance->feaProblem.numLoad+1);
2185// }
2186//
2187// fprintf(fp,")");
2188// } else {
2189// printf("\tWarning: No loads specified for job!!!!\n");
2190// }
2191//
2192// fprintf(fp, "\n");
2193//
2194// fprintf(fp, " PRINT DISP=ALL, STRESS=ALL\n");
2195// }
2196// }
2197
2198
2199 fprintf(fp, "END\n$\n"); // End Case control
2200
2201 //////////////// Bulk data ////////////////
2202 fprintf(fp, "BEGIN BULK(SORT)\n");
2203 fprintf(fp, "$---1---|---2---|---3---|---4---|---5---|---6---|---7---|---8---|---9---|---10--|\n");
2204
2205 //PRINT Parameter ENTRIES IN BULK DATA
2206
2207 if (aimInputs[Parameter-1].nullVal == NotNull) {
49
Assuming field 'nullVal' is not equal to NotNull
50
Taking false branch
2208 for (i = 0; i < aimInputs[Parameter-1].length; i++) {
2209 noQuoteString = string_removeQuotation(aimInputs[Parameter-1].vals.tuple[i].value);
2210 AIM_NOTNULL(noQuoteString, aimInfo, status){ if (noQuoteString == ((void*)0)) { status = -307; aim_status
(aimInfo, status, "astrosAIM.c", 2210, __func__, 1, "%s == NULL!"
, "noQuoteString"); goto cleanup; } }
;
2211 fprintf(fp, "%s, %s\n", aimInputs[Parameter-1].vals.tuple[i].name, noQuoteString);
2212 EG_free(noQuoteString);
2213 }
2214 }
2215
2216 // Turn off auto SPC
2217 //fprintf(fp, "%-8s %7s %7s\n", "PARAM", "AUTOSPC", "N");
2218
2219 // Optimization Objective Response Response, SOL 200 only
2220 if (strcasecmp(analysisType, "StaticOpt") == 0 || strcasecmp(analysisType, "Optimization") == 0) {
2221 /*
2222 objectiveResp = aimInputs[ObjectiveResponseType-1].vals.string;
2223 if (strcasecmp(objectiveResp, "Weight") == 0) objectiveResp = "WEIGHT";
2224 else {
2225 AIM_ERROR(aimInfo, "\tUnrecognized \"ObjectiveResponseType\", %s\n", objectiveResp);
2226 status = CAPS_BADVALUE;
2227 goto cleanup;
2228 }
2229
2230 fprintf(fp,"%-8s", "DRESP1");
2231
2232 tempString = convert_integerToString(1, 7, 1);
2233 fprintf(fp, "%s%s", delimiter, tempString);
2234 EG_free(tempString);
2235
2236 fprintf(fp, "%s%7s", delimiter, objectiveResp);
2237 fprintf(fp, "%s%7s", delimiter, objectiveResp);
2238
2239
2240 fprintf(fp, "\n");
2241 */
2242 }
2243
2244 // Write AERO Card
2245 if (strcasecmp(analysisType, "AeroelasticFlutter") == 0 ) {
51
Assuming the condition is false
52
Taking false branch
2246
2247 printf("\tWriting aero card\n");
2248 status = astros_writeAEROCard(fp,
2249 &astrosInstance->feaProblem.feaAeroRef,
2250 &astrosInstance->feaProblem.feaFileFormat);
2251 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2251, __func__, 0); goto cleanup; }
;
2252 }
2253
2254 // Write AESTAT and AESURF cards
2255 if (strcasecmp(analysisType, "Aeroelastic") == 0 ||
53
Assuming the condition is false
56
Taking false branch
2256 strcasecmp(analysisType, "AeroelasticTrim") == 0 ||
54
Assuming the condition is false
2257 strcasecmp(analysisType, "AeroelasticTrimOpt") == 0) {
55
Assuming the condition is false
2258
2259 printf("\tWriting aeros card\n");
2260 status = astros_writeAEROSCard(fp,
2261 &astrosInstance->feaProblem.feaAeroRef,
2262 &astrosInstance->feaProblem.feaFileFormat);
2263 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2263, __func__, 0); goto cleanup; }
;
2264
2265 // No AESTAT Cards in ASTROS
2266
2267
2268 // fprintf(fp,"\n");
2269 }
2270
2271 // Analysis Cards - Eigenvalue and design objective included, as well as combined load, constraint, and design constraints
2272 for (i = 0; i < astrosInstance->feaProblem.numAnalysis; i++) {
57
Loop condition is true. Entering loop body
2273
2274 if (i
57.1
'i' is equal to 0
== 0) printf("\tWriting analysis cards\n");
58
Taking true branch
2275
2276 status = astros_writeAnalysisCard(fp,
2277 &astrosInstance->feaProblem.feaAnalysis[i],
2278 &astrosInstance->feaProblem.feaFileFormat);
2279 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2279, __func__, 0); goto cleanup; }
;
59
Assuming 'status' is equal to 0
60
Taking false branch
2280
2281 if (astrosInstance->feaProblem.feaAnalysis[i].numLoad != 0) {
61
Assuming field 'numLoad' is not equal to 0
62
Taking true branch
2282
2283 // Create a temporary list of load IDs
2284 tempIntegerArray = (int *) EG_alloc(astrosInstance->feaProblem.feaAnalysis[i].numLoad*sizeof(int));
2285 if (tempIntegerArray == NULL((void*)0)) {
63
Assuming 'tempIntegerArray' is not equal to NULL
64
Taking false branch
2286 status = EGADS_MALLOC-4;
2287 goto cleanup;
2288 }
2289
2290 k = 0;
2291 for (j = 0; j < astrosInstance->feaProblem.feaAnalysis[i].numLoad; j++) {
65
Assuming 'j' is < field 'numLoad'
66
Loop condition is true. Entering loop body
2292 for (l = 0; l < astrosInstance->feaProblem.numLoad; l++) {
67
Assuming 'l' is < field 'numLoad'
68
Loop condition is true. Entering loop body
2293 if (astrosInstance->feaProblem.feaAnalysis[i].loadSetID[j] == feaLoad[l].loadID) break;
69
Dereference of null pointer
2294 }
2295
2296 if (l >= astrosInstance->feaProblem.numLoad) continue;
2297 if (feaLoad[l].loadType == Gravity) continue;
2298 if (feaLoad[l].loadType == Thermal) continue;
2299 tempIntegerArray[k] = feaLoad[l].loadID;
2300 k += 1;
2301 }
2302
2303 tempIntegerArray = (int *) EG_reall(tempIntegerArray, k*sizeof(int));
2304 if (tempIntegerArray == NULL((void*)0)) {
2305 status = EGADS_MALLOC-4;
2306 goto cleanup;
2307 }
2308
2309 // Write combined load card
2310 printf("\tWriting load ADD cards\n");
2311 status = nastran_writeLoadADDCard(fp,
2312 astrosInstance->feaProblem.numLoad+i+1,
2313 k,
2314 tempIntegerArray,
2315 feaLoad,
2316 &astrosInstance->feaProblem.feaFileFormat);
2317
2318 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2318, __func__, 0); goto cleanup; }
;
2319
2320 // Free temporary load ID list
2321 EG_free(tempIntegerArray);
2322 tempIntegerArray = NULL((void*)0);
2323
2324 } else { // If no loads for an individual analysis are specified assume that all loads should be applied
2325
2326 if (astrosInstance->feaProblem.numLoad != 0) {
2327
2328 // Create a temporary list of load IDs
2329 tempIntegerArray = (int *) EG_alloc(astrosInstance->feaProblem.numLoad*sizeof(int));
2330 if (tempIntegerArray == NULL((void*)0)) {
2331 status = EGADS_MALLOC-4;
2332 goto cleanup;
2333 }
2334
2335 k = 0;
2336 for (j = 0; j < astrosInstance->feaProblem.numLoad; j++) {
2337 if (feaLoad[j].loadType == Gravity) continue;
2338 if (feaLoad[j].loadType == Thermal) continue;
2339 tempIntegerArray[k] = feaLoad[j].loadID;
2340 k += 1;
2341 }
2342
2343 tempIntegerArray = (int *) EG_reall(tempIntegerArray, k*sizeof(int));
2344 if (tempIntegerArray == NULL((void*)0)) {
2345 status = EGADS_MALLOC-4;
2346 goto cleanup;
2347 }
2348
2349 //TOOO: eliminate load add card?
2350 // Write combined load card
2351 printf("\tWriting load ADD cards\n");
2352 status = nastran_writeLoadADDCard(fp,
2353 astrosInstance->feaProblem.numLoad+i+1,
2354 k,
2355 tempIntegerArray,
2356 feaLoad,
2357 &astrosInstance->feaProblem.feaFileFormat);
2358
2359 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2359, __func__, 0); goto cleanup; }
;
2360
2361 // Free temporary load ID list
2362 EG_free(tempIntegerArray);
2363 tempIntegerArray = NULL((void*)0);
2364 }
2365
2366 }
2367
2368 if (astrosInstance->feaProblem.feaAnalysis[i].numConstraint != 0) {
2369
2370 // Write combined constraint card
2371 printf("\tWriting constraint cards--each subcase individually\n");
2372 fprintf(fp,"$\n$ Constraint(s)\n");
2373
2374 for (j = 0; j < astrosInstance->feaProblem.feaAnalysis[i].numConstraint; j++) {
2375 k = astrosInstance->feaProblem.feaAnalysis[i].constraintSetID[j] - 1;
2376
2377 // one spc set per subcase, each different
2378 status = astros_writeConstraintCard(fp,
2379 astrosInstance->feaProblem.numConstraint+i+1,
2380 &astrosInstance->feaProblem.feaConstraint[k],
2381 &astrosInstance->feaProblem.feaFileFormat);
2382 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2382, __func__, 0); goto cleanup; }
;
2383 }
2384
2385// printf("\tWriting constraint ADD cards\n");
2386// status = nastran_writeConstraintADDCard(fp,
2387// astrosInstance->feaProblem.numConstraint+i+1,
2388// astrosInstance->feaProblem.feaAnalysis[i].numConstraint,
2389// astrosInstance->feaProblem.feaAnalysis[i].constraintSetID,
2390// &astrosInstance->feaProblem.feaFileFormat);
2391// AIM_STATUS(aimInfo, status);
2392
2393 } else { // If no constraints for an individual analysis are specified assume that all constraints should be applied
2394
2395 if (astrosInstance->feaProblem.numConstraint != 0) {
2396
2397 // Write combined constraint card
2398 printf("\tWriting constraint cards--all constraints for each subcase\n");
2399 fprintf(fp,"$\n$ Constraint(s)\n");
2400
2401 for (j = 0; j < astrosInstance->feaProblem.numConstraint; j++) {
2402
2403 // one spc set per subcase, each the same
2404 status = astros_writeConstraintCard(fp,
2405 astrosInstance->feaProblem.numConstraint+i+1,
2406 &astrosInstance->feaProblem.feaConstraint[j],
2407 &astrosInstance->feaProblem.feaFileFormat);
2408 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2408, __func__, 0); goto cleanup; }
;
2409 }
2410 }
2411 }
2412
2413 if (astrosInstance->feaProblem.feaAnalysis[i].numDesignConstraint != 0) {
2414
2415 printf("\tWriting design constraint cards--no subcases\n");
2416 fprintf(fp,"$\n$ Design constraint(s)\n");
2417 for( j = 0; j < astrosInstance->feaProblem.feaAnalysis[i].numDesignConstraint; j++) {
2418 k = astrosInstance->feaProblem.feaAnalysis[i].designConstraintSetID[j] - 1;
2419
2420 // one design constraint set per subcase analysis, each may be different
2421 status = astros_writeDesignConstraintCard(fp,
2422 astrosInstance->feaProblem.numDesignConstraint+i+1,
2423 &astrosInstance->feaProblem.feaDesignConstraint[k],
2424 astrosInstance->feaProblem.numMaterial,
2425 astrosInstance->feaProblem.feaMaterial,
2426 astrosInstance->feaProblem.numProperty,
2427 astrosInstance->feaProblem.feaProperty,
2428 &astrosInstance->feaProblem.feaFileFormat);
2429 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2429, __func__, 0); goto cleanup; }
;
2430 }
2431
2432 } else { // If no design constraints for an individual analysis are specified assume that all design constraints should be applied
2433
2434 if (astrosInstance->feaProblem.numDesignConstraint != 0) {
2435
2436 printf("\tWriting design constraint cards\n");
2437 fprintf(fp,"$\n$ Design constraint(s)\n");
2438 for( j = 0; j < astrosInstance->feaProblem.numDesignConstraint; j++) {
2439
2440 // one design constraint set per subcase analysis, all the same
2441 status = astros_writeDesignConstraintCard(fp,
2442 astrosInstance->feaProblem.numDesignConstraint+i+1,
2443 &astrosInstance->feaProblem.feaDesignConstraint[j],
2444 astrosInstance->feaProblem.numMaterial,
2445 astrosInstance->feaProblem.feaMaterial,
2446 astrosInstance->feaProblem.numProperty,
2447 astrosInstance->feaProblem.feaProperty,
2448 &astrosInstance->feaProblem.feaFileFormat);
2449 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2449, __func__, 0); goto cleanup; }
;
2450 }
2451 }
2452
2453 }
2454 }
2455
2456 // Loads
2457 for (i = 0; i < astrosInstance->feaProblem.numLoad; i++) {
2458
2459 if (i == 0) {
2460 printf("\tWriting load cards\n");
2461 fprintf(fp,"$\n$ Load(s)\n");
2462 }
2463
2464 status = astros_writeLoadCard(fp,
2465 &astrosInstance->feaProblem.feaMesh,
2466 &feaLoad[i],
2467 &astrosInstance->feaProblem.feaFileFormat);
2468 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2468, __func__, 0); goto cleanup; }
;
2469 }
2470
2471 // Constraints
2472 // Move to subcase level because ASTROS does not support SPCADD card--DB 8 Mar 18
2473 /* for (i = 0; i < astrosInstance->feaProblem.numConstraint; i++) {
2474
2475 if (i == 0) {
2476 printf("\tWriting constraint cards\n");
2477 fprintf(fp,"$\n$ Constraint(s)\n");
2478 }
2479
2480 status = nastran_writeConstraintCard(fp,
2481 &astrosInstance->feaProblem.feaConstraint[i],
2482 &astrosInstance->feaProblem.feaFileFormat);
2483 AIM_STATUS(aimInfo, status);
2484 } */
2485
2486 // Supports
2487 for (i = 0; i < astrosInstance->feaProblem.numSupport; i++) {
2488
2489 if (i == 0) {
2490 printf("\tWriting support cards\n");
2491 fprintf(fp,"$\n$ Support(s)\n");
2492 }
2493
2494 status = astros_writeSupportCard(fp,
2495 &astrosInstance->feaProblem.feaSupport[i],
2496 &astrosInstance->feaProblem.feaFileFormat);
2497 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2497, __func__, 0); goto cleanup; }
;
2498 }
2499
2500
2501 // Materials
2502 for (i = 0; i < astrosInstance->feaProblem.numMaterial; i++) {
2503
2504 if (i == 0) {
2505 printf("\tWriting material cards\n");
2506 fprintf(fp,"$\n$ Material(s)\n");
2507 }
2508
2509 status = nastran_writeMaterialCard(fp,
2510 &astrosInstance->feaProblem.feaMaterial[i],
2511 &astrosInstance->feaProblem.feaFileFormat);
2512 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2512, __func__, 0); goto cleanup; }
;
2513 }
2514
2515 // Properties
2516 for (i = 0; i < astrosInstance->feaProblem.numProperty; i++) {
2517
2518 if (i == 0) {
2519 printf("\tWriting property cards\n");
2520 fprintf(fp,"$\n$ Property(ies)\n");
2521 }
2522
2523 status = astros_writePropertyCard(fp,
2524 &astrosInstance->feaProblem.feaProperty[i],
2525 &astrosInstance->feaProblem.feaFileFormat,
2526 astrosInstance->feaProblem.numDesignVariable,
2527 astrosInstance->feaProblem.feaDesignVariable);
2528 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2528, __func__, 0); goto cleanup; }
;
2529 }
2530
2531 // Coordinate systems
2532 for (i = 0; i < astrosInstance->feaProblem.numCoordSystem; i++) {
2533
2534 if (i == 0) {
2535 printf("\tWriting coordinate system cards\n");
2536 fprintf(fp,"$\n$ Coordinate system(s)\n");
2537 }
2538
2539 status = nastran_writeCoordinateSystemCard(fp, &astrosInstance->feaProblem.feaCoordSystem[i], &astrosInstance->feaProblem.feaFileFormat);
2540 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2540, __func__, 0); goto cleanup; }
;
2541 }
2542
2543 // Optimization - design variables
2544 for (i = 0; i < astrosInstance->feaProblem.numDesignVariable; i++) {
2545
2546 if (i == 0) {
2547 printf("\tWriting design variables and analysis - design variable relation cards\n");
2548 fprintf(fp,"$\n$ Design variable(s)\n");
2549 }
2550
2551 status = astros_writeDesignVariableCard(fp,
2552 &astrosInstance->feaProblem.feaDesignVariable[i],
2553 astrosInstance->feaProblem.numProperty,
2554 astrosInstance->feaProblem.feaProperty,
2555 &astrosInstance->feaProblem.feaFileFormat);
2556 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2556, __func__, 0); goto cleanup; }
;
2557 }
2558
2559 // Optimization - design variables - geometry
2560 nGeomIn = aim_getIndex(aimInfo, NULL((void*)0), GEOMETRYIN);
2561 if (nGeomIn > 0) {
2562 status = aim_getValue(aimInfo, 1, GEOMETRYIN, &geomInVal);
2563 if (status != CAPS_SUCCESS0) {
2564 printf("Error: Cannot get Geometry In Value Structures\n");
2565 nGeomIn = 0;
2566 }
2567 }
2568 for (i = 0; i < astrosInstance->feaProblem.numDesignVariable; i++) {
2569
2570 // Geometric parameterization - only if needed
2571 for (j = 0; j < nGeomIn; j++) {
2572
2573 status = aim_getName(aimInfo, j+1, GEOMETRYIN, &geomInName);
2574 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2574, __func__, 0); goto cleanup; }
;
2575
2576 if (strcmp(astrosInstance->feaProblem.feaDesignVariable[i].name, geomInName) == 0) break;
2577 }
2578
2579 // If name isn't found in Geometry inputs skip write geometric design variables
2580 if (j >= nGeomIn) continue;
2581
2582 if(aim_getGeomInType(aimInfo, j+1) != 0) {
2583 printf("Error: Geometric sensitivity not available for CFGPMTR = %s\n", geomInName);
2584 status = CAPS_NOSENSITVTY-340;
2585 goto cleanup;
2586 }
2587
2588 printf(">>> Writing geometry parametrization\n");
2589 status = astros_writeGeomParametrization(fp,
2590 aimInfo,
2591 astrosInstance->feaProblem.numDesignVariable,
2592 astrosInstance->feaProblem.feaDesignVariable,
2593 nGeomIn, geomInVal,
2594 &astrosInstance->feaProblem.feaMesh,
2595 &astrosInstance->feaProblem.feaFileFormat);
2596 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2596, __func__, 0); goto cleanup; }
;
2597 printf(">>> Done writing geometry parametrization\n");
2598
2599 break; // Only need to call astros_writeGeomParametrization once!
2600 }
2601
2602 // Optimization - design constraints
2603 // Move to subcase level because ASTROS does not support DCONADD card--DB 7 Mar 18
2604 /* for( i = 0; i < astrosInstance->feaProblem.numDesignConstraint; i++) {
2605
2606 if (i == 0) {
2607 printf("\tWriting design constraints and responses cards\n");
2608 fprintf(fp,"$\n$ Design constraint(s)\n");
2609 }
2610
2611 status = astros_writeDesignConstraintCard(fp,
2612 &astrosInstance->feaProblem.feaDesignConstraint[i],
2613 astrosInstance->feaProblem.numMaterial,
2614 astrosInstance->feaProblem.feaMaterial,
2615 astrosInstance->feaProblem.numProperty,
2616 astrosInstance->feaProblem.feaProperty,
2617 &astrosInstance->feaProblem.feaFileFormat);
2618 AIM_STATUS(aimInfo, status);
2619 } */
2620
2621 // Aeroelastic
2622 if (strcasecmp(analysisType, "Aeroelastic") == 0 ||
2623 strcasecmp(analysisType, "AeroelasticTrim") == 0 ||
2624 strcasecmp(analysisType, "AeroelasticTrimOpt") == 0 ) {
2625
2626 printf("\tWriting aeroelastic cards\n");
2627 for (i = 0; i < astrosInstance->feaProblem.numAero; i++){
2628
2629 status = astros_writeCAeroCard(fp,
2630 &astrosInstance->feaProblem.feaAero[i],
2631 &astrosInstance->feaProblem.feaFileFormat);
2632 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2632, __func__, 0); goto cleanup; }
;
2633
2634 status = astros_checkAirfoil(aimInfo,
2635 &astrosInstance->feaProblem.feaAero[i]);
2636 if (status == CAPS_SOURCEERR-330) {
2637
2638 j = (int) false0;
2639 printf("\tBody topology used in aerodynamic surface %d, isn't suitable for airfoil shape, switching to panel", i+1);
2640
2641 } else if (status != CAPS_SUCCESS0) {
2642
2643 goto cleanup;
2644
2645 } else {
2646
2647 j = (int) true1;
2648 }
2649
2650 status = astros_writeAirfoilCard(fp,
2651 j, // useAirfoilShape
2652 &astrosInstance->feaProblem.feaAero[i],
2653 &astrosInstance->feaProblem.feaFileFormat);
2654 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2654, __func__, 0); goto cleanup; }
;
2655
2656 status = astros_writeAeroData(aimInfo,
2657 fp,
2658 j, // useAirfoilShape
2659 &astrosInstance->feaProblem.feaAero[i],
2660 &astrosInstance->feaProblem.feaFileFormat);
2661 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2661, __func__, 0); goto cleanup; }
;
2662
2663 status = astros_writeAeroSplineCard(fp,
2664 &astrosInstance->feaProblem.feaAero[i],
2665 &astrosInstance->feaProblem.feaFileFormat);
2666 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2666, __func__, 0); goto cleanup; }
;
2667
2668 status = nastran_writeSet1Card(fp,
2669 &astrosInstance->feaProblem.feaAero[i],
2670 &astrosInstance->feaProblem.feaFileFormat);
2671 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2671, __func__, 0); goto cleanup; }
;
2672 }
2673 }
2674
2675 // Aeroelastic
2676 if (strcasecmp(analysisType, "AeroelasticFlutter") == 0) {
2677
2678 printf("\tWriting unsteady aeroelastic cards\n");
2679 for (i = 0; i < astrosInstance->feaProblem.numAero; i++){
2680
2681 status = nastran_writeCAeroCard(fp,
2682 &astrosInstance->feaProblem.feaAero[i],
2683 &astrosInstance->feaProblem.feaFileFormat);
2684 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2684, __func__, 0); goto cleanup; }
;
2685
2686 status = astros_writeAeroSplineCard(fp,
2687 &astrosInstance->feaProblem.feaAero[i],
2688 &astrosInstance->feaProblem.feaFileFormat);
2689 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2689, __func__, 0); goto cleanup; }
;
2690
2691 status = nastran_writeSet1Card(fp,
2692 &astrosInstance->feaProblem.feaAero[i],
2693 &astrosInstance->feaProblem.feaFileFormat);
2694 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2694, __func__, 0); goto cleanup; }
;
2695 }
2696 }
2697
2698 // Include mesh file
2699 fprintf(fp,"$\nINCLUDE %s.bdf\n$\n", astrosInstance->projectName);
2700
2701 // End bulk data
2702 fprintf(fp,"ENDDATA\n");
2703
2704 fclose(fp);
2705 fp = NULL((void*)0);
2706/*
2707////////////////////////////////////////
2708 printf("\n\n\nTESTING OUT READER\n\n");
2709
2710 // FO6 data variables
2711 int numGridPoint = 0;
2712 int numEigenVector = 0;
2713 double **dataMatrix = NULL;
2714 filename = (char *) EG_alloc((strlen(astrosInstance->projectName) +
2715 strlen(".out") + 2)*sizeof(char));
2716
2717 sprintf(filename, "%s%s", astrosInstance->projectName, ".out");
2718
2719 // Open file
2720 fp = aim_fopen(aimInfo, filename, "r");
2721 if (filename != NULL) EG_free(filename);
2722 filename = NULL;
2723
2724 if (fp == NULL) {
2725 printf("Unable to open file: %s\n", filename);
2726
2727 return CAPS_IOERR;
2728 }
2729
2730 status = astros_readOUTDisplacement(fp,
2731 -9,
2732 &numGridPoint,
2733 &dataMatrix);
2734
2735 for ( i = 0 ; i < numGridPoint ; i++) printf("dataMatrix = %f %f %f %f %f %f %f %f\n",
2736 dataMatrix[i][0],
2737 dataMatrix[i][1],
2738 dataMatrix[i][2],
2739 dataMatrix[i][3],
2740 dataMatrix[i][4],
2741 dataMatrix[i][5],
2742 dataMatrix[i][6],
2743 dataMatrix[i][7]);
2744 fclose(fp);
2745///////////////////////////////////
2746*/
2747
2748 status = CAPS_SUCCESS0;
2749
2750cleanup:
2751 for (i = 0; i < astrosInstance->feaProblem.numLoad; i++) {
2752 destroy_feaLoadStruct(&feaLoad[i]);
2753 }
2754 AIM_FREE(feaLoad){ EG_free(feaLoad); feaLoad = ((void*)0); };
2755
2756 if (fp != NULL((void*)0)) fclose(fp);
2757
2758 AIM_FREE(tempIntegerArray){ EG_free(tempIntegerArray); tempIntegerArray = ((void*)0); };
2759 AIM_FREE(filename){ EG_free(filename); filename = ((void*)0); };
2760
2761 return status;
2762}
2763
2764
2765// ********************** AIM Function Break *****************************
2766int aimExecute(/*@unused@*/ const void *instStore, /*@unused@*/ void *aimInfo,
2767 int *state)
2768{
2769 /*! \page aimExecuteAstros AIM Execution
2770 *
2771 * If auto execution is enabled when creating an Astros AIM,
2772 * the AIM will execute Astros just-in-time with the command line:
2773 *
2774 * \code{.sh}
2775 * $ASTROS_ROOT/astros < $Proj_Name.dat > $Proj_Name.out
2776 * \endcode
2777 *
2778 * where preAnalysis generated the file Proj_Name + ".dat" which contains the input information.
2779 * The environemtn variable ASTROS_ROOT is assumed to point to the location where the
2780 * "astros.exe" executable and run files "ASTRO.D01" and "ASTRO.IDX" are located.
2781 *
2782 * The analysis can be also be explicitly executed with caps_execute in the C-API
2783 * or via Analysis.runAnalysis in the pyCAPS API.
2784 *
2785 * Calling preAnalysis and postAnalysis is NOT allowed when auto execution is enabled.
2786 *
2787 * Auto execution can also be disabled when creating an Astros AIM object.
2788 * In this mode, caps_execute and Analysis.runAnalysis can be used to run the analysis,
2789 * or Astros can be executed by calling preAnalysis, system call, and posAnalysis as demonstrated
2790 * below with a pyCAPS example:
2791 *
2792 * \code{.py}
2793 * print ("\n\preAnalysis......")
2794 * astros.preAnalysis()
2795 *
2796 * print ("\n\nRunning......")
2797 * astros.system(ASTROS_ROOT + os.sep + "astros.exe < " + astros.input.Proj_Name + ".dat > " + astros.input.Proj_Name + ".out"); # Run via system call
2798 *
2799 * print ("\n\postAnalysis......")
2800 * astros.postAnalysis()
2801 * \endcode
2802 */
2803
2804 int status = CAPS_SUCCESS0;
2805 char command[PATH_MAX4096], *env;
2806 aimStorage *astrosInstance;
2807 *state = 0;
2808
2809 astrosInstance = (aimStorage *) instStore;
2810 if (astrosInstance == NULL((void*)0)) return CAPS_NULLVALUE-307;
2811
2812 env = getenv("ASTROS_ROOT");
2813 if (env == NULL((void*)0)) {
2814 AIM_ERROR(aimInfo, "ASTROS_ROOT environment variable is not set!"){ aim_message(aimInfo, CERROR, 0 , "astrosAIM.c", 2814, __func__
, "ASTROS_ROOT environment variable is not set!"); }
;
2815 return CAPS_EXECERR-335;
2816 }
2817
2818 snprintf(command, PATH_MAX4096, "%s%cASTRO.D01", env, SLASH'/');
2819 status = aim_cpFile(aimInfo, command, "");
2820 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2820, __func__, 0); goto cleanup; }
;
2821
2822 snprintf(command, PATH_MAX4096, "%s%cASTRO.IDX", env, SLASH'/');
2823 status = aim_cpFile(aimInfo, command, "");
2824 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "astrosAIM.c",
2824, __func__, 0); goto cleanup; }
;
2825
2826 snprintf(command, PATH_MAX4096, "%s%castros.exe < %s.dat > %s.out",
2827 env, SLASH'/', astrosInstance->projectName, astrosInstance->projectName);
2828
2829 return aim_system(aimInfo, NULL((void*)0), command);
2830
2831cleanup:
2832 return status;
2833}
2834
2835
2836// ********************** AIM Function Break *****************************
2837// Check that astros ran without errors
2838int
2839aimPostAnalysis(void *instStore, /*@unused@*/ void *aimInfo,
2840 /*@unused@*/ int restart, /*@unused@*/ capsValue *inputs)
2841{
2842 int status = CAPS_SUCCESS0;
2843
2844 char *filename = NULL((void*)0); // File to open
2845 char extOUT[] = ".out";
2846 FILE *fp = NULL((void*)0); // File pointer
2847 aimStorage *astrosInstance;
2848
2849 size_t linecap = 0;
2850 char *line = NULL((void*)0); // Temporary line holder
2851 int withErrors = (int) false0;
2852 int terminated = (int) false0;
2853
2854#ifdef DEBUG
2855 printf(" astrosAIM/aimPostAnalysis!\n");
2856#endif
2857 astrosInstance = (aimStorage *) instStore;
2858
2859 filename = (char *) EG_alloc((strlen(astrosInstance->projectName) +
2860 strlen(extOUT) +1)*sizeof(char));
2861 if (filename == NULL((void*)0)) return EGADS_MALLOC-4;
2862
2863 sprintf(filename, "%s%s", astrosInstance->projectName, extOUT);
2864
2865 fp = aim_fopen(aimInfo, filename, "r");
2866
2867 EG_free(filename); // Free filename allocation
2868
2869 if (fp == NULL((void*)0)) {
2870 AIM_ERROR(aimInfo, " astrosAIM/aimPostAnalysis Cannot open Output file!"){ aim_message(aimInfo, CERROR, 0 , "astrosAIM.c", 2870, __func__
, " astrosAIM/aimPostAnalysis Cannot open Output file!"); }
;
2871
2872 return CAPS_IOERR-332;
2873 }
2874
2875 // Scan the file for the string
2876/*@-nullpass@*/
2877 while( !feof(fp) ) {
2878
2879 // Get line from file
2880 status = getline(&line, &linecap, fp);
2881 if (status < 0) break;
2882
2883 if (terminated == (int) false0) terminated = (int) (strstr(line, "A S T R O S T E R M I N A T E D") != NULL((void*)0));
2884 if (withErrors == (int) false0) withErrors = (int) (strstr(line, "W I T H E R R O R S") != NULL((void*)0));
2885 }
2886/*@+nullpass@*/
2887 fclose(fp);
2888 EG_free(line);
2889 status = CAPS_SUCCESS0;
2890
2891 if (terminated == (int) false0) {
2892 AIM_ERROR(aimInfo, "Astros did not run to termination!"){ aim_message(aimInfo, CERROR, 0 , "astrosAIM.c", 2892, __func__
, "Astros did not run to termination!"); }
;
2893 status = CAPS_EXECERR-335;
2894 }
2895
2896 if (withErrors == (int) true1) {
2897 AIM_ERROR(aimInfo, ""){ aim_message(aimInfo, CERROR, 0 , "astrosAIM.c", 2897, __func__
, ""); }
;
2898 AIM_ADDLINE(aimInfo, "****************************************"){ aim_addLine(aimInfo, "****************************************"
); }
;
2899 AIM_ADDLINE(aimInfo, "*** ***"){ aim_addLine(aimInfo, "*** ***"
); }
;
2900 AIM_ADDLINE(aimInfo, "*** A S T R O S T E R M I N A T E D ***"){ aim_addLine(aimInfo, "*** A S T R O S T E R M I N A T E D ***"
); }
;
2901 AIM_ADDLINE(aimInfo, "*** W I T H E R R O R S ***"){ aim_addLine(aimInfo, "*** W I T H E R R O R S ***"
); }
;
2902 AIM_ADDLINE(aimInfo, "*** ***"){ aim_addLine(aimInfo, "*** ***"
); }
;
2903 AIM_ADDLINE(aimInfo, "****************************************"){ aim_addLine(aimInfo, "****************************************"
); }
;
2904 status = CAPS_EXECERR-335;
2905 }
2906
2907 return status;
2908}
2909
2910
2911// Set Astros output variables
2912int aimOutputs(/*@unused@*/ void *instStore, /*@unused@*/ void *aimStruc,
2913 int index, char **aoname, capsValue *form)
2914{
2915 /*! \page aimOutputsAstros AIM Outputs
2916 * The following list outlines the Astros outputs available through the AIM interface.
2917 */
2918
2919 #ifdef DEBUG
2920 printf(" astrosAIM/aimOutputs instance = %d index = %d!\n", iIndex, index);
2921 #endif
2922
2923 /*! \page aimOutputsAstros AIM Outputs
2924 * - <B>EigenValue</B> = List of Eigen-Values (\f$ \lambda\f$) after a modal solve.
2925 * - <B>EigenRadian</B> = List of Eigen-Values in terms of radians (\f$ \omega = \sqrt{\lambda}\f$ ) after a modal solve.
2926 * - <B>EigenFrequency</B> = List of Eigen-Values in terms of frequencies (\f$ f = \frac{\omega}{2\pi}\f$) after a modal solve.
2927 * - <B>EigenGeneralMass</B> = List of generalized masses for the Eigen-Values.
2928 * - <B>EigenGeneralStiffness</B> = List of generalized stiffness for the Eigen-Values.
2929 * .
2930 */
2931
2932 //printf("***** index=%d *****", index);
2933
2934 if (index == 1) {
2935 *aoname = EG_strdup("EigenValue");
2936
2937 } else if (index == 2) {
2938 *aoname = EG_strdup("EigenRadian");
2939
2940 } else if (index == 3) {
2941 *aoname = EG_strdup("EigenFrequency");
2942
2943 } else if (index == 4) {
2944 *aoname = EG_strdup("EigenGeneralMass");
2945
2946 } else if (index == 5) {
2947 *aoname = EG_strdup("EigenGeneralStiffness");
2948
2949 } else if (index == 6) {
2950 *aoname = EG_strdup("Tmax");
2951
2952 } else if (index == 7) {
2953 *aoname = EG_strdup("T1max");
2954
2955 } else if (index == 8) {
2956 *aoname = EG_strdup("T2max");
2957
2958 } else if (index == 9) {
2959 *aoname = EG_strdup("T3max");
2960 }
2961
2962 //printf(" %s\n", *aoname);
2963
2964 if (index <= 5) {
2965 form->type = Double;
2966 form->units = NULL((void*)0);
2967 form->lfixed = Change;
2968 form->sfixed = Change;
2969 form->vals.reals = NULL((void*)0);
2970 form->vals.real = 0;
2971 } else {
2972 form->type = Double;
2973 form->dim = Vector;
2974 form->nrow = 1;
2975 form->ncol = 1;
2976 form->units = NULL((void*)0);
2977 form->vals.reals = NULL((void*)0);
2978 form->vals.real = 0;
2979 }
2980
2981 return CAPS_SUCCESS0;
2982}
2983
2984
2985// Calculate Astros output
2986int aimCalcOutput(void *instStore, /*@unused@*/ void *aimInfo, int index,
2987 capsValue *val)
2988{
2989 int status = CAPS_SUCCESS0; // Function return status
2990 aimStorage *astrosInstance;
2991
2992 int i; //Indexing
2993
2994 int numEigenVector;
2995 double **dataMatrix = NULL((void*)0);
2996
2997 char *filename = NULL((void*)0); // File to open
2998 char extOUT[] = ".out";
2999 FILE *fp = NULL((void*)0); // File pointer
3000
3001 astrosInstance = (aimStorage *) instStore;
3002
3003 filename = (char *) EG_alloc((strlen(astrosInstance->projectName) + strlen(extOUT) +1)*sizeof(char));
3004 if (filename == NULL((void*)0)) return EGADS_MALLOC-4;
3005
3006 sprintf(filename, "%s%s", astrosInstance->projectName, extOUT);
3007
3008 fp = aim_fopen(aimInfo, filename, "r");
3009
3010 EG_free(filename); // Free filename allocation
3011
3012 if (fp == NULL((void*)0)) {
3013#ifdef DEBUG
3014 printf(" astrosAIM/aimCalcOutput Cannot open Output file!\n");
3015#endif
3016 return CAPS_IOERR-332;
3017 }
3018
3019 if (index <= 5) {
3020
3021 status = astros_readOUTEigenValue(fp, &numEigenVector, &dataMatrix);
3022 if ((status == CAPS_SUCCESS0) && (dataMatrix != NULL((void*)0))) {
3023
3024 val->nrow = numEigenVector;
3025 val->ncol = 1;
3026 val->length = val->nrow*val->ncol;
3027 if (val->length == 1) val->dim = Scalar;
3028 else val->dim = Vector;
3029
3030 if (val->length == 1) {
3031 val->vals.real = dataMatrix[0][index-1];
3032 } else {
3033
3034 val->vals.reals = (double *) EG_alloc(val->length*sizeof(double));
3035 if (val->vals.reals != NULL((void*)0)) {
3036
3037 for (i = 0; i < val->length; i++) {
3038 val->vals.reals[i] = dataMatrix[i][index-1];
3039 }
3040
3041 } else status = EGADS_MALLOC-4;
3042 }
3043 }
3044
3045 if (dataMatrix != NULL((void*)0)) {
3046 for (i = 0; i < numEigenVector; i++) {
3047 if (dataMatrix[i] != NULL((void*)0)) EG_free(dataMatrix[i]);
3048 }
3049 EG_free(dataMatrix);
3050 }
3051
3052 } else if (index <= 9) {
3053 double T1max=0, T2max=0, T3max=0, Tmax=0, TT;
3054 int ipnt, numGridPoint;
3055
3056 status = astros_readOUTDisplacement(fp, -1, &numGridPoint, &dataMatrix);
3057 if ((status == CAPS_SUCCESS0) && (dataMatrix != NULL((void*)0))) {
3058 val->dim = Scalar;
3059 val->nrow = 1;
3060 val->ncol = 1;
3061 val->length = val->nrow * val->ncol;
3062
3063 for (ipnt = 0; ipnt < numGridPoint; ipnt++) {
3064 TT = sqrt(pow(dataMatrix[ipnt][2], 2)
3065 + pow(dataMatrix[ipnt][3], 2)
3066 + pow(dataMatrix[ipnt][4], 2));
3067
3068 if (fabs(dataMatrix[ipnt][2]) > T1max) T1max = fabs(dataMatrix[ipnt][2]);
3069 if (fabs(dataMatrix[ipnt][3]) > T2max) T2max = fabs(dataMatrix[ipnt][3]);
3070 if (fabs(dataMatrix[ipnt][4]) > T3max) T3max = fabs(dataMatrix[ipnt][4]);
3071 if (TT > Tmax ) Tmax = TT;
3072 }
3073
3074 if (index == 6) {
3075 val->vals.real = Tmax;
3076 } else if (index == 7) {
3077 val->vals.real = T1max;
3078 } else if (index == 8) {
3079 val->vals.real = T2max;
3080 } else {
3081 val->vals.real = T3max;
3082 }
3083 }
3084
3085 if (dataMatrix != NULL((void*)0)) {
3086 for (i = 0; i < numGridPoint; i++) {
3087 if (dataMatrix[i] != NULL((void*)0)) EG_free(dataMatrix[i]);
3088 }
3089 EG_free(dataMatrix);
3090 }
3091 }
3092
3093 if (fp != NULL((void*)0)) fclose(fp);
3094
3095 return status;
3096}
3097
3098
3099void aimCleanup(void *instStore)
3100{
3101 int status; // Returning status
3102 aimStorage *astrosInstance;
3103
3104#ifdef DEBUG
3105 printf(" astrosAIM/Cleanup numInstance = %d!\n", numInstance);
3106#endif
3107
3108 astrosInstance = (aimStorage *) instStore;
3109
3110 status = destroy_aimStorage(astrosInstance);
3111 if (status != CAPS_SUCCESS0)
3112 printf("Error: Status %d during clean up\n", status);
3113
3114 EG_free(astrosInstance);
3115}
3116
3117
3118int aimDiscr(char *tname, capsDiscr *discr) {
3119
3120 int status; // Function return status
3121
3122 int numBody, i;
3123 aimStorage *astrosInstance;
3124
3125 // EGADS objects
3126 ego *bodies = NULL((void*)0), *tess = NULL((void*)0);
3127
3128 const char *intents;
3129
3130#ifdef DEBUG
3131 printf(" astrosAIM/aimDiscr: tname = %s, instance = %d!\n", tname);
3132#endif
3133
3134 if (tname == NULL((void*)0)) return CAPS_NOTFOUND-303;
3135
3136 astrosInstance = (aimStorage *) discr->instStore;
3137
3138 /*if (astrosInstance->dataTransferCheck == (int) false) {
3139 printf("The volume is not suitable for data transfer - possibly the volume mesher "
3140 "added unaccounted for points\n");
3141 return CAPS_BADVALUE;
3142 }*/
3143
3144 // Currently this ONLY works if the capsTranfer lives on single body!
3145 status = aim_getBodies(discr->aInfo, &intents, &numBody, &bodies);
3146 AIM_STATUS(discr->aInfo, status)if (status != 0) { aim_status(discr->aInfo, status, "astrosAIM.c"
, 3146, __func__, 0); goto cleanup; }
;
3147
3148 if (bodies == NULL((void*)0)) {
3149 printf(" astrosAIM/aimDiscr: Null Bodies!\n");
3150 return CAPS_NULLOBJ-309;
3151 }
3152
3153 // Check and generate/retrieve the mesh
3154 status = checkAndCreateMesh(discr->aInfo, astrosInstance);
3155 AIM_STATUS(discr->aInfo, status)if (status != 0) { aim_status(discr->aInfo, status, "astrosAIM.c"
, 3155, __func__, 0); goto cleanup; }
;
3156
3157 AIM_ALLOC(tess, astrosInstance->numMesh, ego, discr->aInfo, status){ if (tess != ((void*)0)) { status = -4; aim_status(discr->
aInfo, status, "astrosAIM.c", 3157, __func__, 1, "AIM_ALLOC: %s != NULL"
, "tess"); goto cleanup; } size_t memorysize = astrosInstance
->numMesh; tess = (ego *) EG_alloc(memorysize*sizeof(ego))
; if (tess == ((void*)0)) { status = -4; aim_status(discr->
aInfo, status, "astrosAIM.c", 3157, __func__, 3, "AIM_ALLOC: %s size %zu type %s"
, "tess", memorysize, "ego"); goto cleanup; } }
;
3158 for (i = 0; i < astrosInstance->numMesh; i++) {
3159 tess[i] = astrosInstance->feaMesh[i].egadsTess;
3160 }
3161
3162 status = mesh_fillDiscr(tname, &astrosInstance->attrMap, astrosInstance->numMesh, tess, discr);
3163 AIM_STATUS(discr->aInfo, status)if (status != 0) { aim_status(discr->aInfo, status, "astrosAIM.c"
, 3163, __func__, 0); goto cleanup; }
;
3164
3165#ifdef DEBUG
3166 printf(" astrosAIM/aimDiscr: Instance = %d, Finished!!\n", iIndex);
3167#endif
3168
3169 status = CAPS_SUCCESS0;
3170
3171cleanup:
3172 if (status != CAPS_SUCCESS0)
3173 printf("\tPremature exit in astrosAIM aimDiscr, status = %d\n", status);
3174
3175 AIM_FREE(tess){ EG_free(tess); tess = ((void*)0); };
3176 return status;
3177}
3178
3179
3180int aimTransfer(capsDiscr *discr, const char *dataName, int numPoint,
3181 int dataRank, double *dataVal, /*@unused@*/ char **units)
3182{
3183
3184 /*! \page dataTransferAstros Astros Data Transfer
3185 *
3186 * The Astros AIM has the ability to transfer displacements and eigenvectors from the AIM and pressure
3187 * distributions to the AIM using the conservative and interpolative data transfer schemes in CAPS.
3188 *
3189 * \section dataFromAstros Data transfer from Astros (FieldOut)
3190 *
3191 * <ul>
3192 * <li> <B>"Displacement"</B> </li> <br>
3193 * Retrieves nodal displacements from the *.out file
3194 * </ul>
3195 *
3196 * <ul>
3197 * <li> <B>"EigenVector_#"</B> </li> <br>
3198 * Retrieves modal eigen-vectors from the *.out file, where "#" should be replaced by the
3199 * corresponding mode number for the eigen-vector (e.g. EigenVector_3 would correspond to the third mode,
3200 * while EigenVector_6 would be the sixth mode).
3201 * </ul>
3202 *
3203 * \section dataToAstros Data transfer to Astros (FieldIn)
3204 * <ul>
3205 * <li> <B>"Pressure"</B> </li> <br>
3206 * Writes appropriate load cards using the provided pressure distribution.
3207 * </ul>
3208 *
3209 */
3210
3211 int status; // Function return status
3212 int i, j, dataPoint, bIndex; // Indexing
3213
3214 char *extOUT = ".out";
3215
3216 // FO6 data variables
3217 int numGridPoint = 0;
3218 int numEigenVector = 0;
3219
3220 double **dataMatrix = NULL((void*)0);
3221 aimStorage *astrosInstance;
3222
3223 // Specific EigenVector to use
3224 int eigenVectorIndex = 0;
3225
3226 // Variables used in global node mapping
3227 //int *storage;
3228 int globalNodeID;
3229
3230 // Filename stuff
3231 char *filename = NULL((void*)0);
3232 FILE *fp; // File pointer
3233
3234#ifdef DEBUG
3235 printf(" astrosAIM/aimTransfer name = %s npts = %d/%d!\n",
3236 dataName, numPoint, dataRank);
3237#endif
3238 astrosInstance = (aimStorage *) discr->instStore;
3239
3240 //Get the appropriate parts of the tessellation to data
3241 //storage = (int *) discr->ptrm;
3242 //capsGroupList = &storage[1]; // List of boundary ID (attrMap) in the transfer
3243
3244 if (strcasecmp(dataName, "Displacement") != 0 &&
3245 strncmp(dataName, "EigenVector", 11) != 0) {
3246
3247 printf("Unrecognized data transfer variable - %s\n", dataName);
3248 return CAPS_NOTFOUND-303;
3249 }
3250
3251 filename = (char *) EG_alloc((strlen(astrosInstance->projectName) +
3252 strlen(extOUT) + 1)*sizeof(char));
3253 if (filename == NULL((void*)0)) return EGADS_MALLOC-4;
3254
3255 sprintf(filename, "%s%s", astrosInstance->projectName, extOUT);
3256
3257 // Open file
3258 fp = aim_fopen(discr->aInfo, filename, "r");
3259 if (fp == NULL((void*)0)) {
3260 printf("Unable to open file: %s\n", filename);
3261 if (filename != NULL((void*)0)) EG_free(filename);
3262 return CAPS_IOERR-332;
3263 }
3264
3265 if (filename != NULL((void*)0)) EG_free(filename);
3266 filename = NULL((void*)0);
3267
3268 if (strcasecmp(dataName, "Displacement") == 0) {
3269
3270 if (dataRank != 3) {
3271
3272 printf("Invalid rank for dataName \"%s\" - excepted a rank of 3!!!\n",
3273 dataName);
3274 status = CAPS_BADRANK-301;
3275
3276 } else {
3277
3278 status = astros_readOUTDisplacement(fp,
3279 -1,
3280 &numGridPoint,
3281 &dataMatrix);
3282 fclose(fp);
3283 }
3284
3285 } else if (strncmp(dataName, "EigenVector", 11) == 0) {
3286
3287 // Which EigenVector do we want ?
3288 for (i = 0; i < strlen(dataName); i++) {
3289 if (dataName[i] == '_' ) break;
3290 }
3291
3292 if (i == strlen(dataName)) {
3293 eigenVectorIndex = 1;
3294 } else {
3295
3296 status = sscanf(dataName, "EigenVector_%d", &eigenVectorIndex);
3297 if (status != 1) {
3298 printf("Unable to determine which EigenVector to use - Defaulting the first EigenVector!!!\n");
3299 eigenVectorIndex = 1;
3300 }
3301 }
3302
3303 if (dataRank != 3) {
3304
3305 printf("Invalid rank for dataName \"%s\" - excepted a rank of 3!!!\n", dataName);
3306 status = CAPS_BADRANK-301;
3307
3308 } else {
3309
3310 status = astros_readOUTEigenVector(fp,
3311 &numEigenVector,
3312 &numGridPoint,
3313 &dataMatrix);
3314 }
3315
3316 fclose(fp);
3317
3318 } else {
3319 status = CAPS_NOTFOUND-303;
3320 }
3321 AIM_STATUS(discr->aInfo, status)if (status != 0) { aim_status(discr->aInfo, status, "astrosAIM.c"
, 3321, __func__, 0); goto cleanup; }
;
3322 if (dataMatrix == NULL((void*)0)) return CAPS_NULLVALUE-307;
3323
3324 // Check EigenVector range
3325 if (strncmp(dataName, "EigenVector", 11) == 0) {
3326 if (eigenVectorIndex > numEigenVector) {
3327 AIM_ERROR(discr->aInfo, "Only %d EigenVectors found but index %d requested!",{ aim_message(discr->aInfo, CERROR, 0 , "astrosAIM.c", 3328
, __func__, "Only %d EigenVectors found but index %d requested!"
, numEigenVector, eigenVectorIndex); }
3328 numEigenVector, eigenVectorIndex){ aim_message(discr->aInfo, CERROR, 0 , "astrosAIM.c", 3328
, __func__, "Only %d EigenVectors found but index %d requested!"
, numEigenVector, eigenVectorIndex); }
;
3329 status = CAPS_RANGEERR-326;
3330 goto cleanup;
3331 }
3332
3333 if (eigenVectorIndex < 1) {
3334 AIM_ERROR(discr->aInfo, "For EigenVector_# notation, # must be >= 1, currently # = %d",{ aim_message(discr->aInfo, CERROR, 0 , "astrosAIM.c", 3335
, __func__, "For EigenVector_# notation, # must be >= 1, currently # = %d"
, eigenVectorIndex); }
3335 eigenVectorIndex){ aim_message(discr->aInfo, CERROR, 0 , "astrosAIM.c", 3335
, __func__, "For EigenVector_# notation, # must be >= 1, currently # = %d"
, eigenVectorIndex); }
;
3336 status = CAPS_RANGEERR-326;
3337 goto cleanup;
3338 }
3339 }
3340
3341 for (i = 0; i < numPoint; i++) {
3342
3343 bIndex = discr->tessGlobal[2*i ];
3344 globalNodeID = discr->tessGlobal[2*i+1] +
3345 discr->bodys[bIndex-1].globalOffset;
3346
3347 if (strcasecmp(dataName, "Displacement") == 0) {
3348
3349 for (dataPoint = 0; dataPoint < numGridPoint; dataPoint++) {
3350 if ((int) dataMatrix[dataPoint][0] == globalNodeID) break;
3351 }
3352
3353 if (dataPoint == numGridPoint) {
3354 printf("Unable to locate global ID = %d in the data matrix\n",
3355 globalNodeID);
3356 status = CAPS_NOTFOUND-303;
3357 goto cleanup;
3358 }
3359
3360 dataVal[dataRank*i+0] = dataMatrix[dataPoint][2]; // T1
3361 dataVal[dataRank*i+1] = dataMatrix[dataPoint][3]; // T2
3362 dataVal[dataRank*i+2] = dataMatrix[dataPoint][4]; // T3
3363
3364 } else if (strncmp(dataName, "EigenVector", 11) == 0) {
3365
3366 for (dataPoint = 0; dataPoint < numGridPoint; dataPoint++) {
3367 if ((int) dataMatrix[eigenVectorIndex - 1][8*dataPoint + 0] ==
3368 globalNodeID) break;
3369 }
3370
3371 if (dataPoint == numGridPoint) {
3372 printf("Unable to locate global ID = %d in the data matrix\n",
3373 globalNodeID);
3374 status = CAPS_NOTFOUND-303;
3375 goto cleanup;
3376 }
3377
3378 dataVal[dataRank*i+0] = dataMatrix[eigenVectorIndex- 1][8*dataPoint + 2]; // T1
3379 dataVal[dataRank*i+1] = dataMatrix[eigenVectorIndex- 1][8*dataPoint + 3]; // T2
3380 dataVal[dataRank*i+2] = dataMatrix[eigenVectorIndex- 1][8*dataPoint + 4]; // T3
3381 //dataVal[dataRank*i+3] = dataMatrix[eigenVectorIndex- 1][8*dataPoint + 5]; // R1 - Don't use rotations
3382 //dataVal[dataRank*i+4] = dataMatrix[eigenVectorIndex- 1][8*dataPoint + 6]; // R2
3383 //dataVal[dataRank*i+5] = dataMatrix[eigenVectorIndex- 1][8*dataPoint + 7]; // R3
3384
3385 }
3386 }
3387
3388 status = CAPS_SUCCESS0;
3389
3390cleanup:
3391 if (status != CAPS_SUCCESS0)
3392 printf("\tPremature exit in astrosAIM aimTransfer, status = %d\n", status);
3393
3394 // Free data matrix
3395 if (dataMatrix != NULL((void*)0)) {
3396 j = 0;
3397 if (strcasecmp(dataName, "Displacement") == 0) j = numGridPoint;
3398 else if (strncmp(dataName, "EigenVector", 11) == 0) j = numEigenVector;
3399
3400 for (i = 0; i < j; i++) {
3401 AIM_FREE(dataMatrix[i]){ EG_free(dataMatrix[i]); dataMatrix[i] = ((void*)0); };
3402 }
3403 AIM_FREE(dataMatrix){ EG_free(dataMatrix); dataMatrix = ((void*)0); };
3404 }
3405
3406 return status;
3407}
3408
3409
3410void aimFreeDiscrPtr(void *ptr)
3411{
3412 // Extra information to store into the discr void pointer - just a int array
3413 EG_free(ptr);
3414}
3415
3416
3417int aimLocateElement(capsDiscr *discr, double *params, double *param,
3418 int *bIndex, int *eIndex, double *bary)
3419{
3420#ifdef DEBUG
3421 printf(" astrosAIM/aimLocateElement!\n");
3422#endif
3423
3424 return aim_locateElement(discr, params, param, bIndex,eIndex, bary);
3425}
3426
3427
3428int aimInterpolation(capsDiscr *discr, const char *name,
3429 int bIndex, int eIndex, double *bary,
3430 int rank, double *data,
3431 double *result)
3432{
3433#ifdef DEBUG
3434 printf(" astrosAIM/aimInterpolation %s!\n", name);
3435#endif
3436
3437 return aim_interpolation(discr, name, bIndex, eIndex, bary, rank, data,
3438 result);
3439
3440}
3441
3442
3443int aimInterpolateBar(capsDiscr *discr, const char *name,
3444 int bIndex, int eIndex, double *bary,
3445 int rank, double *r_bar,
3446 double *d_bar)
3447{
3448#ifdef DEBUG
3449 printf(" astrosAIM/aimInterpolateBar %s!\n", name);
3450#endif
3451
3452 return aim_interpolateBar(discr, name, bIndex, eIndex, bary, rank, r_bar,
3453 d_bar);
3454}
3455
3456
3457int aimIntegration(capsDiscr *discr, const char *name,
3458 int bIndex, int eIndex, int rank,
3459 double *data, double *result)
3460{
3461#ifdef DEBUG
3462 printf(" astrosAIM/aimIntegration %s!\n", name);
3463#endif
3464 return aim_integration(discr, name, bIndex, eIndex, rank, data, result);
3465}
3466
3467
3468int aimIntegrateBar( capsDiscr *discr, const char *name,
3469 int bIndex, int eIndex, int rank,
3470 double *r_bar, double *d_bar)
3471{
3472#ifdef DEBUG
3473 printf(" astrosAIM/aimIntegrateBar %s!\n", name);
3474#endif
3475
3476 return aim_integrateBar(discr, name, bIndex, eIndex, rank, r_bar, d_bar);
3477}