Bug Summary

File:astrosAIM.c
Warning:line 2387, column 59
Value stored to 'objectiveResp' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

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