Bug Summary

File:mystranAIM.c
Warning:line 821, column 13
Dereference of null pointer

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name mystranAIM.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/mystran -ferror-limit 19 -fmessage-length 0 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/jenkins/workspace/ESP_Stanalizer/LINUX64/CAPS/scan-build/scanCAPS/2022-04-21-192420-91920-1 -x c mystranAIM.c
1/*
2 * CAPS: Computational Aircraft Prototype Syntheses
3 *
4 * mystran AIM
5 *
6 * Written by Dr. Ryan Durscher AFRL/RQVC
7 *
8 * This software has been cleared for public release on 05 Nov 2020, case number 88ABW-2020-3462.
9 */
10
11
12/*! \mainpage Introduction
13 * \tableofcontents
14 * \section overviewMYSTRAN MYSTRAN 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 MYSTRAN \cite MYSTRAN. MYSTRAN is an open source,
17 * general purpose, linear finite element analysis computer program written by Dr. Bill Case. Available at,
18 * http://www.mystran.com/, MYSTRAN currently supports Linux and Windows operating systems.
19 *
20 *
21 * An outline of the AIM's inputs, outputs and attributes are provided in \ref aimInputsMYSTRAN and
22 * \ref aimOutputsMYSTRAN and \ref attributeMYSTRAN, respectively.
23 *
24 * The MYSTRAN AIM can automatically execute MYSTRAN, with details provided in \ref aimExecuteMYSTRAN.
25 *
26 * Details of the AIM's automated data transfer capabilities are outlined in \ref dataTransferMYSTRAN
27 *
28 *\section mystranExamples Examples
29 * An example problem using the MYSTRAN AIM may be found at \ref mystranExample.
30 *
31 * \section clearanceMYSTRAN Clearance Statement
32 * This software has been cleared for public release on 05 Nov 2020, case number 88ABW-2020-3462.
33 */
34
35
36/*! \page attributeMYSTRAN MYSTRAN AIM attributes
37 * The following list of attributes are required for the MYSTRAN AIM inside the geometry input.
38 *
39 * - <b> capsAIM</b> This attribute is a CAPS requirement to indicate the analysis the geometry
40 * representation supports.
41 *
42 * - <b> capsGroup</b> This is a name assigned to any geometric body. This body could be a solid, surface, face, wire, edge or node.
43 * Recall that a string in ESP starts with a $. For example, attribute <c>capsGroup $Wing</c>.
44 *
45 * - <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>
46 * attribute to allow the user to define a local area to apply a load on without adding multiple <c>capsGroup</c> attributes.
47 * Recall that a string in ESP starts with a $. For example, attribute <c>capsLoad $force</c>.
48 *
49 * - <b> capsConstraint</b> This is a name assigned to any geometric body where a constraint/boundary condition is applied.
50 * This attribute was separated from the <c>capsGroup</c> attribute to allow the user to define a local area to apply a boundary condition
51 * without adding multiple <c>capsGroup</c> attributes. Recall that a string in ESP starts with a $. For example, attribute <c>capsConstraint $fixed</c>.
52 *
53 * - <b> capsIgnore</b> It is possible that there is a geometric body (or entity) that you do not want the MYSTRAN AIM to pay attention to when creating
54 * a finite element model. The capsIgnore attribute allows a body (or entity) to be in the geometry and ignored by the AIM. For example,
55 * because of limitations in OpenCASCADE a situation where two edges are overlapping may occur; capsIgnore allows the user to only
56 * pay attention to one of the overlapping edges.
57 *
58 * - <b> capsBound </b> This is used to mark surfaces on the structural grid in which data transfer with an external
59 * solver will take place. See \ref dataTransferMYSTRAN for additional details.
60 *
61 *
62 */
63
64// No connections yet
65/* - <b> capsConnect</b> This is a name assigned to any geometric body where the user wishes to create
66 * "fictitious" connections such as springs, dampers, and/or rigid body connections to. The user must manually specify
67 * the connection between two <c>capsConnect</c> entities using the "Connect" tuple (see \ref aimInputsMYSTRAN).
68 * Recall that a string in ESP starts with a $. For example, attribute <c>capsConnect $springStart</c>.
69 *
70 * - <b> capsConnectLink</b> Similar to <c>capsConnect</c>, this is a name assigned to any geometric body where
71 * the user wishes to create "fictitious" connections to. A connection is automatically made if a <c>capsConnectLink</c>
72 * matches a <c>capsConnect</c> group. Again further specifics of the connection are input using the "Connect"
73 * tuple (see \ref aimInputsMYSTRAN). Recall that a string in ESP starts with a $.
74 * For example, attribute <c>capsConnectLink $springEnd</c>.
75 */
76
77#include <string.h>
78#include <math.h>
79#include "capsTypes.h"
80#include "aimUtil.h"
81
82#include "meshUtils.h"
83#include "miscUtils.h"
84#include "feaUtils.h"
85#include "nastranUtils.h"
86#include "mystranUtils.h"
87
88#ifdef WIN32
89#define snprintf _snprintf
90#define strcasecmp stricmp
91#endif
92
93//#define DEBUG
94
95enum aimInputs
96{
97 Proj_Name = 1, /* index is 1-based */
98 Tess_Params,
99 Edge_Point_Min,
100 Edge_Point_Max,
101 Quad_Mesh,
102 Property,
103 Material,
104 Constraint,
105 Load,
106 Analysix,
107 Analysis_Type,
108 Support,
109 Mesh,
110 NUMINPUT = Mesh /* Total number of inputs */
111};
112
113#define NUMOUTPUT4 4
114
115
116typedef struct {
117 // Project name
118 char *projectName;
119
120 feaUnitsStruct units; // units system
121
122 feaProblemStruct feaProblem;
123
124 // Attribute to index map
125 mapAttrToIndexStruct attrMap;
126
127 // Attribute to constraint index map
128 mapAttrToIndexStruct constraintMap;
129
130 // Attribute to load index map
131 mapAttrToIndexStruct loadMap;
132
133 /*
134 // Check to make sure data transfer is ok
135 int dataTransferCheck;
136 */
137
138 // Mesh holders
139 int numMesh;
140 meshStruct *feaMesh;
141
142} aimStorage;
143
144
145static int initiate_aimStorage(aimStorage *mystranInstance)
146{
147
148 int status;
149
150 // Set initial values for mystranInstance
151 mystranInstance->projectName = NULL((void*)0);
152
153 // Mesh holders
154 mystranInstance->numMesh = 0;
155 mystranInstance->feaMesh = NULL((void*)0);
156
157 /*
158 // Check to make sure data transfer is ok
159 mystranInstance->dataTransferCheck = (int) true;
160 */
161
162 status = initiate_feaUnitsStruct(&mystranInstance->units);
163 if (status != CAPS_SUCCESS0) return status;
164
165 // Container for attribute to index map
166 status = initiate_mapAttrToIndexStruct(&mystranInstance->attrMap);
167 if (status != CAPS_SUCCESS0) return status;
168
169 // Container for attribute to constraint index map
170 status = initiate_mapAttrToIndexStruct(&mystranInstance->constraintMap);
171 if (status != CAPS_SUCCESS0) return status;
172
173 // Container for attribute to load index map
174 status = initiate_mapAttrToIndexStruct(&mystranInstance->loadMap);
175 if (status != CAPS_SUCCESS0) return status;
176
177 status = initiate_feaProblemStruct(&mystranInstance->feaProblem);
178 if (status != CAPS_SUCCESS0) return status;
179
180 return CAPS_SUCCESS0;
181}
182
183
184static int destroy_aimStorage(aimStorage *mystranInstance)
185{
186
187 int status;
188 int i;
189
190 status = destroy_feaUnitsStruct(&mystranInstance->units);
191 if (status != CAPS_SUCCESS0)
192 printf("Error: Status %d during destroy_feaUnitsStruct!\n", status);
193
194 // Attribute to index map
195 status = destroy_mapAttrToIndexStruct(&mystranInstance->attrMap);
196 if (status != CAPS_SUCCESS0)
197 printf("Error: Status %d during destroy_mapAttrToIndexStruct!\n", status);
198
199 // Attribute to constraint index map
200 status = destroy_mapAttrToIndexStruct(&mystranInstance->constraintMap);
201 if (status != CAPS_SUCCESS0)
202 printf("Error: Status %d during destroy_mapAttrToIndexStruct!\n", status);
203
204 // Attribute to load index map
205 status = destroy_mapAttrToIndexStruct(&mystranInstance->loadMap);
206 if (status != CAPS_SUCCESS0)
207 printf("Error: Status %d during destroy_mapAttrToIndexStruct!\n", status);
208
209 // Cleanup meshes
210 if (mystranInstance->feaMesh != NULL((void*)0)) {
211
212 for (i = 0; i < mystranInstance->numMesh; i++) {
213 status = destroy_meshStruct(&mystranInstance->feaMesh[i]);
214 if (status != CAPS_SUCCESS0)
215 printf("Error: Status %d during destroy_meshStruct!\n", status);
216 }
217
218 AIM_FREE(mystranInstance->feaMesh){ EG_free(mystranInstance->feaMesh); mystranInstance->feaMesh
= ((void*)0); }
;
219 }
220
221 mystranInstance->feaMesh = NULL((void*)0);
222 mystranInstance->numMesh = 0;
223
224 // Destroy FEA problem structure
225 status = destroy_feaProblemStruct(&mystranInstance->feaProblem);
226 if (status != CAPS_SUCCESS0)
227 printf("Error: Status %d during destroy_feaProblemStruct!\n", status);
228
229 // NULL projetName
230 mystranInstance->projectName = NULL((void*)0);
231
232 return CAPS_SUCCESS0;
233}
234
235
236static int checkAndCreateMesh(void *aimInfo, aimStorage *mystranInstance)
237{
238 // Function return flag
239 int status = CAPS_SUCCESS0;
240 int i, remesh = (int)true1;
241
242 // Meshing related variables
243 double tessParam[3] = {0.025, 0.001, 15};
244 int edgePointMin = 2;
245 int edgePointMax = 50;
246 int quadMesh = (int) false0;
247
248 // Attribute to transfer map
249 mapAttrToIndexStruct transferMap;
250
251 // Attribute to connect map
252 mapAttrToIndexStruct connectMap;
253
254 // analysis input values
255 capsValue *TessParams;
256 capsValue *EdgePoint_Min;
257 capsValue *EdgePoint_Max;
258 capsValue *QuadMesh;
259
260 for (i = 0; i < mystranInstance->numMesh; i++) {
261 remesh = remesh && (mystranInstance->feaMesh[i].egadsTess->oclass == EMPTY4);
262 }
263 if (remesh == (int) false0) return CAPS_SUCCESS0;
264
265 // retrieve or create the mesh from fea_createMesh
266 status = aim_getValue(aimInfo, Tess_Params, ANALYSISIN, &TessParams);
267 if (status != CAPS_SUCCESS0) return status;
268
269 status = aim_getValue(aimInfo, Edge_Point_Min, ANALYSISIN, &EdgePoint_Min);
270 if (status != CAPS_SUCCESS0) return status;
271
272 status = aim_getValue(aimInfo, Edge_Point_Max, ANALYSISIN, &EdgePoint_Max);
273 if (status != CAPS_SUCCESS0) return status;
274
275 status = aim_getValue(aimInfo, Quad_Mesh, ANALYSISIN, &QuadMesh);
276 if (status != CAPS_SUCCESS0) return status;
277
278 if (TessParams != NULL((void*)0)) {
279 tessParam[0] = TessParams->vals.reals[0];
280 tessParam[1] = TessParams->vals.reals[1];
281 tessParam[2] = TessParams->vals.reals[2];
282 }
283
284 // Max and min number of points
285 if (EdgePoint_Min != NULL((void*)0) && EdgePoint_Min->nullVal != IsNull) {
286 edgePointMin = EdgePoint_Min->vals.integer;
287 if (edgePointMin < 2) {
288 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, "mystranAIM.c"
, 288, __func__, "Edge_Point_Min = %d must be greater or equal to 2\n"
, edgePointMin); }
;
289 return CAPS_BADVALUE-311;
290 }
291 }
292
293 if (EdgePoint_Max != NULL((void*)0) && EdgePoint_Max->nullVal != IsNull) {
294 edgePointMax = EdgePoint_Max->vals.integer;
295 if (edgePointMax < 2) {
296 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, "mystranAIM.c"
, 296, __func__, "Edge_Point_Max = %d must be greater or equal to 2\n"
, edgePointMax); }
;
297 return CAPS_BADVALUE-311;
298 }
299 }
300
301 if (edgePointMin >= 2 && edgePointMax >= 2 && edgePointMin > edgePointMax) {
302 AIM_ERROR (aimInfo, "Edge_Point_Max must be greater or equal Edge_Point_Min"){ aim_message(aimInfo, CERROR, 0 , "mystranAIM.c", 302, __func__
, "Edge_Point_Max must be greater or equal Edge_Point_Min"); }
;
303 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); }
;
304 return CAPS_BADVALUE-311;
305 }
306
307 if (QuadMesh != NULL((void*)0)) quadMesh = QuadMesh->vals.integer;
308
309 status = initiate_mapAttrToIndexStruct(&transferMap);
310 if (status != CAPS_SUCCESS0) return status;
311
312 status = initiate_mapAttrToIndexStruct(&connectMap);
313 if (status != CAPS_SUCCESS0) return status;
314/*@-nullpass@*/
315 status = fea_createMesh(aimInfo,
316 tessParam,
317 edgePointMin,
318 edgePointMax,
319 quadMesh,
320 &mystranInstance->attrMap,
321 &mystranInstance->constraintMap,
322 &mystranInstance->loadMap,
323 &transferMap,
324 &connectMap,
325 NULL((void*)0),
326 &mystranInstance->numMesh,
327 &mystranInstance->feaMesh,
328 &mystranInstance->feaProblem);
329/*@+nullpass@*/
330 if (status != CAPS_SUCCESS0) return status;
331
332 status = destroy_mapAttrToIndexStruct(&transferMap);
333 if (status != CAPS_SUCCESS0) return status;
334
335 status = destroy_mapAttrToIndexStruct(&connectMap);
336 if (status != CAPS_SUCCESS0) return status;
337
338 return CAPS_SUCCESS0;
339}
340
341
342/* ********************** Exposed AIM Functions ***************************** */
343
344int aimInitialize(int inst, /*@unused@*/ const char *unitSys, void *aimInfo,
345 /*@unused@*/ void **instStore, /*@unused@*/ int *major,
346 /*@unused@*/ int *minor, int *nIn, int *nOut,
347 int *nFields, char ***fnames, int **franks, int **fInOut)
348{
349 int status = CAPS_SUCCESS0, *ints=NULL((void*)0), i;
350 char **strs=NULL((void*)0);
351
352 aimStorage *mystranInstance=NULL((void*)0);
353
354#ifdef DEBUG
355 printf("mystranAIM/aimInitialize inst = %d!\n", inst);
356#endif
357
358 /* specify the number of analysis input and out "parameters" */
359 *nIn = NUMINPUT;
360 *nOut = NUMOUTPUT4;
361 if (inst == -1) return CAPS_SUCCESS0;
362
363 /* specify the field variables this analysis can generate and consume */
364 *nFields = 4;
365
366 /* specify the name of each field variable */
367 AIM_ALLOC(strs, *nFields, char *, aimInfo, status){ if (strs != ((void*)0)) { status = -4; aim_status(aimInfo, status
, "mystranAIM.c", 367, __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, "mystranAIM.c"
, 367, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "strs",
memorysize, "char *"); goto cleanup; } }
;
368
369 strs[0] = EG_strdup("Displacement");
370 strs[1] = EG_strdup("EigenVector");
371 strs[2] = EG_strdup("EigenVector_#");
372 strs[3] = EG_strdup("Pressure");
373 for (i = 0; i < *nFields; i++)
374 if (strs[i] == NULL((void*)0)) { status = EGADS_MALLOC-4; goto cleanup; }
375 *fnames = strs;
376
377 /* specify the dimension of each field variable */
378 AIM_ALLOC(ints, *nFields, int, aimInfo, status){ if (ints != ((void*)0)) { status = -4; aim_status(aimInfo, status
, "mystranAIM.c", 378, __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, "mystranAIM.c", 378
, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "ints", memorysize
, "int"); goto cleanup; } }
;
379 ints[0] = 3;
380 ints[1] = 3;
381 ints[2] = 3;
382 ints[3] = 1;
383 *franks = ints;
384 ints = NULL((void*)0);
385
386 /* specify if a field is an input field or output field */
387 AIM_ALLOC(ints, *nFields, int, aimInfo, status){ if (ints != ((void*)0)) { status = -4; aim_status(aimInfo, status
, "mystranAIM.c", 387, __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, "mystranAIM.c", 387
, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "ints", memorysize
, "int"); goto cleanup; } }
;
388
389 ints[0] = FieldOut;
390 ints[1] = FieldOut;
391 ints[2] = FieldOut;
392 ints[3] = FieldIn;
393 *fInOut = ints;
394 ints = NULL((void*)0);
395
396 // Allocate mystranInstance
397 AIM_ALLOC(mystranInstance, 1, aimStorage, aimInfo, status){ if (mystranInstance != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "mystranAIM.c", 397, __func__, 1, "AIM_ALLOC: %s != NULL"
, "mystranInstance"); goto cleanup; } size_t memorysize = 1; mystranInstance
= (aimStorage *) EG_alloc(memorysize*sizeof(aimStorage)); if
(mystranInstance == ((void*)0)) { status = -4; aim_status(aimInfo
, status, "mystranAIM.c", 397, __func__, 3, "AIM_ALLOC: %s size %zu type %s"
, "mystranInstance", memorysize, "aimStorage"); goto cleanup;
} }
;
398 *instStore = mystranInstance;
399
400 // Initialize instance storage
401 status = initiate_aimStorage(mystranInstance);
402 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "mystranAIM.c"
, 402, __func__, 0); goto cleanup; }
;
403
404cleanup:
405 if (status != CAPS_SUCCESS0) {
406 /* release all possibly allocated memory on error */
407 if (*fnames != NULL((void*)0))
408 for (i = 0; i < *nFields; i++) AIM_FREE((*fnames)[i]){ EG_free((*fnames)[i]); (*fnames)[i] = ((void*)0); };
409 AIM_FREE(*franks){ EG_free(*franks); *franks = ((void*)0); };
410 AIM_FREE(*fInOut){ EG_free(*fInOut); *fInOut = ((void*)0); };
411 AIM_FREE(*fnames){ EG_free(*fnames); *fnames = ((void*)0); };
412 AIM_FREE(*instStore){ EG_free(*instStore); *instStore = ((void*)0); };
413 *nFields = 0;
414 }
415
416 return status;
417}
418
419
420int aimInputs(/*@unused@*/ void *instStore, /*@unused@*/ void *aimInfo,
421 int index, char **ainame, capsValue *defval)
422{
423 /*! \page aimInputsMYSTRAN AIM Inputs
424 * The following list outlines the MYSTRAN inputs along with their default value available
425 * through the AIM interface. Unless noted these values will be not be linked to
426 * any parent AIMs with variables of the same name.
427 */
428 int status = CAPS_SUCCESS0;
429
430#ifdef DEBUG
431 printf(" mystranAIM/aimInputs index = %d!\n", index);
432#endif
433
434 *ainame = NULL((void*)0);
435
436 // MYSTRAN Inputs
437 if (index == Proj_Name) {
438 *ainame = EG_strdup("Proj_Name");
439 defval->type = String;
440 defval->nullVal = NotNull;
441 defval->vals.string = EG_strdup("mystran_CAPS");
442 defval->lfixed = Change;
443
444 /*! \page aimInputsMYSTRAN
445 * - <B> Proj_Name = "mystran_CAPS"</B> <br>
446 * This corresponds to the project name used for file naming.
447 */
448
449 } else if (index == Tess_Params) {
450 *ainame = EG_strdup("Tess_Params");
451 defval->type = Double;
452 defval->dim = Vector;
453 defval->nrow = 3;
454 defval->ncol = 1;
455 defval->units = NULL((void*)0);
456 defval->lfixed = Fixed;
457 defval->vals.reals = (double *) EG_alloc(defval->nrow*sizeof(double));
458 if (defval->vals.reals != NULL((void*)0)) {
459 defval->vals.reals[0] = 0.025;
460 defval->vals.reals[1] = 0.001;
461 defval->vals.reals[2] = 15.00;
462 } else return EGADS_MALLOC-4;
463
464 /*! \page aimInputsMYSTRAN
465 * - <B> Tess_Params = [0.025, 0.001, 15.0]</B> <br>
466 * Body tessellation parameters used when creating a boundary element model.
467 * Tess_Params[0] and Tess_Params[1] get scaled by the bounding
468 * box of the body. (From the EGADS manual) A set of 3 parameters that drive the EDGE discretization
469 * and the FACE triangulation. The first is the maximum length of an EDGE segment or triangle side
470 * (in physical space). A zero is flag that allows for any length. The second is a curvature-based
471 * value that looks locally at the deviation between the centroid of the discrete object and the
472 * underlying geometry. Any deviation larger than the input value will cause the tessellation to
473 * be enhanced in those regions. The third is the maximum interior dihedral angle (in degrees)
474 * between triangle facets (or Edge segment tangents for a WIREBODY tessellation), note that a
475 * zero ignores this phase
476 */
477
478 } else if (index == Edge_Point_Min) {
479 *ainame = EG_strdup("Edge_Point_Min");
480 defval->type = Integer;
481 defval->vals.integer = 2;
482 defval->lfixed = Fixed;
483 defval->nrow = 1;
484 defval->ncol = 1;
485 defval->nullVal = NotNull;
486
487 /*! \page aimInputsMYSTRAN
488 * - <B> Edge_Point_Min = 2</B> <br>
489 * Minimum number of points on an edge including end points to use when creating a surface mesh (min 2).
490 */
491
492 } else if (index == Edge_Point_Max) {
493 *ainame = EG_strdup("Edge_Point_Max");
494 defval->type = Integer;
495 defval->vals.integer = 50;
496 defval->lfixed = Fixed;
497 defval->nrow = 1;
498 defval->ncol = 1;
499 defval->nullVal = NotNull;
500
501 /*! \page aimInputsMYSTRAN
502 * - <B> Edge_Point_Max = 50</B> <br>
503 * Maximum number of points on an edge including end points to use when creating a surface mesh (min 2).
504 */
505
506 } else if (index == Quad_Mesh) {
507 *ainame = EG_strdup("Quad_Mesh");
508 defval->type = Boolean;
509 defval->vals.integer = (int) false0;
510
511 /*! \page aimInputsMYSTRAN
512 * - <B> Quad_Mesh = False</B> <br>
513 * Create a quadratic mesh on four edge faces when creating the boundary element model.
514 */
515
516 } else if (index == Property) {
517 *ainame = EG_strdup("Property");
518 defval->type = Tuple;
519 defval->nullVal = IsNull;
520 //defval->units = NULL;
521 defval->lfixed = Change;
522 defval->vals.tuple = NULL((void*)0);
523 defval->dim = Vector;
524
525 /*! \page aimInputsMYSTRAN
526 * - <B> Property = NULL</B> <br>
527 * Property tuple used to input property information for the model, see \ref feaProperty for additional details.
528 */
529 } else if (index == Material) {
530 *ainame = EG_strdup("Material");
531 defval->type = Tuple;
532 defval->nullVal = IsNull;
533 //defval->units = NULL;
534 defval->lfixed = Change;
535 defval->vals.tuple = NULL((void*)0);
536 defval->dim = Vector;
537
538 /*! \page aimInputsMYSTRAN
539 * - <B> Material = NULL</B> <br>
540 * Material tuple used to input material information for the model, see \ref feaMaterial for additional details.
541 */
542 } else if (index == Constraint) {
543 *ainame = EG_strdup("Constraint");
544 defval->type = Tuple;
545 defval->nullVal = IsNull;
546 //defval->units = NULL;
547 defval->lfixed = Change;
548 defval->vals.tuple = NULL((void*)0);
549 defval->dim = Vector;
550
551 /*! \page aimInputsMYSTRAN
552 * - <B> Constraint = NULL</B> <br>
553 * Constraint tuple used to input constraint information for the model, see \ref feaConstraint for additional details.
554 */
555 } else if (index == Load) {
556 *ainame = EG_strdup("Load");
557 defval->type = Tuple;
558 defval->nullVal = IsNull;
559 //defval->units = NULL;
560 defval->lfixed = Change;
561 defval->vals.tuple = NULL((void*)0);
562 defval->dim = Vector;
563
564 /*! \page aimInputsMYSTRAN
565 * - <B> Load = NULL</B> <br>
566 * Load tuple used to input load information for the model, see \ref feaLoad for additional details.
567 */
568 } else if (index == Analysix) {
569 *ainame = EG_strdup("Analysis");
570 defval->type = Tuple;
571 defval->nullVal = IsNull;
572 //defval->units = NULL;
573 defval->lfixed = Change;
574 defval->vals.tuple = NULL((void*)0);
575 defval->dim = Vector;
576
577 /*! \page aimInputsMYSTRAN
578 * - <B> Analysis = NULL</B> <br>
579 * Analysis tuple used to input analysis/case information for the model, see \ref feaAnalysis for additional details.
580 */
581 } else if (index == Analysis_Type) {
582 *ainame = EG_strdup("Analysis_Type");
583 defval->type = String;
584 defval->nullVal = NotNull;
585 defval->vals.string = EG_strdup("Modal");
586 defval->lfixed = Change;
587
588 /*! \page aimInputsMYSTRAN
589 * - <B> Analysis_Type = "Modal"</B> <br>
590 * Type of analysis to generate files for, options include "Modal", "Static", and "Craig-Bampton".
591 */
592 } else if (index == Support) {
593 *ainame = EG_strdup("Support");
594 defval->type = Tuple;
595 defval->nullVal = IsNull;
596 //defval->units = NULL;
597 defval->lfixed = Change;
598 defval->vals.tuple = NULL((void*)0);
599 defval->dim = Vector;
600
601 /*! \page aimInputsMYSTRAN
602 * - <B> Support = NULL</B> <br>
603 * Support tuple used to input support information for the model, see \ref feaSupport for additional details.
604 */
605
606 } else if (index == Mesh) {
607 *ainame = AIM_NAME(Mesh)EG_strdup("Mesh");
608 defval->type = Pointer;
609 defval->dim = Vector;
610 defval->lfixed = Change;
611 defval->sfixed = Change;
612 defval->vals.AIMptr = NULL((void*)0);
613 defval->nullVal = IsNull;
614 AIM_STRDUP(defval->units, "meshStruct", aimInfo, status){ if (defval->units != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "mystranAIM.c", 614, __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, "mystranAIM.c", 614, __func__
, 2, "AIM_STRDUP: %s %s", "defval->units", "meshStruct"); goto
cleanup; } }
;
615
616 /*! \page aimInputsMYSTRAN
617 * - <B>Mesh = NULL</B> <br>
618 * A Mesh link.
619 */
620
621 } else {
622 status = CAPS_BADINDEX-304;
623 AIM_STATUS(aimInfo, status, "Unknown input index %d!", index)if (status != 0) { aim_status(aimInfo, status, "mystranAIM.c"
, 623, __func__, 2, "Unknown input index %d!", index); goto cleanup
; }
;
624 }
625
626 AIM_NOTNULL(*ainame, aimInfo, status){ if (*ainame == ((void*)0)) { status = -307; aim_status(aimInfo
, status, "mystranAIM.c", 626, __func__, 1, "%s == NULL!", "*ainame"
); goto cleanup; } }
;
627
628cleanup:
629 if (status != CAPS_SUCCESS0) AIM_FREE(*ainame){ EG_free(*ainame); *ainame = ((void*)0); };
630 return status;
631}
632
633
634// ********************** AIM Function Break *****************************
635int aimUpdateState(void *instStore, void *aimInfo,
636 capsValue *aimInputs)
637{
638 int status; // Function return status
639
640 aimStorage *mystranInstance;
641
642 mystranInstance = (aimStorage *) instStore;
643 AIM_NOTNULL(aimInputs, aimInfo, status){ if (aimInputs == ((void*)0)) { status = -307; aim_status(aimInfo
, status, "mystranAIM.c", 643, __func__, 1, "%s == NULL!", "aimInputs"
); goto cleanup; } }
;
644
645 // Get project name
646 mystranInstance->projectName = aimInputs[Proj_Name-1].vals.string;
647
648 // Check and generate/retrieve the mesh
649 status = checkAndCreateMesh(aimInfo, mystranInstance);
650 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "mystranAIM.c"
, 650, __func__, 0); goto cleanup; }
;
651
652 // Note: Setting order is important here.
653 // 1. Materials should be set before properties.
654 // 2. Coordinate system should be set before mesh and loads
655 // 3. Mesh should be set before loads and constraints
656 // 4. Constraints and loads should be set before analysis
657
658 // Set material properties
659 if (aimInputs[Material-1].nullVal == NotNull) {
660 status = fea_getMaterial(aimInfo,
661 aimInputs[Material-1].length,
662 aimInputs[Material-1].vals.tuple,
663 &mystranInstance->units,
664 &mystranInstance->feaProblem.numMaterial,
665 &mystranInstance->feaProblem.feaMaterial);
666 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "mystranAIM.c"
, 666, __func__, 0); goto cleanup; }
;
667 } else printf("\nLoad tuple is NULL - No materials set\n");
668
669 // Set property properties
670 if (aimInputs[Property-1].nullVal == NotNull) {
671 status = fea_getProperty(aimInfo,
672 aimInputs[Property-1].length,
673 aimInputs[Property-1].vals.tuple,
674 &mystranInstance->attrMap,
675 &mystranInstance->units,
676 &mystranInstance->feaProblem);
677 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "mystranAIM.c"
, 677, __func__, 0); goto cleanup; }
;
678 } else printf("\nProperty tuple is NULL - No properties set\n");
679
680 // Set constraint properties
681 if (aimInputs[Constraint-1].nullVal == NotNull) {
682 status = fea_getConstraint(aimInputs[Constraint-1].length,
683 aimInputs[Constraint-1].vals.tuple,
684 &mystranInstance->constraintMap,
685 &mystranInstance->feaProblem);
686 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "mystranAIM.c"
, 686, __func__, 0); goto cleanup; }
;
687 } else printf("\nConstraint tuple is NULL - No constraints applied\n");
688
689 // Set support properties
690 if (aimInputs[Support-1].nullVal == NotNull) {
691 status = fea_getSupport(aimInputs[Support-1].length,
692 aimInputs[Support-1].vals.tuple,
693 &mystranInstance->constraintMap,
694 &mystranInstance->feaProblem);
695 if (status != CAPS_SUCCESS0) return status;
696 } else printf("Support tuple is NULL - No supports applied\n");
697
698 // Set load properties
699 if (aimInputs[Load-1].nullVal == NotNull) {
700 status = fea_getLoad(aimInputs[Load-1].length,
701 aimInputs[Load-1].vals.tuple,
702 &mystranInstance->loadMap,
703 &mystranInstance->feaProblem);
704 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "mystranAIM.c"
, 704, __func__, 0); goto cleanup; }
;
705 } else printf("\nLoad tuple is NULL - No loads applied\n");
706
707 // Set analysis settings
708 if (aimInputs[Analysix-1].nullVal == NotNull) {
709 status = fea_getAnalysis(aimInputs[Analysix-1].length,
710 aimInputs[Analysix-1].vals.tuple,
711 &mystranInstance->feaProblem);
712 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "mystranAIM.c"
, 712, __func__, 0); goto cleanup; }
; // It ok to not have an analysis tuple
713 } else printf("\nAnalysis tuple is NULL\n");
714
715 status = CAPS_SUCCESS0;
716cleanup:
717 return status;
718}
719
720
721// ********************** AIM Function Break *****************************
722int aimPreAnalysis(const void *instStore, void *aimInfo, capsValue *aimInputs)
723{
724
725 int i, j, k; // Indexing
726
727 int status; // Status return
728
729 int found; // Boolean operator
730
731 int *tempIntegerArray = NULL((void*)0); // Temporary array to store a list of integers
732
733 // Analyis information
734 char *analysisType = NULL((void*)0);
735
736 // File IO
737 char filename[PATH_MAX4096]; // Output file name
738 FILE *fp = NULL((void*)0); // Output file pointer
739
740 const aimStorage *mystranInstance;
741
742 // Load information
743 feaLoadStruct *feaLoad = NULL((void*)0); // size = [numLoad]
1
'feaLoad' initialized to a null pointer value
744
745 mystranInstance = (const aimStorage *) instStore;
746 AIM_NOTNULL(aimInputs, aimInfo, status){ if (aimInputs == ((void*)0)) { status = -307; aim_status(aimInfo
, status, "mystranAIM.c", 746, __func__, 1, "%s == NULL!", "aimInputs"
); goto cleanup; } }
;
2
Assuming 'aimInputs' is not equal to null
3
Taking false branch
747
748 if (mystranInstance->feaProblem.numLoad > 0) {
4
Assuming field 'numLoad' is <= 0
5
Taking false branch
749 AIM_ALLOC(feaLoad, mystranInstance->feaProblem.numLoad, feaLoadStruct, aimInfo, status){ if (feaLoad != ((void*)0)) { status = -4; aim_status(aimInfo
, status, "mystranAIM.c", 749, __func__, 1, "AIM_ALLOC: %s != NULL"
, "feaLoad"); goto cleanup; } size_t memorysize = mystranInstance
->feaProblem.numLoad; feaLoad = (feaLoadStruct *) EG_alloc
(memorysize*sizeof(feaLoadStruct)); if (feaLoad == ((void*)0)
) { status = -4; aim_status(aimInfo, status, "mystranAIM.c", 749
, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "feaLoad", memorysize
, "feaLoadStruct"); goto cleanup; } }
;
750 for (i = 0; i < mystranInstance->feaProblem.numLoad; i++) initiate_feaLoadStruct(&feaLoad[i]);
751 for (i = 0; i < mystranInstance->feaProblem.numLoad; i++) {
752 status = copy_feaLoadStruct(aimInfo, &mystranInstance->feaProblem.feaLoad[i], &feaLoad[i]);
753 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "mystranAIM.c"
, 753, __func__, 0); goto cleanup; }
;
754
755 if (feaLoad[i].loadType == PressureExternal) {
756
757 // Transfer external pressures from the AIM discrObj
758 status = fea_transferExternalPressure(aimInfo,
759 &mystranInstance->feaProblem.feaMesh,
760 &feaLoad[i]);
761 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "mystranAIM.c"
, 761, __func__, 0); goto cleanup; }
;
762 }
763 }
764 }
765
766 // Write Nastran Mesh
767 status = mesh_writeNASTRAN(aimInfo,
768 mystranInstance->projectName,
769 1,
770 &mystranInstance->feaProblem.feaMesh,
771 mystranInstance->feaProblem.feaFileFormat.gridFileType,
772 1.0);
773 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "mystranAIM.c"
, 773, __func__, 0); goto cleanup; }
;
6
Assuming 'status' is equal to 0
7
Taking false branch
774
775 // Write mystran input file
776 strcpy(filename, mystranInstance->projectName);
777 strcat(filename, ".dat");
778
779 printf("\nWriting MYSTRAN instruction file....\n");
780 fp = aim_fopen(aimInfo, filename, "w");
781 if (fp == NULL((void*)0)) {
8
Assuming 'fp' is not equal to NULL
9
Taking false branch
782 AIM_ERROR(aimInfo, "Unable to open file: %s\n", filename){ aim_message(aimInfo, CERROR, 0 , "mystranAIM.c", 782, __func__
, "Unable to open file: %s\n", filename); }
;
783 status = CAPS_IOERR-332;
784 goto cleanup;
785 }
786
787 //////////////// Executive control ////////////////
788 fprintf(fp, "ID CAPS generated Problem FOR MYSTRAN\n");
789
790 // Analysis type
791 analysisType = aimInputs[Analysis_Type-1].vals.string;
792
793 if (strcasecmp(analysisType, "Modal") == 0) fprintf(fp, "SOL 3\n");
10
Taking true branch
794 else if(strcasecmp(analysisType, "Static") == 0) fprintf(fp, "SOL 1\n");
795 else if(strcasecmp(analysisType, "Craig-Bampton") == 0) fprintf(fp, "SOL 31\n");
796 else {
797 AIM_ERROR(aimInfo, "Unrecognized \"Analysis_Type\", %s", analysisType){ aim_message(aimInfo, CERROR, 0 , "mystranAIM.c", 797, __func__
, "Unrecognized \"Analysis_Type\", %s", analysisType); }
;
798 status = CAPS_BADVALUE-311;
799 goto cleanup;
800 }
801
802 if (strcasecmp(analysisType, "Modal") == 0) fprintf(fp, "OUTPUT4 EIGEN_VAL, EIGEN_VEC, GEN_MASS, , // -1/21 $\n"); // Binary output of eigenvalues and vectors
11
Assuming the condition is false
12
Taking false branch
803
804 fprintf(fp, "CEND\n\n");
805
806 //////////////// Case control ////////////////
807
808 // Write output request information
809 fprintf(fp, "DISP = ALL\n"); // Output all displacements
810
811 if(strcasecmp(analysisType, "Static") == 0) fprintf(fp, "STRE = ALL\n"); // Output all stress
13
Assuming the condition is false
14
Taking false branch
812
813 if(strcasecmp(analysisType, "Static") == 0) fprintf(fp, "STRA = ALL\n"); // Output all strain
15
Assuming the condition is false
16
Taking false branch
814
815 //fprintf(fp, "ELDATA(6,PRINT) = ALL\n");
816
817 // Check thermal load - currently only a single thermal load is supported - also it only works for the global level - no subcase
818 found = (int) false0;
819 for (i = 0; i < mystranInstance->feaProblem.numLoad; i++) {
17
Assuming 'i' is < field 'numLoad'
18
Loop condition is true. Entering loop body
820
821 if (feaLoad[i].loadType != Thermal) continue;
19
Dereference of null pointer
822
823 if (found == (int) true1) {
824 AIM_ERROR(aimInfo, "More than 1 Thermal load found - mystranAIM does NOT currently doesn't support multiple thermal loads!"){ aim_message(aimInfo, CERROR, 0 , "mystranAIM.c", 824, __func__
, "More than 1 Thermal load found - mystranAIM does NOT currently doesn't support multiple thermal loads!"
); }
;
825 status = CAPS_BADVALUE-311;
826 goto cleanup;
827 }
828
829 found = (int) true1;
830
831 fprintf(fp, "TEMPERATURE = %d\n",
832 feaLoad[i].loadID);
833 }
834
835 // Write constraint information
836 if (mystranInstance->feaProblem.numConstraint != 0) {
837 fprintf(fp, "SPC = %d\n", mystranInstance->feaProblem.numConstraint+1);
838 } else {
839 printf("Warning: No constraints specified for job!!!!\n");
840 }
841
842 // Modal analysis - only
843 // If modal - we are only going to use the first analysis structure we come across that has its type as modal
844 if (strcasecmp(analysisType, "Modal") == 0) {
845
846 // Look through analysis structures for a modal one
847 found = (int) false0;
848 for (i = 0; i < mystranInstance->feaProblem.numAnalysis; i++) {
849 if (mystranInstance->feaProblem.feaAnalysis[i].analysisType == Modal) {
850 found = (int) true1;
851 break;
852 }
853 }
854
855 // Write out analysis ID if a modal analysis structure was found
856 if (found == (int) true1) {
857 fprintf(fp, "METHOD = %d\n",
858 mystranInstance->feaProblem.feaAnalysis[i].analysisID);
859 } else {
860 printf("Warning: No eigenvalue analysis information specified in \"Analysis\" tuple, though "
861 "AIM input \"Analysis_Type\" is set to \"Modal\"!!!!\n");
862 status = CAPS_NOTFOUND-303;
863 goto cleanup;
864 }
865
866 }
867 // Static analysis - only
868 if (strcasecmp(analysisType, "Static") == 0) {
869
870 // If we have multiple analysis structures
871 if (mystranInstance->feaProblem.numAnalysis != 0) {
872
873 // Write subcase information if multiple analysis tuples were provide
874 for (i = 0; i < mystranInstance->feaProblem.numAnalysis; i++) {
875
876 if (mystranInstance->feaProblem.feaAnalysis[i].analysisType == Static) {
877 fprintf(fp, "SUBCASE %d\n", i);
878 fprintf(fp, "\tLABEL %s\n",
879 mystranInstance->feaProblem.feaAnalysis[i].name);
880
881 // Write loads for sub-case
882 if (mystranInstance->feaProblem.numLoad > 0) {
883 fprintf(fp, "\tLOAD = %d\n",
884 mystranInstance->feaProblem.numLoad+i+1);
885 }
886
887 // Issue some warnings regarding loads if necessary
888 if (mystranInstance->feaProblem.feaAnalysis[i].numLoad == 0 &&
889 mystranInstance->feaProblem.numLoad > 0) {
890 printf("Warning: No loads specified for static case %s, assuming "
891 "all loads are applied!!!!\n",
892 mystranInstance->feaProblem.feaAnalysis[i].name);
893 } else if (mystranInstance->feaProblem.numLoad == 0) {
894 printf("Warning: No loads specified for static case %s!!!!\n",
895 mystranInstance->feaProblem.feaAnalysis[i].name);
896 }
897 }
898 }
899
900 } else { // // If no sub-cases
901
902 if (mystranInstance->feaProblem.numLoad > 0) {
903 fprintf(fp, "LOAD = %d\n", mystranInstance->feaProblem.numLoad+1);
904 } else {
905 printf("Warning: No loads specified for static a job!!!!\n");
906 }
907 }
908 }
909
910 //////////////// Bulk data ////////////////
911 fprintf(fp, "\nBEGIN BULK\n");
912
913 // Turn off auto SPC
914 //fprintf(fp, "%-8s %7s %7s\n", "PARAM", "AUTOSPC", "N");
915
916 //fprintf(fp, "%-8s %7s %7d\n", "PARAM", "PRTOU4", 1);
917 //fprintf(fp, "%-8s %7s %7d\n", "PARAM", "PRTDLR", 1);
918
919 //fprintf(fp, "%-8s %7s %7d\n", "PARAM", "PRTDOF", 1);
920
921 //fprintf(fp, "%-8s %7d %7d\n", "DEBUG", 183, 1);
922 // Turn on FEMAP
923 //fprintf(fp, "%-8s %7s %7d\n", "PARAM", "POST", -1);
924
925 // Analysis Cards - Eigenvalue included, as well as combined load
926 if (mystranInstance->feaProblem.numAnalysis != 0) {
927
928 for (i = 0; i < mystranInstance->feaProblem.numAnalysis; i++) {
929
930 status = nastran_writeAnalysisCard(fp,
931 &mystranInstance->feaProblem.feaAnalysis[i],
932 &mystranInstance->feaProblem.feaFileFormat);
933 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "mystranAIM.c"
, 933, __func__, 0); goto cleanup; }
;
934
935 if (mystranInstance->feaProblem.feaAnalysis[i].numLoad != 0) {
936
937 status = nastran_writeLoadADDCard(fp,
938 mystranInstance->feaProblem.numLoad+i+1,
939 mystranInstance->feaProblem.feaAnalysis[i].numLoad,
940 mystranInstance->feaProblem.feaAnalysis[i].loadSetID,
941 feaLoad,
942 &mystranInstance->feaProblem.feaFileFormat);
943 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "mystranAIM.c"
, 943, __func__, 0); goto cleanup; }
;
944
945 } else { // If no loads for an individual analysis are specified assume that all loads should be applied
946
947 if (feaLoad != NULL((void*)0)) {
948
949 // Ignore thermal loads
950 k = 0;
951 for (j = 0; j < mystranInstance->feaProblem.numLoad; j++) {
952 if (feaLoad[j].loadType == Thermal) continue;
953 k += 1;
954 }
955
956 if (k != 0) {
957 // Create a temporary list of load IDs
958 tempIntegerArray = (int *) EG_alloc(k*sizeof(int));
959 if (tempIntegerArray == NULL((void*)0)) {
960 status = EGADS_MALLOC-4;
961 goto cleanup;
962 }
963
964 k = 0;
965 for (j = 0; j < mystranInstance->feaProblem.numLoad; j++) {
966
967 if (feaLoad[j].loadType == Thermal) continue;
968 tempIntegerArray[k] = feaLoad[j].loadID;
969
970 k += 1;
971 }
972
973 // Write combined load card
974 status = nastran_writeLoadADDCard(fp,
975 mystranInstance->feaProblem.numLoad+i+1,
976 k,
977 tempIntegerArray,
978 feaLoad,
979 &mystranInstance->feaProblem.feaFileFormat);
980 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "mystranAIM.c"
, 980, __func__, 0); goto cleanup; }
;
981
982 // Free temporary load ID list
983 if (tempIntegerArray != NULL((void*)0)) EG_free(tempIntegerArray);
984 tempIntegerArray = NULL((void*)0);
985 }
986 }
987 }
988 }
989
990 } else { // If there aren't any analysis structures just write a single combined load card
991
992 // Combined loads
993 if (feaLoad != NULL((void*)0)) {
994
995 // Ignore thermal loads
996 k = 0;
997 for (j = 0; j < mystranInstance->feaProblem.numLoad; j++) {
998 if (feaLoad[j].loadType == Thermal) continue;
999 k += 1;
1000 }
1001
1002 if (k != 0) {
1003 // Create a temporary list of load IDs
1004 tempIntegerArray = (int *) EG_alloc(k*sizeof(int));
1005 if (tempIntegerArray == NULL((void*)0)) {
1006 status = EGADS_MALLOC-4;
1007 goto cleanup;
1008 }
1009
1010 k = 0;
1011 for (j = 0; j < mystranInstance->feaProblem.numLoad; j++) {
1012
1013 if (feaLoad[j].loadType == Thermal) continue;
1014 tempIntegerArray[k] = feaLoad[j].loadID;
1015
1016 k += 1;
1017 }
1018
1019 // Write combined load card
1020 status = nastran_writeLoadADDCard(fp,
1021 mystranInstance->feaProblem.numLoad+1,
1022 k,
1023 tempIntegerArray,
1024 feaLoad,
1025 &mystranInstance->feaProblem.feaFileFormat);
1026
1027 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "mystranAIM.c"
, 1027, __func__, 0); goto cleanup; }
;
1028
1029 // Free temporary load ID list
1030 AIM_FREE(tempIntegerArray){ EG_free(tempIntegerArray); tempIntegerArray = ((void*)0); };
1031 }
1032 }
1033 }
1034
1035 // Combined constraints
1036 if (mystranInstance->feaProblem.numConstraint != 0) {
1037
1038 // Create a temporary list of constraint IDs
1039 AIM_ALLOC(tempIntegerArray, mystranInstance->feaProblem.numConstraint, int, aimInfo, status){ if (tempIntegerArray != ((void*)0)) { status = -4; aim_status
(aimInfo, status, "mystranAIM.c", 1039, __func__, 1, "AIM_ALLOC: %s != NULL"
, "tempIntegerArray"); goto cleanup; } size_t memorysize = mystranInstance
->feaProblem.numConstraint; tempIntegerArray = (int *) EG_alloc
(memorysize*sizeof(int)); if (tempIntegerArray == ((void*)0))
{ status = -4; aim_status(aimInfo, status, "mystranAIM.c", 1039
, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "tempIntegerArray"
, memorysize, "int"); goto cleanup; } }
;
1040
1041 for (i = 0; i < mystranInstance->feaProblem.numConstraint; i++) {
1042 tempIntegerArray[i] = mystranInstance->feaProblem.feaConstraint[i].constraintID;
1043 }
1044
1045 // Write combined constraint card
1046 status = nastran_writeConstraintADDCard(fp,
1047 mystranInstance->feaProblem.numConstraint+1,
1048 mystranInstance->feaProblem.numConstraint,
1049 tempIntegerArray,
1050 &mystranInstance->feaProblem.feaFileFormat);
1051 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "mystranAIM.c"
, 1051, __func__, 0); goto cleanup; }
;
1052
1053 // Free temporary constraint ID list
1054 if (tempIntegerArray != NULL((void*)0)) EG_free(tempIntegerArray);
1055 tempIntegerArray = NULL((void*)0);
1056 }
1057
1058 // Loads
1059 for (i = 0; i < mystranInstance->feaProblem.numLoad; i++) {
1060 status = nastran_writeLoadCard(fp,
1061 &feaLoad[i],
1062 &mystranInstance->feaProblem.feaFileFormat);
1063 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "mystranAIM.c"
, 1063, __func__, 0); goto cleanup; }
;
1064 }
1065
1066 // Constraints
1067 for (i = 0; i < mystranInstance->feaProblem.numConstraint; i++) {
1068 status = nastran_writeConstraintCard(fp,
1069 &mystranInstance->feaProblem.feaConstraint[i],
1070 &mystranInstance->feaProblem.feaFileFormat);
1071 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "mystranAIM.c"
, 1071, __func__, 0); goto cleanup; }
;
1072 }
1073
1074 // Supports
1075 for (i = 0; i < mystranInstance->feaProblem.numSupport; i++) {
1076/*@-nullpass@*/
1077 status = nastran_writeSupportCard(fp,
1078 &mystranInstance->feaProblem.feaSupport[i],
1079 &mystranInstance->feaProblem.feaFileFormat,
1080 NULL((void*)0));
1081/*@+nullpass@*/
1082 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "mystranAIM.c"
, 1082, __func__, 0); goto cleanup; }
;
1083 }
1084
1085 // Materials
1086 for (i = 0; i < mystranInstance->feaProblem.numMaterial; i++) {
1087 status = nastran_writeMaterialCard(fp,
1088 &mystranInstance->feaProblem.feaMaterial[i],
1089 &mystranInstance->feaProblem.feaFileFormat);
1090 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "mystranAIM.c"
, 1090, __func__, 0); goto cleanup; }
;
1091 }
1092
1093 // Properties
1094 for (i = 0; i < mystranInstance->feaProblem.numProperty; i++) {
1095 status = nastran_writePropertyCard(fp,
1096 &mystranInstance->feaProblem.feaProperty[i],
1097 &mystranInstance->feaProblem.feaFileFormat);
1098 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "mystranAIM.c"
, 1098, __func__, 0); goto cleanup; }
;
1099 }
1100
1101 // Coordinate systems
1102 for (i = 0; i < mystranInstance->feaProblem.numCoordSystem; i++) {
1103 status = nastran_writeCoordinateSystemCard(fp,
1104 &mystranInstance->feaProblem.feaCoordSystem[i],
1105 &mystranInstance->feaProblem.feaFileFormat);
1106 AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "mystranAIM.c"
, 1106, __func__, 0); goto cleanup; }
;
1107 }
1108
1109 // Include mesh file
1110 fprintf(fp,"INCLUDE \'%s.bdf\'\n", mystranInstance->projectName);
1111
1112 // End bulk data
1113 fprintf(fp,"ENDDATA\n");
1114
1115 status = CAPS_SUCCESS0;
1116
1117cleanup:
1118
1119 for (i = 0; i < mystranInstance->feaProblem.numLoad; i++) {
1120 destroy_feaLoadStruct(&feaLoad[i]);
1121 }
1122 AIM_FREE(feaLoad){ EG_free(feaLoad); feaLoad = ((void*)0); };
1123
1124 if (fp != NULL((void*)0)) fclose(fp);
1125
1126 AIM_FREE(tempIntegerArray){ EG_free(tempIntegerArray); tempIntegerArray = ((void*)0); };
1127
1128 return status;
1129}
1130
1131
1132// ********************** AIM Function Break *****************************
1133int aimExecute(/*@unused@*/ const void *instStore, /*@unused@*/ void *aimInfo,
1134 int *state)
1135{
1136 /*! \page aimExecuteMYSTRAN AIM Execution
1137 *
1138 * If auto execution is enabled when creating an MYSTRAN AIM,
1139 * the AIM will execute MYSTRAN just-in-time with the command line:
1140 *
1141 * \code{.sh}
1142 * mystran $Proj_Name.dat > Info.out
1143 * \endcode
1144 *
1145 * where preAnalysis generated the file Proj_Name + ".dat" which contains the input information.
1146 *
1147 * The analysis can be also be explicitly executed with caps_execute in the C-API
1148 * or via Analysis.runAnalysis in the pyCAPS API.
1149 *
1150 * Calling preAnalysis and postAnalysis is NOT allowed when auto execution is enabled.
1151 *
1152 * Auto execution can also be disabled when creating an MYSTRAN AIM object.
1153 * In this mode, caps_execute and Analysis.runAnalysis can be used to run the analysis,
1154 * or MYSTRAN can be executed by calling preAnalysis, system call, and posAnalysis as demonstrated
1155 * below with a pyCAPS example:
1156 *
1157 * \code{.py}
1158 * print ("\n\preAnalysis......")
1159 * mystran.preAnalysis()
1160 *
1161 * print ("\n\nRunning......")
1162 * mystran.system("mystran " + mystran.input.Proj_Name + ".dat > Info.out"); # Run via system call
1163 *
1164 * print ("\n\postAnalysis......")
1165 * mystran.postAnalysis()
1166 * \endcode
1167 */
1168
1169 char command[PATH_MAX4096];
1170 const aimStorage *mystranInstance;
1171 *state = 0;
1172
1173 mystranInstance = (const aimStorage *) instStore;
1174 if (mystranInstance == NULL((void*)0)) return CAPS_NULLVALUE-307;
1175
1176 snprintf(command, PATH_MAX4096, "mystran %s.dat > Info.out",
1177 mystranInstance->projectName);
1178
1179 return aim_system(aimInfo, NULL((void*)0), command);
1180}
1181
1182
1183// ********************** AIM Function Break *****************************
1184// Check that MYSTRAN ran without errors
1185int aimPostAnalysis(void *instStore, /*@unused@*/ void *aimInfo,
1186 /*@unused@*/ int restart, /*@unused@*/ capsValue *inputs)
1187{
1188 int status;
1189 char *filename = NULL((void*)0); // File to open
1190 char extF06[] = ".F06";
1191 FILE *fp = NULL((void*)0); // File pointer
1192 aimStorage *mystranInstance;
1193
1194#ifdef DEBUG
1195 printf(" astrosAIM/aimPostAnalysis!\n");
1196#endif
1197 mystranInstance = (aimStorage *) instStore;
1198
1199 // check that the mystran *.F06 file was created
1200 filename = (char *) EG_alloc((strlen(mystranInstance->projectName) +
1201 strlen(extF06)+1)*sizeof(char));
1202 if (filename == NULL((void*)0)) return EGADS_MALLOC-4;
1203
1204 sprintf(filename, "%s%s", mystranInstance->projectName, extF06);
1205
1206 fp = aim_fopen(aimInfo, filename, "r");
1207 if (fp == NULL((void*)0)) {
1208 AIM_ERROR(aimInfo, "Cannot open Output file: %s!", filename){ aim_message(aimInfo, CERROR, 0 , "mystranAIM.c", 1208, __func__
, "Cannot open Output file: %s!", filename); }
;
1209 status = CAPS_IOERR-332;
1210 goto cleanup;
1211 }
1212 status = CAPS_SUCCESS0;
1213
1214cleanup:
1215 EG_free(filename); // Free filename allocation
1216 if (fp != NULL((void*)0)) fclose(fp);
1217
1218 return status;
1219}
1220
1221
1222// Set MYSTRAN output variables
1223int aimOutputs(/*@unused@*/ void *instStore, /*@unused@*/ void *aimStruc,
1224 int index, char **aoname, capsValue *form)
1225{
1226 /*! \page aimOutputsMYSTRAN AIM Outputs
1227 * The following list outlines the MYSTRAN outputs available through the AIM interface.
1228 */
1229
1230#ifdef DEBUG
1231 printf(" mystranAIM/aimOutputs index = %d!\n", index);
1232#endif
1233
1234 /*! \page aimOutputsMYSTRAN AIM Outputs
1235 * - <B>EigenValue</B> = List of Eigen-Values (\f$ \lambda\f$) after a modal solve.
1236 * - <B>EigenRadian</B> = List of Eigen-Values in terms of radians (\f$ \omega = \sqrt{\lambda}\f$ ) after a modal solve.
1237 * - <B>EigenFrequency</B> = List of Eigen-Values in terms of frequencies (\f$ f = \frac{\omega}{2\pi}\f$) after a modal solve.
1238 * - <B>EigenGeneralMass</B> = List of generalized masses for the Eigen-Values.
1239 * .
1240 */
1241
1242 if (index == 1) {
1243 *aoname = EG_strdup("EigenValue");
1244
1245 } else if (index == 2) {
1246 *aoname = EG_strdup("EigenRadian");
1247
1248 } else if (index == 3) {
1249 *aoname = EG_strdup("EigenFrequency");
1250
1251 } else if (index == 4) {
1252 *aoname = EG_strdup("EigenGeneralMass");
1253 }
1254
1255 form->type = Double;
1256 form->units = NULL((void*)0);
1257 form->lfixed = Change;
1258 form->sfixed = Change;
1259 form->vals.reals = NULL((void*)0);
1260 form->vals.real = 0;
1261
1262 /*else if (index == 3) {
1263 *aoname = EG_strdup("EigenVector");
1264 form->type = Double;
1265 form->units = NULL;
1266 form->lfixed = Change;
1267 form->sfixed = Change;
1268 }*/
1269
1270 return CAPS_SUCCESS0;
1271}
1272
1273
1274// Calculate MYSTRAN output
1275int aimCalcOutput(void *instStore, /*@unused@*/ void *aimInfo, int index,
1276 capsValue *val)
1277{
1278 int status = CAPS_SUCCESS0; // Function return status
1279
1280 int i; // Indexing
1281
1282 char filename[PATH_MAX4096]; // File to open
1283 char extOU1[] = ".OU1";
1284 char extF06[] = ".F06";
1285 FILE *fp = NULL((void*)0); // File pointer
1286 aimStorage *mystranInstance;
1287
1288 const double pi = 4.0 * atan(1.0);
1289
1290 mystranInstance = (aimStorage *) instStore;
1291
1292 if (index == 1 || index == 2 || index == 3) {
1293 // Open mystran *.OU1 file - OUTPUT4
1294 snprintf(filename, PATH_MAX4096, "%s%s", mystranInstance->projectName, extOU1);
1295
1296 fp = aim_fopen(aimInfo, filename, "rb");
1297 if (fp == NULL((void*)0)) {
1298#ifdef DEBUG
1299 printf(" mystranAIM/aimCalcOutput Cannot open Output file!\n");
1300#endif
1301 AIM_ERROR(aimInfo, "Failed to open %s", filename){ aim_message(aimInfo, CERROR, 0 , "mystranAIM.c", 1301, __func__
, "Failed to open %s", filename); }
;
1302 return CAPS_IOERR-332;
1303 }
1304
1305 status = mystran_readOutput4Data(fp, "EIGEN_VA", val);
1306 if (status == CAPS_SUCCESS0) {
1307 if (index == 2) {
1308 for (i = 0; i < val->length; i++) {
1309 val->vals.reals[i] = sqrt(val->vals.reals[i]);
1310 }
1311 //val->units = EG_strdup("rads/s");
1312 }
1313
1314 if (index == 3) {
1315 for (i = 0; i < val->length; i++) {
1316 val->vals.reals[i] = sqrt(val->vals.reals[i])/(2*pi);
1317 }
1318 //val->units = EG_strdup("Hz");
1319 }
1320 }
1321
1322 } else if (index == 4) {
1323 // Open mystran *.OU1 file - OUTPUT4
1324 snprintf(filename, PATH_MAX4096, "%s%s", mystranInstance->projectName, extOU1);
1325
1326 fp = aim_fopen(aimInfo, filename, "rb");
1327
1328 if (fp == NULL((void*)0)) {
1329#ifdef DEBUG
1330 printf(" mystranAIM/aimCalcOutput Cannot open Output file!\n");
1331#endif
1332 AIM_ERROR(aimInfo, "Failed to open %s", filename){ aim_message(aimInfo, CERROR, 0 , "mystranAIM.c", 1332, __func__
, "Failed to open %s", filename); }
;
1333 return CAPS_IOERR-332;
1334 }
1335
1336 status = mystran_readOutput4Data(fp, "GEN_MASS", val);
1337
1338 } else if (index == 5) {
1339
1340 // Open mystran *.F06 file
1341 snprintf(filename, PATH_MAX4096, "%s%s", mystranInstance->projectName, extF06);
1342
1343 fp = aim_fopen(aimInfo, filename, "r");
1344
1345 if (fp == NULL((void*)0)) {
1346#ifdef DEBUG
1347 printf(" mystranAIM/aimCalcOutput Cannot open Output file!\n");
1348#endif
1349 AIM_ERROR(aimInfo, "Failed to open %s", filename){ aim_message(aimInfo, CERROR, 0 , "mystranAIM.c", 1349, __func__
, "Failed to open %s", filename); }
;
1350 return CAPS_IOERR-332;
1351 }
1352/*
1353 double **dataMatrix = NULL;
1354 int numEigenVector = 0;
1355 int numGridPoint = 0;
1356 status = mystran_readF06Eigen(fp, &numEigenVector, &numGridPoint,
1357 &dataMatrix);
1358*/
1359 }
1360
1361 if (fp != NULL((void*)0)) fclose(fp);
1362
1363 return status;
1364}
1365
1366
1367void aimCleanup(void *instStore)
1368{
1369 int status; // Returning status
1370 aimStorage *mystranInstance;
1371
1372#ifdef DEBUG
1373 printf(" mystranAIM/aimCleanup!\n");
1374#endif
1375 mystranInstance = (aimStorage *) instStore;
1376
1377 status = destroy_aimStorage(mystranInstance);
1378 if (status != CAPS_SUCCESS0)
1379 printf("Error: Status %d during clean up of instance\n", status);
1380
1381 EG_free(mystranInstance);
1382}
1383
1384
1385int aimDiscr(char *tname, capsDiscr *discr)
1386{
1387 int status; // Function return status
1388
1389 aimStorage *mystranInstance;
1390
1391 int i, numBody;
1392
1393 // EGADS objects
1394 ego *bodies = NULL((void*)0), *tess = NULL((void*)0);
1395
1396 const char *intents;
1397
1398#ifdef DEBUG
1399 printf(" mystranAIM/aimDiscr: tname = %s!\n", tname);
1400#endif
1401
1402 if (tname == NULL((void*)0)) return CAPS_NOTFOUND-303;
1403 mystranInstance = (aimStorage *) discr->instStore;
1404
1405/* if (mystranInstance->dataTransferCheck == (int) false) {
1406 printf("The volume is not suitable for data transfer - possibly the volume mesher "
1407 "added unaccounted for points\n");
1408 return CAPS_BADVALUE;
1409 }*/
1410
1411 // Currently this ONLY works if the capsTranfer lives on single body!
1412 status = aim_getBodies(discr->aInfo, &intents, &numBody, &bodies);
1413 if ((status != CAPS_SUCCESS0) || (bodies == NULL((void*)0))) {
1414 if (status == CAPS_SUCCESS0) status = CAPS_NULLOBJ-309;
1415 printf(" mystranAIM/aimDiscr: aim_getBodies = %d!\n", status);
1416 return status;
1417 }
1418
1419 // Check and generate/retrieve the mesh
1420 status = checkAndCreateMesh(discr->aInfo, mystranInstance);
1421 AIM_STATUS(discr->aInfo, status)if (status != 0) { aim_status(discr->aInfo, status, "mystranAIM.c"
, 1421, __func__, 0); goto cleanup; }
;
1422
1423 AIM_ALLOC(tess, mystranInstance->numMesh, ego, discr->aInfo, status){ if (tess != ((void*)0)) { status = -4; aim_status(discr->
aInfo, status, "mystranAIM.c", 1423, __func__, 1, "AIM_ALLOC: %s != NULL"
, "tess"); goto cleanup; } size_t memorysize = mystranInstance
->numMesh; tess = (ego *) EG_alloc(memorysize*sizeof(ego))
; if (tess == ((void*)0)) { status = -4; aim_status(discr->
aInfo, status, "mystranAIM.c", 1423, __func__, 3, "AIM_ALLOC: %s size %zu type %s"
, "tess", memorysize, "ego"); goto cleanup; } }
;
1424 for (i = 0; i < mystranInstance->numMesh; i++) {
1425 tess[i] = mystranInstance->feaMesh[i].egadsTess;
1426 }
1427
1428 status = mesh_fillDiscr(tname, &mystranInstance->attrMap, mystranInstance->numMesh, tess, discr);
1429 AIM_STATUS(discr->aInfo, status)if (status != 0) { aim_status(discr->aInfo, status, "mystranAIM.c"
, 1429, __func__, 0); goto cleanup; }
;
1430
1431#ifdef DEBUG
1432 printf(" mystranAIM/aimDiscr: Instance = %d, Finished!!\n", iIndex);
1433#endif
1434
1435 status = CAPS_SUCCESS0;
1436
1437cleanup:
1438 if (status != CAPS_SUCCESS0)
1439 printf("\tPremature exit: function aimDiscr mystranAIM status = %d\n",
1440 status);
1441
1442 AIM_FREE(tess){ EG_free(tess); tess = ((void*)0); };
1443 return status;
1444}
1445
1446
1447int aimTransfer(capsDiscr *discr, const char *dataName, int numPoint,
1448 int dataRank, double *dataVal, /*@unused@*/ char **units)
1449{
1450
1451 /*! \page dataTransferMYSTRAN MYSTRAN Data Transfer
1452 *
1453 * The MYSTRAN AIM has the ability to transfer displacements and eigenvectors from the AIM and pressure
1454 * distributions to the AIM using the conservative and interpolative data transfer schemes in CAPS.
1455 *
1456 * \section dataFromMYSTRAN Data transfer from MYSTRAN (FieldOut)
1457 *
1458 * <ul>
1459 * <li> <B>"Displacement"</B> </li> <br>
1460 * Retrieves nodal displacements from the *.F06 file.
1461 * </ul>
1462 *
1463 * <ul>
1464 * <li> <B>"EigenVector_#"</B> </li> <br>
1465 * Retrieves modal eigen-vectors from the *.F06 file, where "#" should be replaced by the
1466 * corresponding mode number for the eigen-vector (eg. EigenVector_3 would correspond to the third mode,
1467 * while EigenVector_6 would be the sixth mode).
1468 * </ul>
1469 *
1470 * \section dataToMYSTRAN Data transfer to MYSTRAN (FieldIn)
1471 * <ul>
1472 * <li> <B>"Pressure"</B> </li> <br>
1473 * Writes appropriate load cards using the provided pressure distribution.
1474 * </ul>
1475 *
1476 */
1477
1478 int status; // Function return status
1479 int i, j, dataPoint, bIndex; // Indexing
1480 aimStorage *mystranInstance;
1481
1482 char *extF06 = ".F06";
1483
1484 // FO6 data variables
1485 int numGridPoint = 0;
1486 int numEigenVector = 0;
1487
1488 double **dataMatrix = NULL((void*)0);
1489
1490 // Specific EigenVector to use
1491 int eigenVectorIndex = 0;
1492
1493 // Variables used in global node mapping
1494 int globalNodeID;
1495
1496 // Filename stuff
1497 char *filename = NULL((void*)0);
1498 FILE *fp; // File pointer
1499
1500#ifdef DEBUG
1501 printf(" mystranAIM/aimTransfer name = %s npts = %d/%d!\n",
1502 dataName, numPoint, dataRank);
1503#endif
1504 mystranInstance = (aimStorage *) discr->instStore;
1505
1506 //capsGroupList = &storage[0]; // List of boundary ID (attrMap) in the transfer
1507
1508 if (strcasecmp(dataName, "Displacement") != 0 &&
1509 strncmp(dataName, "EigenVector", 11) != 0) {
1510
1511 printf("Unrecognized data transfer variable - %s\n", dataName);
1512 return CAPS_NOTFOUND-303;
1513 }
1514
1515 filename = (char *) EG_alloc((strlen(mystranInstance->projectName) +
1516 strlen(extF06) + 1)*sizeof(char));
1517 if (filename == NULL((void*)0)) return EGADS_MALLOC-4;
1518
1519 sprintf(filename,"%s%s", mystranInstance->projectName, extF06);
1520
1521 // Open file
1522 fp = aim_fopen(discr->aInfo, filename, "r");
1523 if (fp == NULL((void*)0)) {
1524 printf("Unable to open file: %s\n", filename);
1525 if (filename != NULL((void*)0)) EG_free(filename);
1526 return CAPS_IOERR-332;
1527 }
1528
1529 if (filename != NULL((void*)0)) EG_free(filename);
1530 filename = NULL((void*)0);
1531
1532 if (strcasecmp(dataName, "Displacement") == 0) {
1533
1534 if (dataRank != 3) {
1535
1536 printf("Invalid rank for dataName \"%s\" - excepted a rank of 3!!!\n",
1537 dataName);
1538 status = CAPS_BADRANK-301;
1539
1540 } else {
1541
1542 status = mystran_readF06Displacement(fp,
1543 1,
1544 &numGridPoint,
1545 &dataMatrix);
1546 fclose(fp);
1547 }
1548
1549 } else if (strncmp(dataName, "EigenVector", 11) == 0) {
1550
1551 // Which EigenVector do we want ?
1552 for (i = 0; i < strlen(dataName); i++) {
1553 if (dataName[i] == '_' ) break;
1554 }
1555
1556 if (i == strlen(dataName)) {
1557 eigenVectorIndex = 1;
1558 } else {
1559
1560 status = sscanf(dataName, "EigenVector_%d", &eigenVectorIndex);
1561 if (status != 1) {
1562 printf("Unable to determine which EigenVector to use - Defaulting the first EigenVector!!!\n");
1563 eigenVectorIndex = 1;
1564 }
1565 }
1566
1567 if (dataRank != 3) {
1568
1569 printf("Invalid rank for dataName \"%s\" - excepted a rank of 3!!!\n",
1570 dataName);
1571 status = CAPS_BADRANK-301;
1572
1573 } else {
1574
1575 status = mystran_readF06EigenVector(fp,
1576 &numEigenVector,
1577 &numGridPoint,
1578 &dataMatrix);
1579 }
1580
1581 fclose(fp);
1582
1583 } else {
1584
1585 status = CAPS_NOTFOUND-303;
1586 }
1587
1588 if (status != CAPS_SUCCESS0) return status;
1589
1590 // Check EigenVector range
1591 if (strncmp(dataName, "EigenVector", 11) == 0) {
1592 if (eigenVectorIndex > numEigenVector) {
1593 printf("Only %d EigenVectors found but index %d requested!\n",
1594 numEigenVector, eigenVectorIndex);
1595 status = CAPS_RANGEERR-326;
1596 goto cleanup;
1597 }
1598
1599 if (eigenVectorIndex < 1) {
1600 printf("For EigenVector_X notation, X must be >= 1, currently X = %d\n",
1601 eigenVectorIndex);
1602 status = CAPS_RANGEERR-326;
1603 goto cleanup;
1604 }
1605 }
1606 if (dataMatrix == NULL((void*)0)) {
1607 status = CAPS_NULLVALUE-307;
1608 goto cleanup;
1609 }
1610
1611 for (i = 0; i < numPoint; i++) {
1612
1613 bIndex = discr->tessGlobal[2*i ];
1614 globalNodeID = discr->tessGlobal[2*i+1] +
1615 discr->bodys[bIndex-1].globalOffset;
1616
1617 if (strcasecmp(dataName, "Displacement") == 0) {
1618
1619 for (dataPoint = 0; dataPoint < numGridPoint; dataPoint++) {
1620 if ((int) dataMatrix[dataPoint][0] == globalNodeID) break;
1621 }
1622
1623 if (dataPoint == numGridPoint) {
1624 printf("Unable to locate global ID = %d in the data matrix\n",
1625 globalNodeID);
1626 status = CAPS_NOTFOUND-303;
1627 goto cleanup;
1628 }
1629
1630 dataVal[dataRank*i+0] = dataMatrix[dataPoint][2]; // T1
1631 dataVal[dataRank*i+1] = dataMatrix[dataPoint][3]; // T2
1632 dataVal[dataRank*i+2] = dataMatrix[dataPoint][4]; // T3
1633
1634 } else if (strncmp(dataName, "EigenVector", 11) == 0) {
1635
1636 for (dataPoint = 0; dataPoint < numGridPoint; dataPoint++) {
1637 if ((int) dataMatrix[eigenVectorIndex - 1][8*dataPoint + 0] ==
1638 globalNodeID) break;
1639 }
1640
1641 if (dataPoint == numGridPoint) {
1642 printf("Unable to locate global ID = %d in the data matrix\n",
1643 globalNodeID);
1644 status = CAPS_NOTFOUND-303;
1645 goto cleanup;
1646 }
1647
1648 dataVal[dataRank*i+0] = dataMatrix[eigenVectorIndex- 1][8*dataPoint + 2]; // T1
1649 dataVal[dataRank*i+1] = dataMatrix[eigenVectorIndex- 1][8*dataPoint + 3]; // T2
1650 dataVal[dataRank*i+2] = dataMatrix[eigenVectorIndex- 1][8*dataPoint + 4]; // T3
1651 //dataVal[dataRank*i+3] = dataMatrix[eigenVectorIndex- 1][8*dataPoint + 5]; // R1 - Don't use rotations
1652 //dataVal[dataRank*i+4] = dataMatrix[eigenVectorIndex- 1][8*dataPoint + 6]; // R2
1653 //dataVal[dataRank*i+5] = dataMatrix[eigenVectorIndex- 1][8*dataPoint + 7]; // R3
1654
1655 }
1656 }
1657
1658 status = CAPS_SUCCESS0;
1659
1660cleanup:
1661 // Free data matrix
1662 if (dataMatrix != NULL((void*)0)) {
1663 j = 0;
1664 if (strcasecmp(dataName, "Displacement") == 0) j = numGridPoint;
1665 else if (strncmp(dataName, "EigenVector", 11) == 0) j = numEigenVector;
1666
1667 for (i = 0; i < j; i++) {
1668 if (dataMatrix[i] != NULL((void*)0)) EG_free(dataMatrix[i]);
1669 }
1670 EG_free(dataMatrix);
1671 }
1672
1673 return status;
1674}
1675
1676
1677void aimFreeDiscrPtr(void *ptr)
1678{
1679 EG_free(ptr); // Extra information to store into the discr void pointer - just a int array
1680}
1681
1682
1683int aimLocateElement(capsDiscr *discr, double *params, double *param,
1684 int *bIndex, int *eIndex, double *bary)
1685{
1686#ifdef DEBUG
1687 printf(" mystranAIM/aimLocateElement!\n");
1688#endif
1689
1690 return aim_locateElement(discr, params, param, bIndex, eIndex, bary);
1691}
1692
1693
1694int aimInterpolation(capsDiscr *discr, const char *name, int bIndex, int eIndex,
1695 double *bary, int rank, double *data, double *result)
1696{
1697#ifdef DEBUG
1698 printf(" mystranAIM/aimInterpolation %s!\n", name);
1699#endif
1700
1701 return aim_interpolation(discr, name, bIndex, eIndex, bary, rank, data,
1702 result);
1703
1704}
1705
1706
1707int aimInterpolateBar(capsDiscr *discr, const char *name, int bIndex,
1708 int eIndex, double *bary, int rank,
1709 double *r_bar, double *d_bar)
1710{
1711#ifdef DEBUG
1712 printf(" mystranAIM/aimInterpolateBar %s!\n", name);
1713#endif
1714
1715 return aim_interpolateBar(discr, name, bIndex, eIndex, bary, rank, r_bar,
1716 d_bar);
1717}
1718
1719
1720int aimIntegration(capsDiscr *discr, const char *name, int bIndex, int eIndex,
1721 int rank, double *data, double *result)
1722{
1723#ifdef DEBUG
1724 printf(" mystranAIM/aimIntegration %s!\n", name);
1725#endif
1726
1727 return aim_integration(discr, name, bIndex, eIndex, rank, data, result);
1728}
1729
1730
1731int aimIntegrateBar(capsDiscr *discr, const char *name, int bIndex, int eIndex,
1732 int rank, double *r_bar, double *d_bar)
1733{
1734#ifdef DEBUG
1735 printf(" mystranAIM/aimIntegrateBar %s!\n", name);
1736#endif
1737
1738 return aim_integrateBar(discr, name, bIndex, eIndex, rank, r_bar, d_bar);
1739}