File: | tacs/tacsAIM.c |
Warning: | line 1210, column 21 Dereference of null pointer |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | |||
2 | * CAPS: Computational Aircraft Prototype Syntheses | |||
3 | * | |||
4 | * TACS AIM | |||
5 | * | |||
6 | * Written by Dr. Marshall C. Galbraith MIT, and Dr. Ryan Durscher and Dr. Ed Alyanak | |||
7 | * | |||
8 | */ | |||
9 | ||||
10 | /*! \mainpage Introduction | |||
11 | * | |||
12 | * \section overviewTACS TACS AIM Overview | |||
13 | * A module in the Computational Aircraft Prototype Syntheses (CAPS) has been developed to interact (primarily | |||
14 | * through input files) with the finite element structural solver TACS \cite TACS. | |||
15 | * | |||
16 | * An outline of the AIM's inputs, outputs and attributes are provided in \ref aimInputsTACS and | |||
17 | * \ref aimOutputsTACS and \ref attributeTACS, respectively. | |||
18 | * | |||
19 | * Details of the AIM's automated data transfer capabilities are outlined in \ref dataTransferTACS | |||
20 | */ | |||
21 | ||||
22 | /*! \page attributeTACS AIM attributes | |||
23 | * The following list of attributes are required for the TACS AIM inside the geometry input. | |||
24 | * | |||
25 | * - <b> capsDiscipline</b> This attribute is a requirement if doing aeroelastic analysis within TACS. capsDiscipline allows | |||
26 | * the AIM to determine which bodies are meant for structural analysis and which are used for aerodynamics. Options | |||
27 | * are: Structure and Aerodynamic (case insensitive). | |||
28 | * | |||
29 | * - <b> capsGroup</b> This is a name assigned to any geometric body to denote a property. This body could be a solid, surface, face, wire, edge or node. | |||
30 | * Recall that a string in ESP starts with a $. For example, attribute <c>capsGroup $Wing</c>. | |||
31 | * | |||
32 | * - <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> | |||
33 | * attribute to allow the user to define a local area to apply a load on without adding multiple <c>capsGroup</c> attributes. | |||
34 | * Recall that a string in ESP starts with a $. For example, attribute <c>capsLoad $force</c>. | |||
35 | * | |||
36 | * - <b> capsConstraint</b> This is a name assigned to any geometric body where a constraint/boundary condition is applied. | |||
37 | * This attribute was separated from the <c>capsGroup</c> attribute to allow the user to define a local area to apply a boundary condition | |||
38 | * without adding multiple <c>capsGroup</c> attributes. Recall that a string in ESP starts with a $. For example, attribute <c>capsConstraint $fixed</c>. | |||
39 | * | |||
40 | * - <b> capsIgnore</b> It is possible that there is a geometric body (or entity) that you do not want the TACS AIM to pay attention to when creating | |||
41 | * a finite element model. The capsIgnore attribute allows a body (or entity) to be in the geometry and ignored by the AIM. For example, | |||
42 | * because of limitations in OpenCASCADE a situation where two edges are overlapping may occur; capsIgnore allows the user to only | |||
43 | * pay attention to one of the overlapping edges. | |||
44 | * | |||
45 | * - <b> capsConnect</b> This is a name assigned to any geometric body where the user wishes to create | |||
46 | * "fictitious" connections such as springs, dampers, and/or rigid body connections to. The user must manually specify | |||
47 | * the connection between two <c>capsConnect</c> entities using the "Connect" tuple (see \ref aimInputsTACS). | |||
48 | * Recall that a string in ESP starts with a $. For example, attribute <c>capsConnect $springStart</c>. | |||
49 | * | |||
50 | * - <b> capsConnectLink</b> Similar to <c>capsConnect</c>, this is a name assigned to any geometric body where | |||
51 | * the user wishes to create "fictitious" connections to. A connection is automatically made if a <c>capsConnectLink</c> | |||
52 | * matches a <c>capsConnect</c> group. Again further specifics of the connection are input using the "Connect" | |||
53 | * tuple (see \ref aimInputsTACS). Recall that a string in ESP starts with a $. | |||
54 | * For example, attribute <c>capsConnectLink $springEnd</c>. | |||
55 | * | |||
56 | * - <b> capsResponse</b> This is a name assigned to any geometric body that will be used to define design sensitivity | |||
57 | * responses for optimization. Specific information for the responses are input using the "Design_Response" tuple (see | |||
58 | * \ref aimInputsTACS). Recall that a string in ESP starts with a $. For examples, | |||
59 | * attribute <c>capsResponse $displacementNode</c>. | |||
60 | * | |||
61 | * - <b> capsBound </b> This is used to mark surfaces on the structural grid in which data transfer with an external | |||
62 | * solver will take place. See \ref dataTransferTACS for additional details. | |||
63 | * | |||
64 | * Internal Aeroelastic Analysis | |||
65 | * | |||
66 | * - <b> capsBound </b> This is used to mark surfaces on the structural grid in which a spline will be created between | |||
67 | * the structural and aero-loads. | |||
68 | * | |||
69 | * - <b> capsReferenceArea</b> [Optional: Default 1.0] Reference area to use when doing aeroelastic analysis. | |||
70 | * This attribute may exist on any aerodynamic cross-section. | |||
71 | * | |||
72 | * - <b> capsReferenceChord</b> [Optional: Default 1.0] Reference chord to use when doing aeroelastic analysis. | |||
73 | * This attribute may exist on any aerodynamic cross-section. | |||
74 | * | |||
75 | * - <b> capsReferenceSpan</b> [Optional: Default 1.0] Reference span to use when doing aeroelastic analysis. | |||
76 | * This attribute may exist on any aerodynamic cross-section. | |||
77 | * | |||
78 | */ | |||
79 | ||||
80 | #include <string.h> | |||
81 | #include <math.h> | |||
82 | #include "capsTypes.h" | |||
83 | #include "aimUtil.h" | |||
84 | ||||
85 | #include "meshUtils.h" // Meshing utilities | |||
86 | #include "miscUtils.h" // Miscellaneous utilities | |||
87 | #include "vlmUtils.h" // Vortex lattice method utilities | |||
88 | #include "vlmSpanSpace.h" | |||
89 | #include "feaUtils.h" // FEA utilities | |||
90 | #include "nastranUtils.h" // Nastran utilities | |||
91 | ||||
92 | #ifdef WIN32 | |||
93 | #define snprintf _snprintf | |||
94 | #define strcasecmp stricmp | |||
95 | #endif | |||
96 | ||||
97 | #define MXCHAR255 255 | |||
98 | ||||
99 | //#define DEBUG | |||
100 | ||||
101 | enum aimInputs | |||
102 | { | |||
103 | Proj_Name = 1, /* index is 1-based */ | |||
104 | Property, | |||
105 | Material, | |||
106 | Constraint, | |||
107 | Load, | |||
108 | Analysix, | |||
109 | Analysis_Type, | |||
110 | File_Format, | |||
111 | Mesh_File_Format, | |||
112 | inDesign_Variable, | |||
113 | Design_Variable_Relation, | |||
114 | Design_Constraint, | |||
115 | Design_Equation, | |||
116 | Design_Table, | |||
117 | Design_Response, | |||
118 | Design_Equation_Response, | |||
119 | Design_Opt_Param, | |||
120 | Support, | |||
121 | Connect, | |||
122 | Parameter, | |||
123 | Mesh, | |||
124 | NUMINPUT = Mesh /* Total number of inputs */ | |||
125 | }; | |||
126 | ||||
127 | #define NUMOUTPUT0 0 | |||
128 | ||||
129 | ||||
130 | typedef struct { | |||
131 | ||||
132 | // Project name | |||
133 | char *projectName; // Project name | |||
134 | ||||
135 | feaUnitsStruct units; // units system | |||
136 | ||||
137 | feaProblemStruct feaProblem; | |||
138 | ||||
139 | // Attribute to capsGroup index map | |||
140 | mapAttrToIndexStruct groupMap; | |||
141 | ||||
142 | // Attribute to constraint index map | |||
143 | mapAttrToIndexStruct constraintMap; | |||
144 | ||||
145 | // Attribute to load index map | |||
146 | mapAttrToIndexStruct loadMap; | |||
147 | ||||
148 | // Attribute to transfer map | |||
149 | mapAttrToIndexStruct transferMap; | |||
150 | ||||
151 | // Attribute to connect map | |||
152 | mapAttrToIndexStruct connectMap; | |||
153 | ||||
154 | // Attribute to response map | |||
155 | mapAttrToIndexStruct responseMap; | |||
156 | ||||
157 | // Mesh holders | |||
158 | int numMesh; | |||
159 | meshStruct *feaMesh; | |||
160 | ||||
161 | } aimStorage; | |||
162 | ||||
163 | ||||
164 | ||||
165 | static int initiate_aimStorage(aimStorage *tacsInstance) | |||
166 | { | |||
167 | ||||
168 | int status; | |||
169 | ||||
170 | // Set initial values for tacsInstance | |||
171 | tacsInstance->projectName = NULL((void*)0); | |||
172 | ||||
173 | /* | |||
174 | // Check to make sure data transfer is ok | |||
175 | tacsInstance->dataTransferCheck = (int) true; | |||
176 | */ | |||
177 | ||||
178 | status = initiate_feaUnitsStruct(&tacsInstance->units); | |||
179 | if (status != CAPS_SUCCESS0) return status; | |||
180 | ||||
181 | // Container for attribute to index map | |||
182 | status = initiate_mapAttrToIndexStruct(&tacsInstance->groupMap); | |||
183 | if (status != CAPS_SUCCESS0) return status; | |||
184 | ||||
185 | // Container for attribute to constraint index map | |||
186 | status = initiate_mapAttrToIndexStruct(&tacsInstance->constraintMap); | |||
187 | if (status != CAPS_SUCCESS0) return status; | |||
188 | ||||
189 | // Container for attribute to load index map | |||
190 | status = initiate_mapAttrToIndexStruct(&tacsInstance->loadMap); | |||
191 | if (status != CAPS_SUCCESS0) return status; | |||
192 | ||||
193 | // Container for transfer to index map | |||
194 | status = initiate_mapAttrToIndexStruct(&tacsInstance->transferMap); | |||
195 | if (status != CAPS_SUCCESS0) return status; | |||
196 | ||||
197 | // Container for connect to index map | |||
198 | status = initiate_mapAttrToIndexStruct(&tacsInstance->connectMap); | |||
199 | if (status != CAPS_SUCCESS0) return status; | |||
200 | ||||
201 | // Container for response to index map | |||
202 | status = initiate_mapAttrToIndexStruct(&tacsInstance->responseMap); | |||
203 | if (status != CAPS_SUCCESS0) return status; | |||
204 | ||||
205 | status = initiate_feaProblemStruct(&tacsInstance->feaProblem); | |||
206 | if (status != CAPS_SUCCESS0) return status; | |||
207 | ||||
208 | // Mesh holders | |||
209 | tacsInstance->numMesh = 0; | |||
210 | tacsInstance->feaMesh = NULL((void*)0); | |||
211 | ||||
212 | return CAPS_SUCCESS0; | |||
213 | } | |||
214 | ||||
215 | ||||
216 | static int destroy_aimStorage(aimStorage *tacsInstance) | |||
217 | { | |||
218 | int i, status; | |||
219 | ||||
220 | status = destroy_feaUnitsStruct(&tacsInstance->units); | |||
221 | if (status != CAPS_SUCCESS0) | |||
222 | printf("Error: Status %d during destroy_feaUnitsStruct!\n", status); | |||
223 | ||||
224 | // Attribute to index map | |||
225 | status = destroy_mapAttrToIndexStruct(&tacsInstance->groupMap); | |||
226 | if (status != CAPS_SUCCESS0) | |||
227 | printf("Error: Status %d during destroy_mapAttrToIndexStruct!\n", status); | |||
228 | ||||
229 | // Attribute to constraint index map | |||
230 | status = destroy_mapAttrToIndexStruct(&tacsInstance->constraintMap); | |||
231 | if (status != CAPS_SUCCESS0) | |||
232 | printf("Error: Status %d during destroy_mapAttrToIndexStruct!\n", status); | |||
233 | ||||
234 | // Attribute to load index map | |||
235 | status = destroy_mapAttrToIndexStruct(&tacsInstance->loadMap); | |||
236 | if (status != CAPS_SUCCESS0) | |||
237 | printf("Error: Status %d during destroy_mapAttrToIndexStruct!\n", status); | |||
238 | ||||
239 | // Transfer to index map | |||
240 | status = destroy_mapAttrToIndexStruct(&tacsInstance->transferMap); | |||
241 | if (status != CAPS_SUCCESS0) | |||
242 | printf("Error: Status %d during destroy_mapAttrToIndexStruct!\n", status); | |||
243 | ||||
244 | // Connect to index map | |||
245 | status = destroy_mapAttrToIndexStruct(&tacsInstance->connectMap); | |||
246 | if (status != CAPS_SUCCESS0) | |||
247 | printf("Error: Status %d during destroy_mapAttrToIndexStruct!\n", status); | |||
248 | ||||
249 | // Response to index map | |||
250 | status = destroy_mapAttrToIndexStruct(&tacsInstance->responseMap); | |||
251 | if (status != CAPS_SUCCESS0) | |||
252 | printf("Error: Status %d during destroy_mapAttrToIndexStruct!\n", status); | |||
253 | ||||
254 | // Cleanup meshes | |||
255 | if (tacsInstance->feaMesh != NULL((void*)0)) { | |||
256 | ||||
257 | for (i = 0; i < tacsInstance->numMesh; i++) { | |||
258 | status = destroy_meshStruct(&tacsInstance->feaMesh[i]); | |||
259 | if (status != CAPS_SUCCESS0) | |||
260 | printf("Error: Status %d during destroy_meshStruct!\n", status); | |||
261 | } | |||
262 | ||||
263 | EG_free(tacsInstance->feaMesh); | |||
264 | } | |||
265 | ||||
266 | tacsInstance->feaMesh = NULL((void*)0); | |||
267 | tacsInstance->numMesh = 0; | |||
268 | ||||
269 | // Destroy FEA problem structure | |||
270 | status = destroy_feaProblemStruct(&tacsInstance->feaProblem); | |||
271 | if (status != CAPS_SUCCESS0) | |||
272 | printf("Error: Status %d during destroy_feaProblemStruct!\n", status); | |||
273 | ||||
274 | // NULL projetName | |||
275 | tacsInstance->projectName = NULL((void*)0); | |||
276 | ||||
277 | return CAPS_SUCCESS0; | |||
278 | } | |||
279 | ||||
280 | ||||
281 | static int checkAndCreateMesh(void *aimInfo, aimStorage *tacsInstance) | |||
282 | { | |||
283 | // Function return flag | |||
284 | int status = CAPS_SUCCESS0; | |||
285 | ||||
286 | status = fea_createMesh(aimInfo, | |||
287 | NULL((void*)0), | |||
288 | 0, | |||
289 | 0, | |||
290 | (int)false0, | |||
291 | &tacsInstance->groupMap, | |||
292 | &tacsInstance->constraintMap, | |||
293 | &tacsInstance->loadMap, | |||
294 | &tacsInstance->transferMap, | |||
295 | &tacsInstance->connectMap, | |||
296 | &tacsInstance->responseMap, | |||
297 | &tacsInstance->numMesh, | |||
298 | &tacsInstance->feaMesh, | |||
299 | &tacsInstance->feaProblem ); | |||
300 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 300 , __func__, 0); goto cleanup; }; | |||
301 | ||||
302 | cleanup: | |||
303 | return status; | |||
304 | } | |||
305 | ||||
306 | /* ********************** Exposed AIM Functions ***************************** */ | |||
307 | ||||
308 | int aimInitialize(int inst, /*@unused@*/ const char *unitSys, void *aimInfo, | |||
309 | /*@unused@*/ void **instStore, /*@unused@*/ int *major, | |||
310 | /*@unused@*/ int *minor, int *nIn, int *nOut, | |||
311 | int *nFields, char ***fnames, int **franks, int **fInOut) | |||
312 | { | |||
313 | int *ints=NULL((void*)0), i, status = CAPS_SUCCESS0; | |||
314 | char **strs=NULL((void*)0); | |||
315 | ||||
316 | aimStorage *tacsInstance=NULL((void*)0); | |||
317 | ||||
318 | #ifdef DEBUG | |||
319 | printf("nastranAIM/aimInitialize instance = %d!\n", inst); | |||
320 | #endif | |||
321 | ||||
322 | /* specify the number of analysis input and out "parameters" */ | |||
323 | *nIn = NUMINPUT; | |||
324 | *nOut = NUMOUTPUT0; | |||
325 | if (inst == -1) return CAPS_SUCCESS0; | |||
326 | ||||
327 | /* specify the field variables this analysis can generate and consume */ | |||
328 | *nFields = 0; | |||
329 | ||||
330 | /* specify the name of each field variable */ | |||
331 | // AIM_ALLOC(strs, *nFields, char *, aimInfo, status); | |||
332 | ||||
333 | // strs[0] = EG_strdup("Displacement"); | |||
334 | // strs[1] = EG_strdup("EigenVector"); | |||
335 | // strs[2] = EG_strdup("EigenVector_#"); | |||
336 | // strs[3] = EG_strdup("Pressure"); | |||
337 | // for (i = 0; i < *nFields; i++) | |||
338 | // if (strs[i] == NULL) { status = EGADS_MALLOC; goto cleanup; } | |||
339 | *fnames = strs; | |||
340 | ||||
341 | /* specify the dimension of each field variable */ | |||
342 | // AIM_ALLOC(ints, *nFields, int, aimInfo, status); | |||
343 | // ints[0] = 3; | |||
344 | // ints[1] = 3; | |||
345 | // ints[2] = 3; | |||
346 | // ints[3] = 1; | |||
347 | *franks = ints; | |||
348 | ints = NULL((void*)0); | |||
349 | ||||
350 | /* specify if a field is an input field or output field */ | |||
351 | // AIM_ALLOC(ints, *nFields, int, aimInfo, status); | |||
352 | // | |||
353 | // ints[0] = FieldOut; | |||
354 | // ints[1] = FieldOut; | |||
355 | // ints[2] = FieldOut; | |||
356 | // ints[3] = FieldIn; | |||
357 | *fInOut = ints; | |||
358 | ints = NULL((void*)0); | |||
359 | ||||
360 | // Allocate tacsInstance | |||
361 | AIM_ALLOC(tacsInstance, 1, aimStorage, aimInfo, status){ if (tacsInstance != ((void*)0)) { status = -4; aim_status(aimInfo , status, "tacsAIM.c", 361, __func__, 1, "AIM_ALLOC: %s != NULL" , "tacsInstance"); goto cleanup; } size_t memorysize = 1; tacsInstance = (aimStorage *) EG_alloc(memorysize*sizeof(aimStorage)); if (tacsInstance == ((void*)0)) { status = -4; aim_status(aimInfo , status, "tacsAIM.c", 361, __func__, 3, "AIM_ALLOC: %s size %zu type %s" , "tacsInstance", memorysize, "aimStorage"); goto cleanup; } }; | |||
362 | *instStore = tacsInstance; | |||
363 | ||||
364 | // Initialize instance storage | |||
365 | (void) initiate_aimStorage(tacsInstance); | |||
366 | ||||
367 | cleanup: | |||
368 | if (status != CAPS_SUCCESS0) { | |||
369 | /* release all possibly allocated memory on error */ | |||
370 | if (*fnames != NULL((void*)0)) | |||
371 | for (i = 0; i < *nFields; i++) AIM_FREE((*fnames)[i]){ EG_free((*fnames)[i]); (*fnames)[i] = ((void*)0); }; | |||
372 | AIM_FREE(*franks){ EG_free(*franks); *franks = ((void*)0); }; | |||
373 | AIM_FREE(*fInOut){ EG_free(*fInOut); *fInOut = ((void*)0); }; | |||
374 | AIM_FREE(*fnames){ EG_free(*fnames); *fnames = ((void*)0); }; | |||
375 | AIM_FREE(*instStore){ EG_free(*instStore); *instStore = ((void*)0); }; | |||
376 | *nFields = 0; | |||
377 | } | |||
378 | ||||
379 | return status; | |||
380 | } | |||
381 | ||||
382 | ||||
383 | int aimInputs(/*@unused@*/ void *instStore, /*@unused@*/ void *aimInfo, | |||
384 | int index, char **ainame, capsValue *defval) | |||
385 | { | |||
386 | ||||
387 | /*! \page aimInputsTACS AIM Inputs | |||
388 | * The following list outlines the TACS inputs along with their default value available | |||
389 | * through the AIM interface. Unless noted these values will be not be linked to | |||
390 | * any parent AIMs with variables of the same name. | |||
391 | */ | |||
392 | int status = CAPS_SUCCESS0; | |||
393 | ||||
394 | #ifdef DEBUG | |||
395 | printf(" nastranAIM/aimInputs index = %d!\n", index); | |||
396 | #endif | |||
397 | ||||
398 | *ainame = NULL((void*)0); | |||
399 | ||||
400 | // TACS Inputs | |||
401 | if (index == Proj_Name) { | |||
402 | *ainame = EG_strdup("Proj_Name"); | |||
403 | defval->type = String; | |||
404 | defval->nullVal = NotNull; | |||
405 | defval->vals.string = EG_strdup("nastran_CAPS"); | |||
406 | defval->lfixed = Change; | |||
407 | ||||
408 | /*! \page aimInputsTACS | |||
409 | * - <B> Proj_Name = "nastran_CAPS"</B> <br> | |||
410 | * This corresponds to the project name used for file naming. | |||
411 | */ | |||
412 | ||||
413 | } else if (index == Property) { | |||
414 | *ainame = EG_strdup("Property"); | |||
415 | defval->type = Tuple; | |||
416 | defval->nullVal = IsNull; | |||
417 | //defval->units = NULL; | |||
418 | defval->lfixed = Change; | |||
419 | defval->vals.tuple = NULL((void*)0); | |||
420 | defval->dim = Vector; | |||
421 | ||||
422 | /*! \page aimInputsTACS | |||
423 | * - <B> Property = NULL</B> <br> | |||
424 | * Property tuple used to input property information for the model, see \ref feaProperty for additional details. | |||
425 | */ | |||
426 | } else if (index == Material) { | |||
427 | *ainame = EG_strdup("Material"); | |||
428 | defval->type = Tuple; | |||
429 | defval->nullVal = IsNull; | |||
430 | //defval->units = NULL; | |||
431 | defval->lfixed = Change; | |||
432 | defval->vals.tuple = NULL((void*)0); | |||
433 | defval->dim = Vector; | |||
434 | ||||
435 | /*! \page aimInputsTACS | |||
436 | * - <B> Material = NULL</B> <br> | |||
437 | * Material tuple used to input material information for the model, see \ref feaMaterial for additional details. | |||
438 | */ | |||
439 | } else if (index == Constraint) { | |||
440 | *ainame = EG_strdup("Constraint"); | |||
441 | defval->type = Tuple; | |||
442 | defval->nullVal = IsNull; | |||
443 | //defval->units = NULL; | |||
444 | defval->lfixed = Change; | |||
445 | defval->vals.tuple = NULL((void*)0); | |||
446 | defval->dim = Vector; | |||
447 | ||||
448 | /*! \page aimInputsTACS | |||
449 | * - <B> Constraint = NULL</B> <br> | |||
450 | * Constraint tuple used to input constraint information for the model, see \ref feaConstraint for additional details. | |||
451 | */ | |||
452 | } else if (index == Load) { | |||
453 | *ainame = EG_strdup("Load"); | |||
454 | defval->type = Tuple; | |||
455 | defval->nullVal = IsNull; | |||
456 | //defval->units = NULL; | |||
457 | defval->lfixed = Change; | |||
458 | defval->vals.tuple = NULL((void*)0); | |||
459 | defval->dim = Vector; | |||
460 | ||||
461 | /*! \page aimInputsTACS | |||
462 | * - <B> Load = NULL</B> <br> | |||
463 | * Load tuple used to input load information for the model, see \ref feaLoad for additional details. | |||
464 | */ | |||
465 | } else if (index == Analysix) { | |||
466 | *ainame = EG_strdup("Analysis"); | |||
467 | defval->type = Tuple; | |||
468 | defval->nullVal = IsNull; | |||
469 | //defval->units = NULL; | |||
470 | defval->lfixed = Change; | |||
471 | defval->vals.tuple = NULL((void*)0); | |||
472 | defval->dim = Vector; | |||
473 | ||||
474 | /*! \page aimInputsTACS | |||
475 | * - <B> Analysis = NULL</B> <br> | |||
476 | * Analysis tuple used to input analysis/case information for the model, see \ref feaAnalysis for additional details. | |||
477 | */ | |||
478 | } else if (index == Analysis_Type) { | |||
479 | *ainame = EG_strdup("Analysis_Type"); | |||
480 | defval->type = String; | |||
481 | defval->nullVal = NotNull; | |||
482 | defval->vals.string = EG_strdup("Modal"); | |||
483 | defval->lfixed = Change; | |||
484 | ||||
485 | /*! \page aimInputsTACS | |||
486 | * - <B> Analysis_Type = "Modal"</B> <br> | |||
487 | * Type of analysis to generate files for, options include "Modal", "Static", "AeroelasticTrim", "AeroelasticFlutter", and "Optimization". | |||
488 | * Note: "Aeroelastic" and "StaticOpt" are still supported and refer to "AeroelasticTrim" and "Optimization". | |||
489 | */ | |||
490 | } else if (index == File_Format) { | |||
491 | *ainame = EG_strdup("File_Format"); | |||
492 | defval->type = String; | |||
493 | defval->vals.string = EG_strdup("Small"); // Small, Large, Free | |||
494 | defval->lfixed = Change; | |||
495 | ||||
496 | /*! \page aimInputsTACS | |||
497 | * - <B> File_Format = "Small"</B> <br> | |||
498 | * Formatting type for the bulk file. Options: "Small", "Large", "Free". | |||
499 | */ | |||
500 | ||||
501 | } else if (index == Mesh_File_Format) { | |||
502 | *ainame = EG_strdup("Mesh_File_Format"); | |||
503 | defval->type = String; | |||
504 | defval->vals.string = EG_strdup("Free"); // Small, Large, Free | |||
505 | defval->lfixed = Change; | |||
506 | ||||
507 | /*! \page aimInputsTACS | |||
508 | * - <B> Mesh_File_Format = "Small"</B> <br> | |||
509 | * Formatting type for the mesh file. Options: "Small", "Large", "Free". | |||
510 | */ | |||
511 | ||||
512 | } else if (index == inDesign_Variable) { | |||
513 | *ainame = EG_strdup("Design_Variable"); | |||
514 | defval->type = Tuple; | |||
515 | defval->nullVal = IsNull; | |||
516 | //defval->units = NULL; | |||
517 | defval->lfixed = Change; | |||
518 | defval->vals.tuple = NULL((void*)0); | |||
519 | defval->dim = Vector; | |||
520 | ||||
521 | /*! \page aimInputsTACS | |||
522 | * - <B> Design_Variable = NULL</B> <br> | |||
523 | * The design variable tuple is used to input design variable information for the model optimization, see \ref feaDesignVariable for additional details. | |||
524 | */ | |||
525 | ||||
526 | } else if (index == Design_Variable_Relation) { | |||
527 | *ainame = EG_strdup("Design_Variable_Relation"); | |||
528 | defval->type = Tuple; | |||
529 | defval->nullVal = IsNull; | |||
530 | //defval->units = NULL; | |||
531 | defval->lfixed = Change; | |||
532 | defval->vals.tuple = NULL((void*)0); | |||
533 | defval->dim = Vector; | |||
534 | ||||
535 | /*! \page aimInputsTACS | |||
536 | * - <B> Design_Variable_Relation = NULL</B> <br> | |||
537 | * The design variable relation tuple is used to input design variable relation information for the model optimization, see \ref feaDesignVariableRelation for additional details. | |||
538 | */ | |||
539 | ||||
540 | } else if (index == Design_Constraint) { | |||
541 | *ainame = EG_strdup("Design_Constraint"); | |||
542 | defval->type = Tuple; | |||
543 | defval->nullVal = IsNull; | |||
544 | //defval->units = NULL; | |||
545 | defval->lfixed = Change; | |||
546 | defval->vals.tuple = NULL((void*)0); | |||
547 | defval->dim = Vector; | |||
548 | ||||
549 | /*! \page aimInputsTACS | |||
550 | * - <B> Design_Constraint = NULL</B> <br> | |||
551 | * The design constraint tuple is used to input design constraint information for the model optimization, see \ref feaDesignConstraint for additional details. | |||
552 | */ | |||
553 | ||||
554 | } else if (index == Design_Equation) { | |||
555 | *ainame = EG_strdup("Design_Equation"); | |||
556 | defval->type = Tuple; | |||
557 | defval->nullVal = IsNull; | |||
558 | //defval->units = NULL; | |||
559 | defval->lfixed = Change; | |||
560 | defval->vals.tuple = NULL((void*)0); | |||
561 | defval->dim = Vector; | |||
562 | ||||
563 | /*! \page aimInputsTACS | |||
564 | * - <B> Design_Equation = NULL</B> <br> | |||
565 | * The design equation tuple used to input information defining equations for use in design sensitivity, see \ref feaDesignEquation for additional details. | |||
566 | */ | |||
567 | ||||
568 | } else if (index == Design_Table) { | |||
569 | *ainame = EG_strdup("Design_Table"); | |||
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 aimInputsTACS | |||
578 | * - <B> Design_Table = NULL</B> <br> | |||
579 | * The design table tuple used to input table of real constants used in equations, see \ref feaDesignTable for additional details. | |||
580 | */ | |||
581 | ||||
582 | } else if (index == Design_Response) { | |||
583 | *ainame = EG_strdup("Design_Response"); | |||
584 | defval->type = Tuple; | |||
585 | defval->nullVal = IsNull; | |||
586 | //defval->units = NULL; | |||
587 | defval->lfixed = Change; | |||
588 | defval->vals.tuple = NULL((void*)0); | |||
589 | defval->dim = Vector; | |||
590 | ||||
591 | /*! \page aimInputsTACS | |||
592 | * - <B> Design_Response = NULL</B> <br> | |||
593 | * The design response tuple used to input design sensitivity response information, see \ref feaDesignResponse for additional details. | |||
594 | */ | |||
595 | ||||
596 | } else if (index == Design_Equation_Response) { | |||
597 | *ainame = EG_strdup("Design_Equation_Response"); | |||
598 | defval->type = Tuple; | |||
599 | defval->nullVal = IsNull; | |||
600 | //defval->units = NULL; | |||
601 | defval->lfixed = Change; | |||
602 | defval->vals.tuple = NULL((void*)0); | |||
603 | defval->dim = Vector; | |||
604 | ||||
605 | /*! \page aimInputsTACS | |||
606 | * - <B> Design_Equation_Response = NULL</B> <br> | |||
607 | * The design equation response tuple used to input design sensitivity equation response information, see \ref feaDesignEquationResponse for additional details. | |||
608 | */ | |||
609 | ||||
610 | } else if (index == Design_Opt_Param) { | |||
611 | *ainame = EG_strdup("Design_Opt_Param"); | |||
612 | defval->type = Tuple; | |||
613 | defval->nullVal = IsNull; | |||
614 | //defval->units = NULL; | |||
615 | defval->lfixed = Change; | |||
616 | defval->vals.tuple = NULL((void*)0); | |||
617 | defval->dim = Vector; | |||
618 | ||||
619 | /*! \page aimInputsTACS | |||
620 | * - <B> Design_Opt_Param = NULL</B> <br> | |||
621 | * The design optimization parameter tuple used to input parameters used in design optimization. | |||
622 | */ | |||
623 | ||||
624 | } else if (index == Support) { | |||
625 | *ainame = EG_strdup("Support"); | |||
626 | defval->type = Tuple; | |||
627 | defval->nullVal = IsNull; | |||
628 | //defval->units = NULL; | |||
629 | defval->lfixed = Change; | |||
630 | defval->vals.tuple = NULL((void*)0); | |||
631 | defval->dim = Vector; | |||
632 | ||||
633 | /*! \page aimInputsTACS | |||
634 | * - <B> Support = NULL</B> <br> | |||
635 | * Support tuple used to input support information for the model, see \ref feaSupport for additional details. | |||
636 | */ | |||
637 | } else if (index == Connect) { | |||
638 | *ainame = EG_strdup("Connect"); | |||
639 | defval->type = Tuple; | |||
640 | defval->nullVal = IsNull; | |||
641 | //defval->units = NULL; | |||
642 | defval->lfixed = Change; | |||
643 | defval->vals.tuple = NULL((void*)0); | |||
644 | defval->dim = Vector; | |||
645 | ||||
646 | /*! \page aimInputsTACS | |||
647 | * - <B> Connect = NULL</B> <br> | |||
648 | * Connect tuple used to define connection to be made in the, see \ref feaConnection for additional details. | |||
649 | */ | |||
650 | } else if (index == Parameter) { | |||
651 | *ainame = EG_strdup("Parameter"); | |||
652 | defval->type = Tuple; | |||
653 | defval->nullVal = IsNull; | |||
654 | //defval->units = NULL; | |||
655 | defval->lfixed = Change; | |||
656 | defval->vals.tuple = NULL((void*)0); | |||
657 | defval->dim = Vector; | |||
658 | ||||
659 | /*! \page aimInputsTACS | |||
660 | * - <B> Parameter = NULL</B> <br> | |||
661 | * Parameter tuple used to define PARAM entries. Note, entries are output exactly as inputed, that is, if the PARAM entry | |||
662 | * requires an integer entry the user must input an integer! | |||
663 | */ | |||
664 | ||||
665 | } else if (index == Mesh) { | |||
666 | *ainame = AIM_NAME(Mesh)EG_strdup("Mesh"); | |||
667 | defval->type = Pointer; | |||
668 | defval->dim = Vector; | |||
669 | defval->lfixed = Change; | |||
670 | defval->sfixed = Change; | |||
671 | defval->vals.AIMptr = NULL((void*)0); | |||
672 | defval->nullVal = IsNull; | |||
673 | AIM_STRDUP(defval->units, "meshStruct", aimInfo, status){ if (defval->units != ((void*)0)) { status = -4; aim_status (aimInfo, status, "tacsAIM.c", 673, __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, "tacsAIM.c", 673, __func__, 2 , "AIM_STRDUP: %s %s", "defval->units", "meshStruct"); goto cleanup; } }; | |||
674 | ||||
675 | /*! \page aimInputsTACS | |||
676 | * - <B>Mesh = NULL</B> <br> | |||
677 | * A Mesh link. | |||
678 | */ | |||
679 | } | |||
680 | ||||
681 | AIM_NOTNULL(*ainame, aimInfo, status){ if (*ainame == ((void*)0)) { status = -307; aim_status(aimInfo , status, "tacsAIM.c", 681, __func__, 1, "%s == NULL!", "*ainame" ); goto cleanup; } }; | |||
682 | ||||
683 | cleanup: | |||
684 | if (status != CAPS_SUCCESS0) AIM_FREE(*ainame){ EG_free(*ainame); *ainame = ((void*)0); }; | |||
685 | return status; | |||
686 | } | |||
687 | ||||
688 | ||||
689 | // ********************** AIM Function Break ***************************** | |||
690 | int aimUpdateState(void *instStore, void *aimInfo, | |||
691 | capsValue *aimInputs) | |||
692 | { | |||
693 | int status; // Function return status | |||
694 | ||||
695 | const char *analysisType = NULL((void*)0); | |||
696 | ||||
697 | aimStorage *tacsInstance; | |||
698 | ||||
699 | tacsInstance = (aimStorage *) instStore; | |||
700 | AIM_NOTNULL(aimInputs, aimInfo, status){ if (aimInputs == ((void*)0)) { status = -307; aim_status(aimInfo , status, "tacsAIM.c", 700, __func__, 1, "%s == NULL!", "aimInputs" ); goto cleanup; } }; | |||
701 | ||||
702 | // Get project name | |||
703 | tacsInstance->projectName = aimInputs[Proj_Name-1].vals.string; | |||
704 | ||||
705 | // Analysis type | |||
706 | analysisType = aimInputs[Analysis_Type-1].vals.string; | |||
707 | ||||
708 | if (aimInputs[Mesh-1].nullVal == IsNull) { | |||
709 | AIM_ANALYSISIN_ERROR(aimInfo, Mesh, "'Mesh' input must be linked to an output 'Surface_Mesh'"){ aim_message(aimInfo, CERROR, Mesh, "tacsAIM.c", 709, __func__ , "'Mesh' input must be linked to an output 'Surface_Mesh'"); }; | |||
710 | status = CAPS_BADVALUE-311; | |||
711 | goto cleanup; | |||
712 | } | |||
713 | ||||
714 | // Get FEA mesh if we don't already have one | |||
715 | status = checkAndCreateMesh(aimInfo, tacsInstance); | |||
716 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 716 , __func__, 0); goto cleanup; }; | |||
717 | ||||
718 | // Note: Setting order is important here. | |||
719 | // 1. Materials should be set before properties. | |||
720 | // 2. Coordinate system should be set before mesh and loads | |||
721 | // 3. Mesh should be set before loads, constraints, supports, and connections | |||
722 | // 4. Constraints and loads should be set before analysis | |||
723 | // 5. Optimization should be set after properties, but before analysis | |||
724 | ||||
725 | // Set material properties | |||
726 | if (aimInputs[Material-1].nullVal == NotNull) { | |||
727 | status = fea_getMaterial(aimInfo, | |||
728 | aimInputs[Material-1].length, | |||
729 | aimInputs[Material-1].vals.tuple, | |||
730 | &tacsInstance->units, | |||
731 | &tacsInstance->feaProblem.numMaterial, | |||
732 | &tacsInstance->feaProblem.feaMaterial); | |||
733 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 733 , __func__, 0); goto cleanup; }; | |||
734 | } else printf("Material tuple is NULL - No materials set\n"); | |||
735 | ||||
736 | // Set property properties | |||
737 | if (aimInputs[Property-1].nullVal == NotNull) { | |||
738 | status = fea_getProperty(aimInfo, | |||
739 | aimInputs[Property-1].length, | |||
740 | aimInputs[Property-1].vals.tuple, | |||
741 | &tacsInstance->groupMap, | |||
742 | &tacsInstance->units, | |||
743 | &tacsInstance->feaProblem); | |||
744 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 744 , __func__, 0); goto cleanup; }; | |||
745 | ||||
746 | ||||
747 | // Assign element "subtypes" based on properties set | |||
748 | status = fea_assignElementSubType(tacsInstance->feaProblem.numProperty, | |||
749 | tacsInstance->feaProblem.feaProperty, | |||
750 | &tacsInstance->feaProblem.feaMesh); | |||
751 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 751 , __func__, 0); goto cleanup; }; | |||
752 | ||||
753 | } else printf("Property tuple is NULL - No properties set\n"); | |||
754 | ||||
755 | // Set constraint properties | |||
756 | if (aimInputs[Constraint-1].nullVal == NotNull) { | |||
757 | status = fea_getConstraint(aimInputs[Constraint-1].length, | |||
758 | aimInputs[Constraint-1].vals.tuple, | |||
759 | &tacsInstance->constraintMap, | |||
760 | &tacsInstance->feaProblem); | |||
761 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 761 , __func__, 0); goto cleanup; }; | |||
762 | } else printf("Constraint tuple is NULL - No constraints applied\n"); | |||
763 | ||||
764 | // Set support properties | |||
765 | if (aimInputs[Support-1].nullVal == NotNull) { | |||
766 | status = fea_getSupport(aimInputs[Support-1].length, | |||
767 | aimInputs[Support-1].vals.tuple, | |||
768 | &tacsInstance->constraintMap, | |||
769 | &tacsInstance->feaProblem); | |||
770 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 770 , __func__, 0); goto cleanup; }; | |||
771 | } else printf("Support tuple is NULL - No supports applied\n"); | |||
772 | ||||
773 | // Set connection properties | |||
774 | if (aimInputs[Connect-1].nullVal == NotNull) { | |||
775 | status = fea_getConnection(aimInputs[Connect-1].length, | |||
776 | aimInputs[Connect-1].vals.tuple, | |||
777 | &tacsInstance->connectMap, | |||
778 | &tacsInstance->feaProblem); | |||
779 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 779 , __func__, 0); goto cleanup; }; | |||
780 | } else printf("Connect tuple is NULL - Using defaults\n"); | |||
781 | ||||
782 | // Set load properties | |||
783 | if (aimInputs[Load-1].nullVal == NotNull) { | |||
784 | status = fea_getLoad(aimInputs[Load-1].length, | |||
785 | aimInputs[Load-1].vals.tuple, | |||
786 | &tacsInstance->loadMap, | |||
787 | &tacsInstance->feaProblem); | |||
788 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 788 , __func__, 0); goto cleanup; }; | |||
789 | } else printf("Load tuple is NULL - No loads applied\n"); | |||
790 | ||||
791 | // Set design variables | |||
792 | if (aimInputs[inDesign_Variable-1].nullVal == NotNull) { | |||
793 | status = fea_getDesignVariable(aimInfo, | |||
794 | (int)false0, | |||
795 | aimInputs[inDesign_Variable-1].length, | |||
796 | aimInputs[inDesign_Variable-1].vals.tuple, | |||
797 | aimInputs[Design_Variable_Relation-1].length, | |||
798 | aimInputs[Design_Variable_Relation-1].vals.tuple, | |||
799 | &tacsInstance->groupMap, | |||
800 | &tacsInstance->feaProblem); | |||
801 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 801 , __func__, 0); goto cleanup; }; | |||
802 | ||||
803 | } else printf("Design_Variable tuple is NULL - No design variables applied\n"); | |||
804 | ||||
805 | // Set design constraints | |||
806 | if (aimInputs[Design_Constraint-1].nullVal == NotNull) { | |||
807 | status = fea_getDesignConstraint(aimInputs[Design_Constraint-1].length, | |||
808 | aimInputs[Design_Constraint-1].vals.tuple, | |||
809 | &tacsInstance->feaProblem); | |||
810 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 810 , __func__, 0); goto cleanup; }; | |||
811 | } else printf("Design_Constraint tuple is NULL - No design constraints applied\n"); | |||
812 | ||||
813 | // Set design equations | |||
814 | if (aimInputs[Design_Equation-1].nullVal == NotNull) { | |||
815 | status = fea_getDesignEquation(aimInputs[Design_Equation-1].length, | |||
816 | aimInputs[Design_Equation-1].vals.tuple, | |||
817 | &tacsInstance->feaProblem); | |||
818 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 818 , __func__, 0); goto cleanup; }; | |||
819 | } else printf("Design_Equation tuple is NULL - No design equations applied\n"); | |||
820 | ||||
821 | // Set design table constants | |||
822 | if (aimInputs[Design_Table-1].nullVal == NotNull) { | |||
823 | status = fea_getDesignTable(aimInputs[Design_Table-1].length, | |||
824 | aimInputs[Design_Table-1].vals.tuple, | |||
825 | &tacsInstance->feaProblem); | |||
826 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 826 , __func__, 0); goto cleanup; }; | |||
827 | } else printf("Design_Table tuple is NULL - No design table constants applied\n"); | |||
828 | ||||
829 | // Set design optimization parameters | |||
830 | if (aimInputs[Design_Opt_Param-1].nullVal == NotNull) { | |||
831 | status = fea_getDesignOptParam(aimInputs[Design_Opt_Param-1].length, | |||
832 | aimInputs[Design_Opt_Param-1].vals.tuple, | |||
833 | &tacsInstance->feaProblem); | |||
834 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 834 , __func__, 0); goto cleanup; }; | |||
835 | } else printf("Design_Opt_Param tuple is NULL - No design optimization parameters applied\n"); | |||
836 | ||||
837 | // Set design responses | |||
838 | if (aimInputs[Design_Response-1].nullVal == NotNull) { | |||
839 | status = fea_getDesignResponse(aimInputs[Design_Response-1].length, | |||
840 | aimInputs[Design_Response-1].vals.tuple, | |||
841 | &tacsInstance->responseMap, | |||
842 | &tacsInstance->feaProblem); | |||
843 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 843 , __func__, 0); goto cleanup; }; | |||
844 | } else printf("Design_Response tuple is NULL - No design responses applied\n"); | |||
845 | ||||
846 | // Set design equation responses | |||
847 | if (aimInputs[Design_Equation_Response-1].nullVal == NotNull) { | |||
848 | status = fea_getDesignEquationResponse(aimInputs[Design_Equation_Response-1].length, | |||
849 | aimInputs[Design_Equation_Response-1].vals.tuple, | |||
850 | &tacsInstance->feaProblem); | |||
851 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 851 , __func__, 0); goto cleanup; }; | |||
852 | } else printf("Design_Equation_Response tuple is NULL - No design equation responses applied\n"); | |||
853 | ||||
854 | // Set analysis settings | |||
855 | if (aimInputs[Analysix-1].nullVal == NotNull) { | |||
856 | status = fea_getAnalysis(aimInputs[Analysix-1].length, | |||
857 | aimInputs[Analysix-1].vals.tuple, | |||
858 | &tacsInstance->feaProblem); | |||
859 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 859 , __func__, 0); goto cleanup; }; // It ok to not have an analysis tuple | |||
860 | } else { | |||
861 | printf("Analysis tuple is NULL\n"); | |||
862 | status = fea_createDefaultAnalysis(&tacsInstance->feaProblem, analysisType); | |||
863 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 863 , __func__, 0); goto cleanup; }; | |||
864 | } | |||
865 | ||||
866 | ||||
867 | // Set file format type | |||
868 | if (strcasecmp(aimInputs[File_Format-1].vals.string, "Small") == 0) { | |||
869 | tacsInstance->feaProblem.feaFileFormat.fileType = SmallField; | |||
870 | } else if (strcasecmp(aimInputs[File_Format-1].vals.string, "Large") == 0) { | |||
871 | tacsInstance->feaProblem.feaFileFormat.fileType = LargeField; | |||
872 | } else if (strcasecmp(aimInputs[File_Format-1].vals.string, "Free") == 0) { | |||
873 | tacsInstance->feaProblem.feaFileFormat.fileType = FreeField; | |||
874 | } else { | |||
875 | printf("Unrecognized \"File_Format\", valid choices are [Small, Large, or Free]. Reverting to default\n"); | |||
876 | } | |||
877 | ||||
878 | // Set grid file format type | |||
879 | if (strcasecmp(aimInputs[Mesh_File_Format-1].vals.string, "Small") == 0) { | |||
880 | tacsInstance->feaProblem.feaFileFormat.gridFileType = SmallField; | |||
881 | } else if (strcasecmp(aimInputs[Mesh_File_Format-1].vals.string, "Large") == 0) { | |||
882 | tacsInstance->feaProblem.feaFileFormat.gridFileType = LargeField; | |||
883 | } else if (strcasecmp(aimInputs[Mesh_File_Format-1].vals.string, "Free") == 0) { | |||
884 | tacsInstance->feaProblem.feaFileFormat.gridFileType = FreeField; | |||
885 | } else { | |||
886 | printf("Unrecognized \"Mesh_File_Format\", valid choices are [Small, Large, or Free]. Reverting to default\n"); | |||
887 | } | |||
888 | ||||
889 | cleanup: | |||
890 | return status; | |||
891 | } | |||
892 | ||||
893 | ||||
894 | // ********************** AIM Function Break ***************************** | |||
895 | int aimPreAnalysis(const void *instStore, void *aimInfo, capsValue *aimInputs) | |||
896 | { | |||
897 | ||||
898 | int i, j, k, l; // Indexing | |||
899 | ||||
900 | int status; // Status return | |||
901 | ||||
902 | int found; // Boolean operator | |||
903 | ||||
904 | int *tempIntegerArray = NULL((void*)0); // Temporary array to store a list of integers | |||
905 | ||||
906 | // Analysis information | |||
907 | const char *analysisType = NULL((void*)0); | |||
908 | int haveSubAeroelasticTrim = (int) false0; | |||
909 | int haveSubAeroelasticFlutter = (int) false0; | |||
910 | ||||
911 | // Aeroelastic Information | |||
912 | int numAEStatSurf = 0; | |||
913 | //char **aeStatSurf = NULL; | |||
914 | ||||
915 | // File format information | |||
916 | char *tempString = NULL((void*)0), *delimiter = NULL((void*)0); | |||
917 | ||||
918 | // File IO | |||
919 | char *filename = NULL((void*)0); // Output file name | |||
920 | FILE *fp = NULL((void*)0); // Output file pointer | |||
921 | ||||
922 | feaLoadStruct *feaLoad=NULL((void*)0); | |||
| ||||
923 | int numThermalLoad=0; | |||
924 | ||||
925 | int numSetID; | |||
926 | int tempID, *setID = NULL((void*)0); | |||
927 | ||||
928 | const aimStorage *tacsInstance; | |||
929 | ||||
930 | tacsInstance = (const aimStorage *) instStore; | |||
931 | AIM_NOTNULL(aimInputs, aimInfo, status){ if (aimInputs == ((void*)0)) { status = -307; aim_status(aimInfo , status, "tacsAIM.c", 931, __func__, 1, "%s == NULL!", "aimInputs" ); goto cleanup; } }; | |||
932 | ||||
933 | // Analysis type | |||
934 | analysisType = aimInputs[Analysis_Type-1].vals.string; | |||
935 | ||||
936 | if (tacsInstance->feaProblem.numLoad > 0) { | |||
937 | AIM_ALLOC(feaLoad, tacsInstance->feaProblem.numLoad, feaLoadStruct, aimInfo, status){ if (feaLoad != ((void*)0)) { status = -4; aim_status(aimInfo , status, "tacsAIM.c", 937, __func__, 1, "AIM_ALLOC: %s != NULL" , "feaLoad"); goto cleanup; } size_t memorysize = tacsInstance ->feaProblem.numLoad; feaLoad = (feaLoadStruct *) EG_alloc (memorysize*sizeof(feaLoadStruct)); if (feaLoad == ((void*)0) ) { status = -4; aim_status(aimInfo, status, "tacsAIM.c", 937 , __func__, 3, "AIM_ALLOC: %s size %zu type %s", "feaLoad", memorysize , "feaLoadStruct"); goto cleanup; } }; | |||
938 | for (i = 0; i < tacsInstance->feaProblem.numLoad; i++) initiate_feaLoadStruct(&feaLoad[i]); | |||
939 | for (i = 0; i < tacsInstance->feaProblem.numLoad; i++) { | |||
940 | status = copy_feaLoadStruct(aimInfo, &tacsInstance->feaProblem.feaLoad[i], &feaLoad[i]); | |||
941 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 941 , __func__, 0); goto cleanup; }; | |||
942 | ||||
943 | if (feaLoad[i].loadType == PressureExternal) { | |||
944 | ||||
945 | // Transfer external pressures from the AIM discrObj | |||
946 | status = fea_transferExternalPressure(aimInfo, | |||
947 | &tacsInstance->feaProblem.feaMesh, | |||
948 | &feaLoad[i]); | |||
949 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 949 , __func__, 0); goto cleanup; }; | |||
950 | } | |||
951 | } | |||
952 | } | |||
953 | ||||
954 | // Write TACS Mesh | |||
955 | filename = EG_alloc(MXCHAR255 +1); | |||
956 | if (filename == NULL((void*)0)) return EGADS_MALLOC-4; | |||
957 | ||||
958 | strcpy(filename, tacsInstance->projectName); | |||
959 | ||||
960 | status = mesh_writeNASTRAN(aimInfo, | |||
961 | filename, | |||
962 | 1, | |||
963 | &tacsInstance->feaProblem.feaMesh, | |||
964 | tacsInstance->feaProblem.feaFileFormat.gridFileType, | |||
965 | 1.0); | |||
966 | if (status != CAPS_SUCCESS0) { | |||
967 | EG_free(filename); | |||
968 | return status; | |||
969 | } | |||
970 | ||||
971 | // Write TACS subElement types not supported by mesh_writeNASTRAN | |||
972 | strcat(filename, ".bdf"); | |||
973 | fp = aim_fopen(aimInfo, filename, "a"); | |||
974 | if (fp == NULL((void*)0)) { | |||
975 | printf("Unable to open file: %s\n", filename); | |||
976 | EG_free(filename); | |||
977 | return CAPS_IOERR-332; | |||
978 | } | |||
979 | EG_free(filename); | |||
980 | ||||
981 | printf("Writing subElement types (if any) - appending mesh file\n"); | |||
982 | status = nastran_writeSubElementCard(fp, | |||
983 | &tacsInstance->feaProblem.feaMesh, | |||
984 | tacsInstance->feaProblem.numProperty, | |||
985 | tacsInstance->feaProblem.feaProperty, | |||
986 | &tacsInstance->feaProblem.feaFileFormat); | |||
987 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 987 , __func__, 0); goto cleanup; }; | |||
988 | ||||
989 | // Connections | |||
990 | for (i = 0; i < tacsInstance->feaProblem.numConnect; i++) { | |||
991 | ||||
992 | if (i == 0) { | |||
993 | printf("Writing connection cards - appending mesh file\n"); | |||
994 | } | |||
995 | ||||
996 | status = nastran_writeConnectionCard(fp, | |||
997 | &tacsInstance->feaProblem.feaConnect[i], | |||
998 | &tacsInstance->feaProblem.feaFileFormat); | |||
999 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 999 , __func__, 0); goto cleanup; }; | |||
1000 | } | |||
1001 | if (fp
| |||
1002 | fp = NULL((void*)0); | |||
1003 | ||||
1004 | // Write nastran input file | |||
1005 | filename = EG_alloc(MXCHAR255 +1); | |||
1006 | if (filename == NULL((void*)0)) return EGADS_MALLOC-4; | |||
1007 | strcpy(filename, tacsInstance->projectName); | |||
1008 | strcat(filename, ".dat"); | |||
1009 | ||||
1010 | printf("\nWriting TACS instruction file....\n"); | |||
1011 | fp = aim_fopen(aimInfo, filename, "w"); | |||
1012 | if (fp == NULL((void*)0)) { | |||
1013 | AIM_ERROR(aimInfo, "Unable to open file: %s\n", filename){ aim_message(aimInfo, CERROR, 0 , "tacsAIM.c", 1013, __func__ , "Unable to open file: %s\n", filename); }; | |||
1014 | EG_free(filename); | |||
1015 | return CAPS_IOERR-332; | |||
1016 | } | |||
1017 | EG_free(filename); | |||
1018 | ||||
1019 | // define file format delimiter type | |||
1020 | if (tacsInstance->feaProblem.feaFileFormat.fileType == FreeField) { | |||
1021 | delimiter = ","; | |||
1022 | } else { | |||
1023 | delimiter = " "; | |||
1024 | } | |||
1025 | ||||
1026 | //////////////// Executive control //////////////// | |||
1027 | fprintf(fp, "ID CAPS generated Problem FOR TACS\n"); | |||
1028 | ||||
1029 | // Analysis type | |||
1030 | if (strcasecmp(analysisType, "Modal") == 0) fprintf(fp, "SOL 3\n"); | |||
1031 | else if(strcasecmp(analysisType, "Static") == 0) fprintf(fp, "SOL 1\n"); | |||
1032 | else if(strcasecmp(analysisType, "Craig-Bampton") == 0) fprintf(fp, "SOL 31\n"); | |||
1033 | else if(strcasecmp(analysisType, "StaticOpt") == 0) fprintf(fp, "SOL 200\n"); | |||
1034 | else if(strcasecmp(analysisType, "Optimization") == 0) fprintf(fp, "SOL 200\n"); | |||
1035 | else if(strcasecmp(analysisType, "Aeroelastic") == 0) fprintf(fp, "SOL 144\n"); | |||
1036 | else if(strcasecmp(analysisType, "AeroelasticTrim") == 0) fprintf(fp, "SOL 144\n"); | |||
1037 | else if(strcasecmp(analysisType, "AeroelasticFlutter") == 0) fprintf(fp, "SOL 145\n"); | |||
1038 | else { | |||
1039 | AIM_ERROR(aimInfo, "Unrecognized \"Analysis_Type\", %s", analysisType){ aim_message(aimInfo, CERROR, 0 , "tacsAIM.c", 1039, __func__ , "Unrecognized \"Analysis_Type\", %s", analysisType); }; | |||
1040 | status = CAPS_BADVALUE-311; | |||
1041 | goto cleanup; | |||
1042 | } | |||
1043 | ||||
1044 | fprintf(fp, "CEND\n\n"); | |||
1045 | ||||
1046 | if (tacsInstance->feaProblem.feaMesh.numNode> 10000) fprintf(fp, "LINE=%d\n", tacsInstance->feaProblem.feaMesh.numNode*10); | |||
1047 | else fprintf(fp, "LINE=10000\n"); | |||
1048 | ||||
1049 | ||||
1050 | // Set up the case information | |||
1051 | if (tacsInstance->feaProblem.numAnalysis == 0) { | |||
1052 | printf("Error: No analyses in the feaProblem! (this shouldn't be possible)\n"); | |||
1053 | status = CAPS_BADVALUE-311; | |||
1054 | goto cleanup; | |||
1055 | } | |||
1056 | ||||
1057 | //////////////// Case control //////////////// | |||
1058 | ||||
1059 | // Write output request information | |||
1060 | fprintf(fp, "DISP (PRINT,PUNCH) = ALL\n"); // Output all displacements | |||
1061 | ||||
1062 | fprintf(fp, "STRE (PRINT,PUNCH) = ALL\n"); // Output all stress | |||
1063 | ||||
1064 | fprintf(fp, "STRA (PRINT,PUNCH) = ALL\n"); // Output all strain | |||
1065 | ||||
1066 | // Write sub-case information if multiple analysis tuples were provide - will always have at least 1 | |||
1067 | for (i = 0; i < tacsInstance->feaProblem.numAnalysis; i++) { | |||
1068 | //printf("SUBCASE = %d\n", i); | |||
1069 | ||||
1070 | fprintf(fp, "SUBCASE %d\n", i+1); | |||
1071 | fprintf(fp, "\tLABEL = %s\n", tacsInstance->feaProblem.feaAnalysis[i].name); | |||
1072 | ||||
1073 | if (tacsInstance->feaProblem.feaAnalysis[i].analysisType == Static) { | |||
1074 | fprintf(fp,"\tANALYSIS = STATICS\n"); | |||
1075 | } else if (tacsInstance->feaProblem.feaAnalysis[i].analysisType == Modal) { | |||
1076 | fprintf(fp,"\tANALYSIS = MODES\n"); | |||
1077 | } else if (tacsInstance->feaProblem.feaAnalysis[i].analysisType == AeroelasticTrim) { | |||
1078 | fprintf(fp,"\tANALYSIS = SAERO\n"); | |||
1079 | haveSubAeroelasticTrim = (int) true1; | |||
1080 | } else if (tacsInstance->feaProblem.feaAnalysis[i].analysisType == AeroelasticFlutter) { | |||
1081 | fprintf(fp,"\tANALYSIS = FLUTTER\n"); | |||
1082 | haveSubAeroelasticFlutter = (int) true1; | |||
1083 | } else if (tacsInstance->feaProblem.feaAnalysis[i].analysisType == Optimization) { | |||
1084 | printf("\t *** WARNING :: INPUT TO ANALYSIS CASE INPUT analysisType should NOT be Optimization or StaticOpt - Defaulting to Static\n"); | |||
1085 | fprintf(fp,"\tANALYSIS = STATICS\n"); | |||
1086 | } | |||
1087 | ||||
1088 | // Write support for sub-case | |||
1089 | if (tacsInstance->feaProblem.feaAnalysis[i].numSupport != 0) { | |||
1090 | if (tacsInstance->feaProblem.feaAnalysis[i].numSupport > 1) { | |||
1091 | printf("\tWARNING: More than 1 support is not supported at this time for sub-cases!\n"); | |||
1092 | ||||
1093 | } else { | |||
1094 | fprintf(fp, "\tSUPORT1 = %d\n", tacsInstance->feaProblem.feaAnalysis[i].supportSetID[0]); | |||
1095 | } | |||
1096 | } | |||
1097 | ||||
1098 | // Write constraint for sub-case | |||
1099 | if (tacsInstance->feaProblem.numConstraint != 0) { | |||
1100 | fprintf(fp, "\tSPC = %d\n", tacsInstance->feaProblem.numConstraint+i+1); //TODO - change to i+1 to just i | |||
1101 | } | |||
1102 | ||||
1103 | // Issue some warnings regarding constraints if necessary | |||
1104 | if (tacsInstance->feaProblem.feaAnalysis[i].numConstraint == 0 && tacsInstance->feaProblem.numConstraint !=0) { | |||
1105 | ||||
1106 | printf("\tWarning: No constraints specified for case %s, assuming " | |||
1107 | "all constraints are applied!!!!\n", tacsInstance->feaProblem.feaAnalysis[i].name); | |||
1108 | ||||
1109 | } else if (tacsInstance->feaProblem.numConstraint
| |||
1110 | ||||
1111 | printf("\tWarning: No constraints specified for case %s!!!!\n", tacsInstance->feaProblem.feaAnalysis[i].name); | |||
1112 | } | |||
1113 | ||||
1114 | // // Write MPC for sub-case - currently only supported when we have RBE2 elements - see above for unification - TODO - investigate | |||
1115 | // for (j = 0; j < astrosInstance[iIndex].feaProblem.numConnect; j++) { | |||
1116 | // | |||
1117 | // if (astrosInstance[iIndex].feaProblem.feaConnect[j].connectionType == RigidBody) { | |||
1118 | // | |||
1119 | // if (addComma == (int) true) fprintf(fp,","); | |||
1120 | // | |||
1121 | // fprintf(fp, " MPC = %d ", astrosInstance[iIndex].feaProblem.feaConnect[j].connectionID); | |||
1122 | // addComma = (int) true; | |||
1123 | // break; | |||
1124 | // } | |||
1125 | // } | |||
1126 | ||||
1127 | if (tacsInstance->feaProblem.feaAnalysis[i].analysisType
| |||
1128 | fprintf(fp,"\tMETHOD = %d\n", tacsInstance->feaProblem.feaAnalysis[i].analysisID); | |||
1129 | } | |||
1130 | ||||
1131 | if (tacsInstance->feaProblem.feaAnalysis[i].analysisType
| |||
1132 | fprintf(fp,"\tMETHOD = %d\n", tacsInstance->feaProblem.feaAnalysis[i].analysisID); | |||
1133 | fprintf(fp,"\tFMETHOD = %d\n", 100+tacsInstance->feaProblem.feaAnalysis[i].analysisID); | |||
1134 | } | |||
1135 | ||||
1136 | if (tacsInstance->feaProblem.feaAnalysis[i].analysisType
| |||
1137 | fprintf(fp,"\tTRIM = %d\n", tacsInstance->feaProblem.feaAnalysis[i].analysisID); | |||
1138 | } | |||
1139 | ||||
1140 | if (tacsInstance->feaProblem.feaAnalysis[i].analysisType
| |||
1141 | tacsInstance->feaProblem.feaAnalysis[i].analysisType
| |||
1142 | ||||
1143 | if (tacsInstance->feaProblem.feaAnalysis[i].aeroSymmetryXY != NULL((void*)0)) { | |||
1144 | ||||
1145 | if(strcmp("SYM",tacsInstance->feaProblem.feaAnalysis->aeroSymmetryXY) == 0) { | |||
1146 | fprintf(fp,"\tAESYMXY = %s\n","SYMMETRIC"); | |||
1147 | } else if(strcmp("ANTISYM",tacsInstance->feaProblem.feaAnalysis->aeroSymmetryXY) == 0) { | |||
1148 | fprintf(fp,"\tAESYMXY = %s\n","ANTISYMMETRIC"); | |||
1149 | } else if(strcmp("ASYM",tacsInstance->feaProblem.feaAnalysis->aeroSymmetryXY) == 0) { | |||
1150 | fprintf(fp,"\tAESYMXY = %s\n","ASYMMETRIC"); | |||
1151 | } else if(strcmp("SYMMETRIC",tacsInstance->feaProblem.feaAnalysis->aeroSymmetryXY) == 0) { | |||
1152 | fprintf(fp,"\tAESYMXY = %s\n","SYMMETRIC"); | |||
1153 | } else if(strcmp("ANTISYMMETRIC",tacsInstance->feaProblem.feaAnalysis->aeroSymmetryXY) == 0) { | |||
1154 | fprintf(fp,"\tAESYMXY = %s\n","ANTISYMMETRIC"); | |||
1155 | } else if(strcmp("ASYMMETRIC",tacsInstance->feaProblem.feaAnalysis->aeroSymmetryXY) == 0) { | |||
1156 | fprintf(fp,"\tAESYMXY = %s\n","ASYMMETRIC"); | |||
1157 | } else { | |||
1158 | printf("\t*** Warning *** aeroSymmetryXY Input %s to nastranAIM not understood!\n",tacsInstance->feaProblem.feaAnalysis->aeroSymmetryXY ); | |||
1159 | } | |||
1160 | } | |||
1161 | ||||
1162 | if (tacsInstance->feaProblem.feaAnalysis[i].aeroSymmetryXZ != NULL((void*)0)) { | |||
1163 | ||||
1164 | if(strcmp("SYM",tacsInstance->feaProblem.feaAnalysis->aeroSymmetryXZ) == 0) { | |||
1165 | fprintf(fp,"\tAESYMXZ = %s\n","SYMMETRIC"); | |||
1166 | } else if(strcmp("ANTISYM",tacsInstance->feaProblem.feaAnalysis->aeroSymmetryXZ) == 0) { | |||
1167 | fprintf(fp,"\tAESYMXZ = %s\n","ANTISYMMETRIC"); | |||
1168 | } else if(strcmp("ASYM",tacsInstance->feaProblem.feaAnalysis->aeroSymmetryXZ) == 0) { | |||
1169 | fprintf(fp,"\tAESYMXZ = %s\n","ASYMMETRIC"); | |||
1170 | } else if(strcmp("SYMMETRIC",tacsInstance->feaProblem.feaAnalysis->aeroSymmetryXZ) == 0) { | |||
1171 | fprintf(fp,"\tAESYMXZ = %s\n","SYMMETRIC"); | |||
1172 | } else if(strcmp("ANTISYMMETRIC",tacsInstance->feaProblem.feaAnalysis->aeroSymmetryXZ) == 0) { | |||
1173 | fprintf(fp,"\tAESYMXZ = %s\n","ANTISYMMETRIC"); | |||
1174 | } else if(strcmp("ASYMMETRIC",tacsInstance->feaProblem.feaAnalysis->aeroSymmetryXZ) == 0) { | |||
1175 | fprintf(fp,"\tAESYMXZ = %s\n","ASYMMETRIC"); | |||
1176 | } else { | |||
1177 | printf("\t*** Warning *** aeroSymmetryXZ Input %s to nastranAIM not understood!\n",tacsInstance->feaProblem.feaAnalysis->aeroSymmetryXZ ); | |||
1178 | } | |||
1179 | ||||
1180 | } | |||
1181 | } | |||
1182 | ||||
1183 | // Issue some warnings regarding loads if necessary | |||
1184 | if (tacsInstance->feaProblem.feaAnalysis[i].numLoad == 0 && tacsInstance->feaProblem.numLoad !=0) { | |||
1185 | printf("\tWarning: No loads specified for case %s, assuming " | |||
1186 | "all loads are applied!!!!\n", tacsInstance->feaProblem.feaAnalysis[i].name); | |||
1187 | } else if (tacsInstance->feaProblem.numLoad == 0) { | |||
1188 | printf("\tWarning: No loads specified for case %s!!!!\n", tacsInstance->feaProblem.feaAnalysis[i].name); | |||
1189 | } | |||
1190 | ||||
1191 | // Write loads for sub-case | |||
1192 | if (tacsInstance->feaProblem.numLoad
| |||
1193 | ||||
1194 | found = (int) false0; | |||
1195 | ||||
1196 | for (k = 0; k < tacsInstance->feaProblem.numLoad; k++) { | |||
1197 | ||||
1198 | if (tacsInstance->feaProblem.feaAnalysis[i].numLoad
| |||
1199 | ||||
1200 | for (j = 0; j < tacsInstance->feaProblem.feaAnalysis[i].numLoad; j++) { // See if the load is in the loadSet | |||
1201 | ||||
1202 | if (feaLoad[k].loadID == tacsInstance->feaProblem.feaAnalysis[i].loadSetID[j]) break; | |||
1203 | } | |||
1204 | ||||
1205 | if (j >= tacsInstance->feaProblem.feaAnalysis[i].numLoad) continue; // If it isn't in the loadSet move on | |||
1206 | } else { | |||
1207 | //pass | |||
1208 | } | |||
1209 | ||||
1210 | if (feaLoad[k].loadType == Thermal && numThermalLoad == 0) { | |||
| ||||
1211 | ||||
1212 | fprintf(fp, "\tTemperature = %d\n", feaLoad[k].loadID); | |||
1213 | numThermalLoad += 1; | |||
1214 | if (numThermalLoad > 1) { | |||
1215 | printf("More than 1 Thermal load found - nastranAIM does NOT currently doesn't support multiple thermal loads in a given case!\n"); | |||
1216 | } | |||
1217 | ||||
1218 | continue; | |||
1219 | } | |||
1220 | ||||
1221 | found = (int) true1; | |||
1222 | } | |||
1223 | ||||
1224 | if (found == (int) true1) { | |||
1225 | fprintf(fp, "\tLOAD = %d\n", tacsInstance->feaProblem.numLoad+i+1); | |||
1226 | } | |||
1227 | } | |||
1228 | ||||
1229 | //if (tacsInstance->feaProblem.feaAnalysis[i].analysisType == Optimization) { | |||
1230 | // Write objective function | |||
1231 | //fprintf(fp, "\tDESOBJ(%s) = %d\n", tacsInstance->feaProblem.feaAnalysis[i].objectiveMinMax, | |||
1232 | // tacsInstance->feaProblem.feaAnalysis[i].analysisID); | |||
1233 | // Write optimization constraints | |||
1234 | if (tacsInstance->feaProblem.feaAnalysis[i].numDesignConstraint != 0) { | |||
1235 | fprintf(fp, "\tDESSUB = %d\n", tacsInstance->feaProblem.numDesignConstraint+i+1); | |||
1236 | } | |||
1237 | //} | |||
1238 | ||||
1239 | // Write response spanning for sub-case | |||
1240 | if (tacsInstance->feaProblem.feaAnalysis[i].numDesignResponse != 0) { | |||
1241 | ||||
1242 | numSetID = tacsInstance->feaProblem.feaAnalysis[i].numDesignResponse; | |||
1243 | // setID = tacsInstance->feaProblem.feaAnalysis[i].designResponseSetID; | |||
1244 | setID = EG_alloc(numSetID * sizeof(int)); | |||
1245 | if (setID == NULL((void*)0)) { | |||
1246 | status = EGADS_MALLOC-4; | |||
1247 | goto cleanup; | |||
1248 | } | |||
1249 | ||||
1250 | for (j = 0; j < numSetID; j++) { | |||
1251 | tempID = tacsInstance->feaProblem.feaAnalysis[i].designResponseSetID[j]; | |||
1252 | setID[j] = tempID + 100000; | |||
1253 | } | |||
1254 | ||||
1255 | tempID = i+1; | |||
1256 | status = nastran_writeSetCard(fp, tempID, numSetID, setID); | |||
1257 | ||||
1258 | EG_free(setID); | |||
1259 | ||||
1260 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1260 , __func__, 0); goto cleanup; }; | |||
1261 | fprintf(fp, "\tDRSPAN = %d\n", tempID); | |||
1262 | } | |||
1263 | ||||
1264 | } | |||
1265 | ||||
1266 | //////////////// Bulk data //////////////// | |||
1267 | fprintf(fp, "\nBEGIN BULK\n"); | |||
1268 | fprintf(fp, "$---1---|---2---|---3---|---4---|---5---|---6---|---7---|---8---|---9---|---10--|\n"); | |||
1269 | //PRINT PARAM ENTRIES IN BULK DATA | |||
1270 | ||||
1271 | if (aimInputs[Parameter-1].nullVal == NotNull) { | |||
1272 | for (i = 0; i < aimInputs[Parameter-1].length; i++) { | |||
1273 | fprintf(fp, "PARAM, %s, %s\n", aimInputs[Parameter-1].vals.tuple[i].name, | |||
1274 | aimInputs[Parameter-1].vals.tuple[i].value); | |||
1275 | } | |||
1276 | } | |||
1277 | ||||
1278 | fprintf(fp, "PARAM, %s\n", "POST, -1\n"); // Output OP2 file | |||
1279 | ||||
1280 | // Write AEROS, AESTAT and AESURF cards | |||
1281 | if (strcasecmp(analysisType, "AeroelasticFlutter") == 0 || | |||
1282 | haveSubAeroelasticFlutter == (int) true1) { | |||
1283 | ||||
1284 | printf("\tWriting aero card\n"); | |||
1285 | status = nastran_writeAEROCard(fp, | |||
1286 | &tacsInstance->feaProblem.feaAeroRef, | |||
1287 | &tacsInstance->feaProblem.feaFileFormat); | |||
1288 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1288 , __func__, 0); goto cleanup; }; | |||
1289 | } | |||
1290 | ||||
1291 | // Write AEROS, AESTAT and AESURF cards | |||
1292 | if (strcasecmp(analysisType, "Aeroelastic") == 0 || | |||
1293 | strcasecmp(analysisType, "AeroelasticTrim") == 0 || | |||
1294 | haveSubAeroelasticTrim == (int) true1) { | |||
1295 | ||||
1296 | printf("\tWriting aeros card\n"); | |||
1297 | status = nastran_writeAEROSCard(fp, | |||
1298 | &tacsInstance->feaProblem.feaAeroRef, | |||
1299 | &tacsInstance->feaProblem.feaFileFormat); | |||
1300 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1300 , __func__, 0); goto cleanup; }; | |||
1301 | ||||
1302 | numAEStatSurf = 0; | |||
1303 | for (i = 0; i < tacsInstance->feaProblem.numAnalysis; i++) { | |||
1304 | ||||
1305 | if (tacsInstance->feaProblem.feaAnalysis[i].analysisType != AeroelasticTrim) continue; | |||
1306 | ||||
1307 | if (i == 0) printf("\tWriting aestat cards\n"); | |||
1308 | ||||
1309 | // Loop over rigid variables | |||
1310 | for (j = 0; j < tacsInstance->feaProblem.feaAnalysis[i].numRigidVariable; j++) { | |||
1311 | ||||
1312 | found = (int) false0; | |||
1313 | ||||
1314 | // Loop over previous rigid variables | |||
1315 | for (k = 0; k < i; k++) { | |||
1316 | for (l = 0; l < tacsInstance->feaProblem.feaAnalysis[k].numRigidVariable; l++) { | |||
1317 | ||||
1318 | // If current rigid variable was previous written - mark as found | |||
1319 | if (strcmp(tacsInstance->feaProblem.feaAnalysis[i].rigidVariable[j], | |||
1320 | tacsInstance->feaProblem.feaAnalysis[k].rigidVariable[l]) == 0) { | |||
1321 | found = (int) true1; | |||
1322 | break; | |||
1323 | } | |||
1324 | } | |||
1325 | } | |||
1326 | ||||
1327 | // If already found continue | |||
1328 | if (found == (int) true1) continue; | |||
1329 | ||||
1330 | // If not write out an aestat card | |||
1331 | numAEStatSurf += 1; | |||
1332 | ||||
1333 | fprintf(fp,"%-8s", "AESTAT"); | |||
1334 | ||||
1335 | tempString = convert_integerToString(numAEStatSurf, 7, 1); | |||
1336 | AIM_NOTNULL(tempString, aimInfo, status){ if (tempString == ((void*)0)) { status = -307; aim_status(aimInfo , status, "tacsAIM.c", 1336, __func__, 1, "%s == NULL!", "tempString" ); goto cleanup; } }; | |||
1337 | fprintf(fp, "%s%s", delimiter, tempString); | |||
1338 | AIM_FREE(tempString){ EG_free(tempString); tempString = ((void*)0); }; | |||
1339 | ||||
1340 | fprintf(fp, "%s%7s\n", delimiter, tacsInstance->feaProblem.feaAnalysis[i].rigidVariable[j]); | |||
1341 | } | |||
1342 | ||||
1343 | // Loop over rigid Constraints | |||
1344 | for (j = 0; j < tacsInstance->feaProblem.feaAnalysis[i].numRigidConstraint; j++) { | |||
1345 | ||||
1346 | found = (int) false0; | |||
1347 | ||||
1348 | // Loop over previous rigid constraints | |||
1349 | for (k = 0; k < i; k++) { | |||
1350 | for (l = 0; l < tacsInstance->feaProblem.feaAnalysis[k].numRigidConstraint; l++) { | |||
1351 | ||||
1352 | // If current rigid constraint was previous written - mark as found | |||
1353 | if (strcmp(tacsInstance->feaProblem.feaAnalysis[i].rigidConstraint[j], | |||
1354 | tacsInstance->feaProblem.feaAnalysis[k].rigidConstraint[l]) == 0) { | |||
1355 | found = (int) true1; | |||
1356 | break; | |||
1357 | } | |||
1358 | } | |||
1359 | } | |||
1360 | ||||
1361 | // If already found continue | |||
1362 | if (found == (int) true1) continue; | |||
1363 | ||||
1364 | // Make sure constraint isn't already in rigid variables too! | |||
1365 | for (k = 0; k < i; k++) { | |||
1366 | for (l = 0; l < tacsInstance->feaProblem.feaAnalysis[k].numRigidVariable; l++) { | |||
1367 | ||||
1368 | // If current rigid constraint was previous written - mark as found | |||
1369 | if (strcmp(tacsInstance->feaProblem.feaAnalysis[i].rigidConstraint[j], | |||
1370 | tacsInstance->feaProblem.feaAnalysis[k].rigidVariable[l]) == 0) { | |||
1371 | found = (int) true1; | |||
1372 | break; | |||
1373 | } | |||
1374 | } | |||
1375 | } | |||
1376 | ||||
1377 | // If already found continue | |||
1378 | if (found == (int) true1) continue; | |||
1379 | ||||
1380 | // If not write out an aestat card | |||
1381 | numAEStatSurf += 1; | |||
1382 | ||||
1383 | fprintf(fp,"%-8s", "AESTAT"); | |||
1384 | ||||
1385 | tempString = convert_integerToString(numAEStatSurf, 7, 1); | |||
1386 | AIM_NOTNULL(tempString, aimInfo, status){ if (tempString == ((void*)0)) { status = -307; aim_status(aimInfo , status, "tacsAIM.c", 1386, __func__, 1, "%s == NULL!", "tempString" ); goto cleanup; } }; | |||
1387 | fprintf(fp, "%s%s", delimiter, tempString); | |||
1388 | AIM_FREE(tempString){ EG_free(tempString); tempString = ((void*)0); }; | |||
1389 | ||||
1390 | fprintf(fp, "%s%7s\n", delimiter, tacsInstance->feaProblem.feaAnalysis[i].rigidConstraint[j]); | |||
1391 | } | |||
1392 | } | |||
1393 | ||||
1394 | fprintf(fp,"\n"); | |||
1395 | } | |||
1396 | ||||
1397 | // Analysis Cards - Eigenvalue and design objective included, as well as combined load, constraint, and design constraints | |||
1398 | for (i = 0; i < tacsInstance->feaProblem.numAnalysis; i++) { | |||
1399 | ||||
1400 | if (i == 0) printf("\tWriting analysis cards\n"); | |||
1401 | ||||
1402 | status = nastran_writeAnalysisCard(fp, | |||
1403 | &tacsInstance->feaProblem.feaAnalysis[i], | |||
1404 | &tacsInstance->feaProblem.feaFileFormat); | |||
1405 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1405 , __func__, 0); goto cleanup; }; | |||
1406 | ||||
1407 | if (tacsInstance->feaProblem.feaAnalysis[i].numLoad != 0) { | |||
1408 | ||||
1409 | // Create a temporary list of load IDs | |||
1410 | tempIntegerArray = (int *) EG_alloc(tacsInstance->feaProblem.feaAnalysis[i].numLoad*sizeof(int)); | |||
1411 | if (tempIntegerArray == NULL((void*)0)) { | |||
1412 | status = EGADS_MALLOC-4; | |||
1413 | goto cleanup; | |||
1414 | } | |||
1415 | ||||
1416 | k = 0; | |||
1417 | for (j = 0; j < tacsInstance->feaProblem.feaAnalysis[i].numLoad; j++) { | |||
1418 | for (l = 0; l < tacsInstance->feaProblem.numLoad; l++) { | |||
1419 | if (tacsInstance->feaProblem.feaAnalysis[i].loadSetID[j] == feaLoad[l].loadID) break; | |||
1420 | } | |||
1421 | if (feaLoad[l].loadType == Thermal) continue; | |||
1422 | tempIntegerArray[j] = feaLoad[l].loadID; | |||
1423 | k += 1; | |||
1424 | } | |||
1425 | ||||
1426 | tempIntegerArray = (int *) EG_reall(tempIntegerArray, k*sizeof(int)); | |||
1427 | if (tempIntegerArray == NULL((void*)0)) { | |||
1428 | status = EGADS_MALLOC-4; | |||
1429 | goto cleanup; | |||
1430 | } | |||
1431 | ||||
1432 | // Write combined load card | |||
1433 | printf("\tWriting load ADD cards\n"); | |||
1434 | status = nastran_writeLoadADDCard(fp, | |||
1435 | tacsInstance->feaProblem.numLoad+i+1, | |||
1436 | k, | |||
1437 | tempIntegerArray, | |||
1438 | feaLoad, | |||
1439 | &tacsInstance->feaProblem.feaFileFormat); | |||
1440 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1440 , __func__, 0); goto cleanup; }; | |||
1441 | ||||
1442 | // Free temporary load ID list | |||
1443 | EG_free(tempIntegerArray); | |||
1444 | tempIntegerArray = NULL((void*)0); | |||
1445 | ||||
1446 | } else { // If no loads for an individual analysis are specified assume that all loads should be applied | |||
1447 | ||||
1448 | if (tacsInstance->feaProblem.numLoad != 0) { | |||
1449 | ||||
1450 | // Create a temporary list of load IDs | |||
1451 | tempIntegerArray = (int *) EG_alloc(tacsInstance->feaProblem.numLoad*sizeof(int)); | |||
1452 | if (tempIntegerArray == NULL((void*)0)) { | |||
1453 | status = EGADS_MALLOC-4; | |||
1454 | goto cleanup; | |||
1455 | } | |||
1456 | ||||
1457 | k = 0; | |||
1458 | for (j = 0; j < tacsInstance->feaProblem.numLoad; j++) { | |||
1459 | if (feaLoad[j].loadType == Gravity) continue; | |||
1460 | tempIntegerArray[j] = feaLoad[j].loadID; | |||
1461 | k += 1; | |||
1462 | } | |||
1463 | ||||
1464 | AIM_ERROR(aimInfo, "Writing load ADD cards is not properly implemented!"){ aim_message(aimInfo, CERROR, 0 , "tacsAIM.c", 1464, __func__ , "Writing load ADD cards is not properly implemented!"); }; | |||
1465 | status = CAPS_NOTIMPLEMENT-334; | |||
1466 | goto cleanup; | |||
1467 | ||||
1468 | #ifdef FIX_tempIntegerArray_INIT | |||
1469 | // tempIntegerArray needs to be initialized!!! | |||
1470 | ||||
1471 | tempIntegerArray = (int *) EG_reall(tempIntegerArray, k*sizeof(int)); | |||
1472 | if (tempIntegerArray == NULL((void*)0)) { | |||
1473 | status = EGADS_MALLOC-4; | |||
1474 | goto cleanup; | |||
1475 | } | |||
1476 | ||||
1477 | //TOOO: eliminate load add card? | |||
1478 | // Write combined load card | |||
1479 | printf("\tWriting load ADD cards\n"); | |||
1480 | status = nastran_writeLoadADDCard(fp, | |||
1481 | tacsInstance->feaProblem.numLoad+i+1, | |||
1482 | k, | |||
1483 | tempIntegerArray, | |||
1484 | feaLoad, | |||
1485 | &tacsInstance->feaProblem.feaFileFormat); | |||
1486 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1486 , __func__, 0); goto cleanup; }; | |||
1487 | ||||
1488 | // Free temporary load ID list | |||
1489 | EG_free(tempIntegerArray); | |||
1490 | tempIntegerArray = NULL((void*)0); | |||
1491 | #endif | |||
1492 | } | |||
1493 | ||||
1494 | } | |||
1495 | ||||
1496 | if (tacsInstance->feaProblem.feaAnalysis[i].numConstraint != 0) { | |||
1497 | // Write combined constraint card | |||
1498 | printf("\tWriting constraint ADD cards\n"); | |||
1499 | status = nastran_writeConstraintADDCard(fp, | |||
1500 | tacsInstance->feaProblem.numConstraint+i+1, | |||
1501 | tacsInstance->feaProblem.feaAnalysis[i].numConstraint, | |||
1502 | tacsInstance->feaProblem.feaAnalysis[i].constraintSetID, | |||
1503 | &tacsInstance->feaProblem.feaFileFormat); | |||
1504 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1504 , __func__, 0); goto cleanup; }; | |||
1505 | ||||
1506 | } else { // If no constraints for an individual analysis are specified assume that all constraints should be applied | |||
1507 | ||||
1508 | if (tacsInstance->feaProblem.numConstraint != 0) { | |||
1509 | ||||
1510 | printf("\tWriting combined constraint cards\n"); | |||
1511 | ||||
1512 | // Create a temporary list of constraint IDs | |||
1513 | AIM_ALLOC(tempIntegerArray, tacsInstance->feaProblem.numConstraint, int, aimInfo, status){ if (tempIntegerArray != ((void*)0)) { status = -4; aim_status (aimInfo, status, "tacsAIM.c", 1513, __func__, 1, "AIM_ALLOC: %s != NULL" , "tempIntegerArray"); goto cleanup; } size_t memorysize = tacsInstance ->feaProblem.numConstraint; tempIntegerArray = (int *) EG_alloc (memorysize*sizeof(int)); if (tempIntegerArray == ((void*)0)) { status = -4; aim_status(aimInfo, status, "tacsAIM.c", 1513 , __func__, 3, "AIM_ALLOC: %s size %zu type %s", "tempIntegerArray" , memorysize, "int"); goto cleanup; } }; | |||
1514 | ||||
1515 | for (j = 0; j < tacsInstance->feaProblem.numConstraint; j++) { | |||
1516 | tempIntegerArray[j] = tacsInstance->feaProblem.feaConstraint[j].constraintID; | |||
1517 | } | |||
1518 | ||||
1519 | // Write combined constraint card | |||
1520 | status = nastran_writeConstraintADDCard(fp, | |||
1521 | tacsInstance->feaProblem.numConstraint+i+1, | |||
1522 | tacsInstance->feaProblem.numConstraint, | |||
1523 | tempIntegerArray, | |||
1524 | &tacsInstance->feaProblem.feaFileFormat); | |||
1525 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1525 , __func__, 0); goto cleanup; }; | |||
1526 | ||||
1527 | // Free temporary constraint ID list | |||
1528 | AIM_FREE(tempIntegerArray){ EG_free(tempIntegerArray); tempIntegerArray = ((void*)0); }; | |||
1529 | } | |||
1530 | } | |||
1531 | ||||
1532 | if (tacsInstance->feaProblem.feaAnalysis[i].numDesignConstraint != 0) { | |||
1533 | ||||
1534 | // Write combined design constraint card | |||
1535 | printf("\tWriting design constraint ADD cards\n"); | |||
1536 | status = nastran_writeDesignConstraintADDCard(fp, | |||
1537 | tacsInstance->feaProblem.numDesignConstraint+i+1, | |||
1538 | tacsInstance->feaProblem.feaAnalysis[i].numDesignConstraint, | |||
1539 | tacsInstance->feaProblem.feaAnalysis[i].designConstraintSetID, | |||
1540 | &tacsInstance->feaProblem.feaFileFormat); | |||
1541 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1541 , __func__, 0); goto cleanup; }; | |||
1542 | ||||
1543 | } else { // If no design constraints for an individual analysis are specified assume that all design constraints should be applied | |||
1544 | ||||
1545 | if (tacsInstance->feaProblem.numDesignConstraint != 0) { | |||
1546 | ||||
1547 | // Create a temporary list of design constraint IDs | |||
1548 | AIM_ALLOC(tempIntegerArray, tacsInstance->feaProblem.numDesignConstraint, int, aimInfo, status){ if (tempIntegerArray != ((void*)0)) { status = -4; aim_status (aimInfo, status, "tacsAIM.c", 1548, __func__, 1, "AIM_ALLOC: %s != NULL" , "tempIntegerArray"); goto cleanup; } size_t memorysize = tacsInstance ->feaProblem.numDesignConstraint; tempIntegerArray = (int * ) EG_alloc(memorysize*sizeof(int)); if (tempIntegerArray == ( (void*)0)) { status = -4; aim_status(aimInfo, status, "tacsAIM.c" , 1548, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "tempIntegerArray" , memorysize, "int"); goto cleanup; } }; | |||
1549 | ||||
1550 | for (j = 0; j < tacsInstance->feaProblem.numDesignConstraint; j++) { | |||
1551 | tempIntegerArray[j] = tacsInstance->feaProblem.feaDesignConstraint[j].designConstraintID; | |||
1552 | } | |||
1553 | ||||
1554 | // Write combined design constraint card | |||
1555 | printf("\tWriting design constraint ADD cards\n"); | |||
1556 | status = nastran_writeDesignConstraintADDCard(fp, | |||
1557 | tacsInstance->feaProblem.numDesignConstraint+i+1, | |||
1558 | tacsInstance->feaProblem.numDesignConstraint, | |||
1559 | tempIntegerArray, | |||
1560 | &tacsInstance->feaProblem.feaFileFormat); | |||
1561 | // Free temporary design constraint ID list | |||
1562 | if (tempIntegerArray != NULL((void*)0)) EG_free(tempIntegerArray); | |||
1563 | tempIntegerArray = NULL((void*)0); | |||
1564 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1564 , __func__, 0); goto cleanup; }; | |||
1565 | } | |||
1566 | ||||
1567 | } | |||
1568 | } | |||
1569 | ||||
1570 | ||||
1571 | // Loads | |||
1572 | for (i = 0; i < tacsInstance->feaProblem.numLoad; i++) { | |||
1573 | ||||
1574 | if (i == 0) printf("\tWriting load cards\n"); | |||
1575 | ||||
1576 | status = nastran_writeLoadCard(fp, | |||
1577 | &feaLoad[i], | |||
1578 | &tacsInstance->feaProblem.feaFileFormat); | |||
1579 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1579 , __func__, 0); goto cleanup; }; | |||
1580 | } | |||
1581 | ||||
1582 | // Constraints | |||
1583 | for (i = 0; i < tacsInstance->feaProblem.numConstraint; i++) { | |||
1584 | ||||
1585 | if (i == 0) printf("\tWriting constraint cards\n"); | |||
1586 | ||||
1587 | status = nastran_writeConstraintCard(fp, | |||
1588 | &tacsInstance->feaProblem.feaConstraint[i], | |||
1589 | &tacsInstance->feaProblem.feaFileFormat); | |||
1590 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1590 , __func__, 0); goto cleanup; }; | |||
1591 | } | |||
1592 | ||||
1593 | // Supports | |||
1594 | for (i = 0; i < tacsInstance->feaProblem.numSupport; i++) { | |||
1595 | ||||
1596 | if (i == 0) printf("\tWriting support cards\n"); | |||
1597 | j = (int) true1; | |||
1598 | status = nastran_writeSupportCard(fp, | |||
1599 | &tacsInstance->feaProblem.feaSupport[i], | |||
1600 | &tacsInstance->feaProblem.feaFileFormat, | |||
1601 | &j); | |||
1602 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1602 , __func__, 0); goto cleanup; }; | |||
1603 | } | |||
1604 | ||||
1605 | ||||
1606 | // Materials | |||
1607 | for (i = 0; i < tacsInstance->feaProblem.numMaterial; i++) { | |||
1608 | ||||
1609 | if (i == 0) printf("\tWriting material cards\n"); | |||
1610 | ||||
1611 | status = nastran_writeMaterialCard(fp, | |||
1612 | &tacsInstance->feaProblem.feaMaterial[i], | |||
1613 | &tacsInstance->feaProblem.feaFileFormat); | |||
1614 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1614 , __func__, 0); goto cleanup; }; | |||
1615 | } | |||
1616 | ||||
1617 | // Properties | |||
1618 | for (i = 0; i < tacsInstance->feaProblem.numProperty; i++) { | |||
1619 | ||||
1620 | if (i == 0) printf("\tWriting property cards\n"); | |||
1621 | ||||
1622 | status = nastran_writePropertyCard(fp, | |||
1623 | &tacsInstance->feaProblem.feaProperty[i], | |||
1624 | &tacsInstance->feaProblem.feaFileFormat); | |||
1625 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1625 , __func__, 0); goto cleanup; }; | |||
1626 | } | |||
1627 | ||||
1628 | // Coordinate systems | |||
1629 | // printf("DEBUG: Number of coord systems: %d\n", tacsInstance->feaProblem.numCoordSystem); | |||
1630 | for (i = 0; i < tacsInstance->feaProblem.numCoordSystem; i++) { | |||
1631 | ||||
1632 | if (i == 0) printf("\tWriting coordinate system cards\n"); | |||
1633 | ||||
1634 | status = nastran_writeCoordinateSystemCard(fp, | |||
1635 | &tacsInstance->feaProblem.feaCoordSystem[i], | |||
1636 | &tacsInstance->feaProblem.feaFileFormat); | |||
1637 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1637 , __func__, 0); goto cleanup; }; | |||
1638 | } | |||
1639 | ||||
1640 | // Optimization - design variables | |||
1641 | for( i = 0; i < tacsInstance->feaProblem.numDesignVariable; i++) { | |||
1642 | ||||
1643 | if (i == 0) printf("\tWriting design variable cards\n"); | |||
1644 | ||||
1645 | status = nastran_writeDesignVariableCard(fp, | |||
1646 | &tacsInstance->feaProblem.feaDesignVariable[i], | |||
1647 | &tacsInstance->feaProblem.feaFileFormat); | |||
1648 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1648 , __func__, 0); goto cleanup; }; | |||
1649 | } | |||
1650 | ||||
1651 | // Optimization - design variable relations | |||
1652 | for( i = 0; i < tacsInstance->feaProblem.numDesignVariableRelation; i++) { | |||
1653 | ||||
1654 | if (i == 0) printf("\tWriting design variable relation cards\n"); | |||
1655 | ||||
1656 | status = nastran_writeDesignVariableRelationCard(aimInfo, | |||
1657 | fp, | |||
1658 | &tacsInstance->feaProblem.feaDesignVariableRelation[i], | |||
1659 | &tacsInstance->feaProblem, | |||
1660 | &tacsInstance->feaProblem.feaFileFormat); | |||
1661 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1661 , __func__, 0); goto cleanup; }; | |||
1662 | } | |||
1663 | ||||
1664 | // Optimization - design constraints | |||
1665 | for( i = 0; i < tacsInstance->feaProblem.numDesignConstraint; i++) { | |||
1666 | ||||
1667 | if (i == 0) printf("\tWriting design constraints and responses cards\n"); | |||
1668 | ||||
1669 | status = nastran_writeDesignConstraintCard(fp, | |||
1670 | &tacsInstance->feaProblem.feaDesignConstraint[i], | |||
1671 | &tacsInstance->feaProblem.feaFileFormat); | |||
1672 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1672 , __func__, 0); goto cleanup; }; | |||
1673 | } | |||
1674 | ||||
1675 | // Optimization - design equations | |||
1676 | for( i = 0; i < tacsInstance->feaProblem.numEquation; i++) { | |||
1677 | ||||
1678 | if (i == 0) printf("\tWriting design equation cards\n"); | |||
1679 | ||||
1680 | status = nastran_writeDesignEquationCard(fp, | |||
1681 | &tacsInstance->feaProblem.feaEquation[i], | |||
1682 | &tacsInstance->feaProblem.feaFileFormat); | |||
1683 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1683 , __func__, 0); goto cleanup; }; | |||
1684 | } | |||
1685 | ||||
1686 | // Optimization - design table constants | |||
1687 | if (tacsInstance->feaProblem.feaDesignTable.numConstant > 0) | |||
1688 | printf("\tWriting design table card\n"); | |||
1689 | status = nastran_writeDesignTableCard(fp, | |||
1690 | &tacsInstance->feaProblem.feaDesignTable, | |||
1691 | &tacsInstance->feaProblem.feaFileFormat); | |||
1692 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1692 , __func__, 0); goto cleanup; }; | |||
1693 | ||||
1694 | // Optimization - design optimization parameters | |||
1695 | if (tacsInstance->feaProblem.feaDesignOptParam.numParam > 0) | |||
1696 | printf("\tWriting design optimization parameters card\n"); | |||
1697 | status = nastran_writeDesignOptParamCard(fp, | |||
1698 | &tacsInstance->feaProblem.feaDesignOptParam, | |||
1699 | &tacsInstance->feaProblem.feaFileFormat); | |||
1700 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1700 , __func__, 0); goto cleanup; }; | |||
1701 | ||||
1702 | // Optimization - design responses | |||
1703 | for( i = 0; i < tacsInstance->feaProblem.numDesignResponse; i++) { | |||
1704 | ||||
1705 | if (i == 0) printf("\tWriting design response cards\n"); | |||
1706 | ||||
1707 | status = nastran_writeDesignResponseCard(fp, | |||
1708 | &tacsInstance->feaProblem.feaDesignResponse[i], | |||
1709 | &tacsInstance->feaProblem.feaFileFormat); | |||
1710 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1710 , __func__, 0); goto cleanup; }; | |||
1711 | } | |||
1712 | ||||
1713 | // Optimization - design equation responses | |||
1714 | for( i = 0; i < tacsInstance->feaProblem.numEquationResponse; i++) { | |||
1715 | ||||
1716 | if (i == 0) printf("\tWriting design equation response cards\n"); | |||
1717 | ||||
1718 | status = nastran_writeDesignEquationResponseCard(fp, | |||
1719 | &tacsInstance->feaProblem.feaEquationResponse[i], | |||
1720 | &tacsInstance->feaProblem, | |||
1721 | &tacsInstance->feaProblem.feaFileFormat); | |||
1722 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1722 , __func__, 0); goto cleanup; }; | |||
1723 | } | |||
1724 | ||||
1725 | // Include mesh file | |||
1726 | fprintf(fp,"\nINCLUDE \'%s.bdf\'\n\n", tacsInstance->projectName); | |||
1727 | ||||
1728 | // End bulk data | |||
1729 | fprintf(fp,"ENDDATA\n"); | |||
1730 | ||||
1731 | fclose(fp); | |||
1732 | fp = NULL((void*)0); | |||
1733 | ||||
1734 | status = CAPS_SUCCESS0; | |||
1735 | ||||
1736 | cleanup: | |||
1737 | if (status != CAPS_SUCCESS0) | |||
1738 | printf("\tPremature exit in tacsAIM preAnalysis, status = %d\n", | |||
1739 | status); | |||
1740 | ||||
1741 | for (i = 0; i < tacsInstance->feaProblem.numLoad; i++) { | |||
1742 | destroy_feaLoadStruct(&feaLoad[i]); | |||
1743 | } | |||
1744 | AIM_FREE(feaLoad){ EG_free(feaLoad); feaLoad = ((void*)0); }; | |||
1745 | ||||
1746 | if (tempIntegerArray != NULL((void*)0)) EG_free(tempIntegerArray); | |||
1747 | ||||
1748 | if (fp != NULL((void*)0)) fclose(fp); | |||
1749 | ||||
1750 | return status; | |||
1751 | } | |||
1752 | ||||
1753 | ||||
1754 | /* no longer optional and needed for restart */ | |||
1755 | int aimPostAnalysis(void *instStore, void *aimInfo, | |||
1756 | /*@unused@*/ int restart, capsValue *inputs) | |||
1757 | { | |||
1758 | int status = CAPS_SUCCESS0; // Function return status | |||
1759 | ||||
1760 | int i, j, k, idv, irow, icol, ibody; // Indexing | |||
1761 | int index, nGeomIn=0; | |||
1762 | ||||
1763 | char tmp[128]; | |||
1764 | int numFunctional=0; | |||
1765 | int **functional_map=NULL((void*)0); | |||
1766 | double **functional_xyz=NULL((void*)0); | |||
1767 | double functional_dvar; | |||
1768 | ||||
1769 | int numNode = 0, *numPoint=NULL((void*)0), *surf2tess=NULL((void*)0); | |||
1770 | ||||
1771 | const char *name; | |||
1772 | char **names=NULL((void*)0); | |||
1773 | double **dxyz = NULL((void*)0); | |||
1774 | ||||
1775 | FILE *fp=NULL((void*)0); | |||
1776 | capsValue *values=NULL((void*)0), *geomInVal; | |||
1777 | aimStorage *tacsInstance; | |||
1778 | tacsInstance = (aimStorage*)instStore; | |||
1779 | AIM_NOTNULL(inputs, aimInfo, status){ if (inputs == ((void*)0)) { status = -307; aim_status(aimInfo , status, "tacsAIM.c", 1779, __func__, 1, "%s == NULL!", "inputs" ); goto cleanup; } }; | |||
1780 | ||||
1781 | if (inputs[inDesign_Variable-1].nullVal == NotNull) { | |||
1782 | ||||
1783 | /* check for GeometryIn variables*/ | |||
1784 | nGeomIn = 0; | |||
1785 | for (i = 0; i < tacsInstance->feaProblem.numDesignVariable; i++) { | |||
1786 | ||||
1787 | name = tacsInstance->feaProblem.feaDesignVariable[i].name; | |||
1788 | ||||
1789 | // Loop over the geometry in values and compute sensitivities for all bodies | |||
1790 | index = aim_getIndex(aimInfo, name, GEOMETRYIN); | |||
1791 | if (index == CAPS_NOTFOUND-303){ | |||
1792 | continue; | |||
1793 | } | |||
1794 | if (index < CAPS_SUCCESS0 ) { | |||
1795 | status = index; | |||
1796 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1796 , __func__, 0); goto cleanup; }; | |||
1797 | } | |||
1798 | ||||
1799 | if(aim_getGeomInType(aimInfo, index) != 0) { | |||
1800 | AIM_ERROR(aimInfo, "GeometryIn value %s is a configuration parameter and not a valid design parameter - can't get sensitivity\n",{ aim_message(aimInfo, CERROR, 0 , "tacsAIM.c", 1801, __func__ , "GeometryIn value %s is a configuration parameter and not a valid design parameter - can't get sensitivity\n" , name); } | |||
1801 | name){ aim_message(aimInfo, CERROR, 0 , "tacsAIM.c", 1801, __func__ , "GeometryIn value %s is a configuration parameter and not a valid design parameter - can't get sensitivity\n" , name); }; | |||
1802 | status = CAPS_BADVALUE-311; | |||
1803 | goto cleanup; | |||
1804 | } | |||
1805 | ||||
1806 | nGeomIn++; | |||
1807 | } | |||
1808 | ||||
1809 | // No geometry sensitivties, so don't look for .sens file | |||
1810 | if (nGeomIn == 0) { | |||
1811 | status = CAPS_SUCCESS0; | |||
1812 | goto cleanup; | |||
1813 | } | |||
1814 | ||||
1815 | numNode = 0; | |||
1816 | for (ibody = 0; ibody < tacsInstance->numMesh; ibody++) { | |||
1817 | numNode += tacsInstance->feaMesh[ibody].numNode; | |||
1818 | } | |||
1819 | ||||
1820 | AIM_ALLOC(surf2tess, 2*numNode, int, aimInfo, status){ if (surf2tess != ((void*)0)) { status = -4; aim_status(aimInfo , status, "tacsAIM.c", 1820, __func__, 1, "AIM_ALLOC: %s != NULL" , "surf2tess"); goto cleanup; } size_t memorysize = 2*numNode ; surf2tess = (int *) EG_alloc(memorysize*sizeof(int)); if (surf2tess == ((void*)0)) { status = -4; aim_status(aimInfo, status, "tacsAIM.c" , 1820, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "surf2tess" , memorysize, "int"); goto cleanup; } }; | |||
1821 | for (i = 0; i < 2*numNode; i++) surf2tess[i] = 0; | |||
1822 | ||||
1823 | numNode = 0; | |||
1824 | for (ibody = 0; ibody < tacsInstance->numMesh; ibody++) { | |||
1825 | for (i = 0; i < tacsInstance->feaMesh[ibody].numNode; i++) { | |||
1826 | surf2tess[2*(numNode+i)+0] = ibody; | |||
1827 | surf2tess[2*(numNode+i)+1] = i; | |||
1828 | } | |||
1829 | numNode += tacsInstance->feaMesh[ibody].numNode; | |||
1830 | } | |||
1831 | ||||
1832 | // Read <Proj_Name>.sens | |||
1833 | snprintf(tmp, 128, "%s%s", tacsInstance->projectName, ".sens"); | |||
1834 | fp = aim_fopen(aimInfo, tmp, "r"); | |||
1835 | if (fp == NULL((void*)0)) { | |||
1836 | AIM_ERROR(aimInfo, "Unable to open: %s", tmp){ aim_message(aimInfo, CERROR, 0 , "tacsAIM.c", 1836, __func__ , "Unable to open: %s", tmp); }; | |||
1837 | status = CAPS_IOERR-332; | |||
1838 | goto cleanup; | |||
1839 | } | |||
1840 | ||||
1841 | // Number of nodes and functinoals in the file | |||
1842 | status = fscanf(fp, "%d", &numFunctional); | |||
1843 | if (status == EOF(-1) || status != 1) { | |||
1844 | AIM_ERROR(aimInfo, "Failed to read sens file number of functionals"){ aim_message(aimInfo, CERROR, 0 , "tacsAIM.c", 1844, __func__ , "Failed to read sens file number of functionals"); }; | |||
1845 | status = CAPS_IOERR-332; goto cleanup; | |||
1846 | } | |||
1847 | ||||
1848 | AIM_ALLOC(numPoint, numFunctional, int, aimInfo, status){ if (numPoint != ((void*)0)) { status = -4; aim_status(aimInfo , status, "tacsAIM.c", 1848, __func__, 1, "AIM_ALLOC: %s != NULL" , "numPoint"); goto cleanup; } size_t memorysize = numFunctional ; numPoint = (int *) EG_alloc(memorysize*sizeof(int)); if (numPoint == ((void*)0)) { status = -4; aim_status(aimInfo, status, "tacsAIM.c" , 1848, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "numPoint" , memorysize, "int"); goto cleanup; } }; | |||
1849 | for (i = 0; i < numFunctional; i++) numPoint[i] = 0; | |||
1850 | ||||
1851 | AIM_ALLOC(functional_map, numFunctional, int*, aimInfo, status){ if (functional_map != ((void*)0)) { status = -4; aim_status (aimInfo, status, "tacsAIM.c", 1851, __func__, 1, "AIM_ALLOC: %s != NULL" , "functional_map"); goto cleanup; } size_t memorysize = numFunctional ; functional_map = (int* *) EG_alloc(memorysize*sizeof(int*)) ; if (functional_map == ((void*)0)) { status = -4; aim_status (aimInfo, status, "tacsAIM.c", 1851, __func__, 3, "AIM_ALLOC: %s size %zu type %s" , "functional_map", memorysize, "int*"); goto cleanup; } }; | |||
1852 | for (i = 0; i < numFunctional; i++) functional_map[i] = NULL((void*)0); | |||
1853 | ||||
1854 | AIM_ALLOC(functional_xyz, numFunctional, double*, aimInfo, status){ if (functional_xyz != ((void*)0)) { status = -4; aim_status (aimInfo, status, "tacsAIM.c", 1854, __func__, 1, "AIM_ALLOC: %s != NULL" , "functional_xyz"); goto cleanup; } size_t memorysize = numFunctional ; functional_xyz = (double* *) EG_alloc(memorysize*sizeof(double *)); if (functional_xyz == ((void*)0)) { status = -4; aim_status (aimInfo, status, "tacsAIM.c", 1854, __func__, 3, "AIM_ALLOC: %s size %zu type %s" , "functional_xyz", memorysize, "double*"); goto cleanup; } }; | |||
1855 | for (i = 0; i < numFunctional; i++) functional_xyz[i] = NULL((void*)0); | |||
1856 | ||||
1857 | AIM_ALLOC(names, numFunctional, char*, aimInfo, status){ if (names != ((void*)0)) { status = -4; aim_status(aimInfo, status, "tacsAIM.c", 1857, __func__, 1, "AIM_ALLOC: %s != NULL" , "names"); goto cleanup; } size_t memorysize = numFunctional ; names = (char* *) EG_alloc(memorysize*sizeof(char*)); if (names == ((void*)0)) { status = -4; aim_status(aimInfo, status, "tacsAIM.c" , 1857, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "names" , memorysize, "char*"); goto cleanup; } }; | |||
1858 | for (i = 0; i < numFunctional; i++) names[i] = NULL((void*)0); | |||
1859 | ||||
1860 | AIM_ALLOC(values, numFunctional, capsValue, aimInfo, status){ if (values != ((void*)0)) { status = -4; aim_status(aimInfo , status, "tacsAIM.c", 1860, __func__, 1, "AIM_ALLOC: %s != NULL" , "values"); goto cleanup; } size_t memorysize = numFunctional ; values = (capsValue *) EG_alloc(memorysize*sizeof(capsValue )); if (values == ((void*)0)) { status = -4; aim_status(aimInfo , status, "tacsAIM.c", 1860, __func__, 3, "AIM_ALLOC: %s size %zu type %s" , "values", memorysize, "capsValue"); goto cleanup; } }; | |||
1861 | for (i = 0; i < numFunctional; i++) aim_initValue(&values[i]); | |||
1862 | ||||
1863 | for (i = 0; i < numFunctional; i++) { | |||
1864 | values[i].type = DoubleDeriv; | |||
1865 | ||||
1866 | /* allocate derivatives */ | |||
1867 | AIM_ALLOC(values[i].derivs, tacsInstance->feaProblem.numDesignVariable, capsDeriv, aimInfo, status){ if (values[i].derivs != ((void*)0)) { status = -4; aim_status (aimInfo, status, "tacsAIM.c", 1867, __func__, 1, "AIM_ALLOC: %s != NULL" , "values[i].derivs"); goto cleanup; } size_t memorysize = tacsInstance ->feaProblem.numDesignVariable; values[i].derivs = (capsDeriv *) EG_alloc(memorysize*sizeof(capsDeriv)); if (values[i].derivs == ((void*)0)) { status = -4; aim_status(aimInfo, status, "tacsAIM.c" , 1867, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "values[i].derivs" , memorysize, "capsDeriv"); goto cleanup; } }; | |||
1868 | for (idv = 0; idv < tacsInstance->feaProblem.numDesignVariable; idv++) { | |||
1869 | values[i].derivs[idv].name = NULL((void*)0); | |||
1870 | values[i].derivs[idv].deriv = NULL((void*)0); | |||
1871 | values[i].derivs[idv].len_wrt = 0; | |||
1872 | } | |||
1873 | values[i].nderiv = tacsInstance->feaProblem.numDesignVariable; | |||
1874 | } | |||
1875 | ||||
1876 | // Read in Functional name, value, numPoint, and dFunctinoal/dxyz | |||
1877 | for (i = 0; i < numFunctional; i++) { | |||
1878 | ||||
1879 | status = fscanf(fp, "%s", tmp); | |||
1880 | if (status == EOF(-1)) { | |||
1881 | AIM_ERROR(aimInfo, "Failed to read sens file functional name"){ aim_message(aimInfo, CERROR, 0 , "tacsAIM.c", 1881, __func__ , "Failed to read sens file functional name"); }; | |||
1882 | status = CAPS_IOERR-332; goto cleanup; | |||
1883 | } | |||
1884 | ||||
1885 | AIM_STRDUP(names[i], tmp, aimInfo, status){ if (names[i] != ((void*)0)) { status = -4; aim_status(aimInfo , status, "tacsAIM.c", 1885, __func__, 1, "AIM_STRDUP: %s != NULL!" , "names[i]"); goto cleanup; } names[i] = EG_strdup(tmp); if ( names[i] == ((void*)0)) { status = -4; aim_status(aimInfo, status , "tacsAIM.c", 1885, __func__, 2, "AIM_STRDUP: %s %s", "names[i]" , tmp); goto cleanup; } }; | |||
1886 | ||||
1887 | status = fscanf(fp, "%lf", &values[i].vals.real); | |||
1888 | if (status == EOF(-1) || status != 1) { | |||
1889 | AIM_ERROR(aimInfo, "Failed to read sens file functional value"){ aim_message(aimInfo, CERROR, 0 , "tacsAIM.c", 1889, __func__ , "Failed to read sens file functional value"); }; | |||
1890 | status = CAPS_IOERR-332; goto cleanup; | |||
1891 | } | |||
1892 | ||||
1893 | status = fscanf(fp, "%d", &numPoint[i]); | |||
1894 | if (status == EOF(-1) || status != 1) { | |||
1895 | AIM_ERROR(aimInfo, "Failed to read sens file number of points"){ aim_message(aimInfo, CERROR, 0 , "tacsAIM.c", 1895, __func__ , "Failed to read sens file number of points"); }; | |||
1896 | status = CAPS_IOERR-332; goto cleanup; | |||
1897 | } | |||
1898 | ||||
1899 | AIM_ALLOC(functional_map[i], numPoint[i], int , aimInfo, status){ if (functional_map[i] != ((void*)0)) { status = -4; aim_status (aimInfo, status, "tacsAIM.c", 1899, __func__, 1, "AIM_ALLOC: %s != NULL" , "functional_map[i]"); goto cleanup; } size_t memorysize = numPoint [i]; functional_map[i] = (int *) EG_alloc(memorysize*sizeof(int )); if (functional_map[i] == ((void*)0)) { status = -4; aim_status (aimInfo, status, "tacsAIM.c", 1899, __func__, 3, "AIM_ALLOC: %s size %zu type %s" , "functional_map[i]", memorysize, "int"); goto cleanup; } }; | |||
1900 | AIM_ALLOC(functional_xyz[i], 3*numPoint[i], double, aimInfo, status){ if (functional_xyz[i] != ((void*)0)) { status = -4; aim_status (aimInfo, status, "tacsAIM.c", 1900, __func__, 1, "AIM_ALLOC: %s != NULL" , "functional_xyz[i]"); goto cleanup; } size_t memorysize = 3 *numPoint[i]; functional_xyz[i] = (double *) EG_alloc(memorysize *sizeof(double)); if (functional_xyz[i] == ((void*)0)) { status = -4; aim_status(aimInfo, status, "tacsAIM.c", 1900, __func__ , 3, "AIM_ALLOC: %s size %zu type %s", "functional_xyz[i]", memorysize , "double"); goto cleanup; } }; | |||
1901 | ||||
1902 | for (j = 0; j < numPoint[i]; j++) { | |||
1903 | status = fscanf(fp, "%d %lf %lf %lf", &functional_map[i][j], | |||
1904 | &functional_xyz[i][3*j+0], | |||
1905 | &functional_xyz[i][3*j+1], | |||
1906 | &functional_xyz[i][3*j+2]); | |||
1907 | if (status == EOF(-1) || status != 4) { | |||
1908 | AIM_ERROR(aimInfo, "Failed to read sens file data"){ aim_message(aimInfo, CERROR, 0 , "tacsAIM.c", 1908, __func__ , "Failed to read sens file data"); }; | |||
1909 | status = CAPS_IOERR-332; goto cleanup; | |||
1910 | } | |||
1911 | ||||
1912 | if (functional_map[i][j] < 1 || functional_map[i][j] > numNode) { | |||
1913 | AIM_ERROR(aimInfo, "sens file volume mesh vertex index: %d out-of-range [1-%d]", functional_map[i][j], numNode){ aim_message(aimInfo, CERROR, 0 , "tacsAIM.c", 1913, __func__ , "sens file volume mesh vertex index: %d out-of-range [1-%d]" , functional_map[i][j], numNode); }; | |||
1914 | status = CAPS_IOERR-332; goto cleanup; | |||
1915 | } | |||
1916 | } | |||
1917 | } | |||
1918 | ||||
1919 | AIM_ALLOC(dxyz, tacsInstance->numMesh, double*, aimInfo, status){ if (dxyz != ((void*)0)) { status = -4; aim_status(aimInfo, status , "tacsAIM.c", 1919, __func__, 1, "AIM_ALLOC: %s != NULL", "dxyz" ); goto cleanup; } size_t memorysize = tacsInstance->numMesh ; dxyz = (double* *) EG_alloc(memorysize*sizeof(double*)); if (dxyz == ((void*)0)) { status = -4; aim_status(aimInfo, status , "tacsAIM.c", 1919, __func__, 3, "AIM_ALLOC: %s size %zu type %s" , "dxyz", memorysize, "double*"); goto cleanup; } }; | |||
1920 | for (ibody = 0; ibody < tacsInstance->numMesh; ibody++) dxyz[ibody] = NULL((void*)0); | |||
1921 | ||||
1922 | /* set derivatives */ | |||
1923 | for (idv = 0; idv < tacsInstance->feaProblem.numDesignVariable; idv++) { | |||
1924 | ||||
1925 | name = tacsInstance->feaProblem.feaDesignVariable[idv].name; | |||
1926 | ||||
1927 | // Loop over the geometry in values and compute sensitivities for all bodies | |||
1928 | index = aim_getIndex(aimInfo, name, GEOMETRYIN); | |||
1929 | status = aim_getValue(aimInfo, index, GEOMETRYIN, &geomInVal); | |||
1930 | if (status == CAPS_BADINDEX-304) continue; | |||
1931 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1931 , __func__, 0); goto cleanup; }; | |||
1932 | ||||
1933 | for (i = 0; i < numFunctional; i++) { | |||
1934 | AIM_STRDUP(values[i].derivs[idv].name, name, aimInfo, status){ if (values[i].derivs[idv].name != ((void*)0)) { status = -4 ; aim_status(aimInfo, status, "tacsAIM.c", 1934, __func__, 1, "AIM_STRDUP: %s != NULL!", "values[i].derivs[idv].name"); goto cleanup; } values[i].derivs[idv].name = EG_strdup(name); if ( values[i].derivs[idv].name == ((void*)0)) { status = -4; aim_status (aimInfo, status, "tacsAIM.c", 1934, __func__, 2, "AIM_STRDUP: %s %s" , "values[i].derivs[idv].name", name); goto cleanup; } }; | |||
1935 | ||||
1936 | AIM_ALLOC(values[i].derivs[idv].deriv, geomInVal->length, double, aimInfo, status){ if (values[i].derivs[idv].deriv != ((void*)0)) { status = - 4; aim_status(aimInfo, status, "tacsAIM.c", 1936, __func__, 1 , "AIM_ALLOC: %s != NULL", "values[i].derivs[idv].deriv"); goto cleanup; } size_t memorysize = geomInVal->length; values[ i].derivs[idv].deriv = (double *) EG_alloc(memorysize*sizeof( double)); if (values[i].derivs[idv].deriv == ((void*)0)) { status = -4; aim_status(aimInfo, status, "tacsAIM.c", 1936, __func__ , 3, "AIM_ALLOC: %s size %zu type %s", "values[i].derivs[idv].deriv" , memorysize, "double"); goto cleanup; } }; | |||
1937 | values[i].derivs[idv].len_wrt = geomInVal->length; | |||
1938 | for (j = 0; j < geomInVal->length; j++) | |||
1939 | values[i].derivs[idv].deriv[j] = 0; | |||
1940 | } | |||
1941 | ||||
1942 | for (irow = 0; irow < geomInVal->nrow; irow++) { | |||
1943 | for (icol = 0; icol < geomInVal->ncol; icol++) { | |||
1944 | ||||
1945 | for (ibody = 0; ibody < tacsInstance->numMesh; ibody++) { | |||
1946 | status = aim_tessSensitivity(aimInfo, | |||
1947 | name, | |||
1948 | irow+1, icol+1, // row, col | |||
1949 | tacsInstance->feaMesh[ibody].egadsTess, | |||
1950 | &numNode, &dxyz[ibody]); | |||
1951 | AIM_STATUS(aimInfo, status, "Sensitivity for: %s\n", name)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1951 , __func__, 2, "Sensitivity for: %s\n", name); goto cleanup; }; | |||
1952 | AIM_NOTNULL(dxyz[ibody], aimInfo, status){ if (dxyz[ibody] == ((void*)0)) { status = -307; aim_status( aimInfo, status, "tacsAIM.c", 1952, __func__, 1, "%s == NULL!" , "dxyz[ibody]"); goto cleanup; } }; | |||
1953 | } | |||
1954 | ||||
1955 | for (i = 0; i < numFunctional; i++) { | |||
1956 | functional_dvar = values[i].derivs[idv].deriv[geomInVal->ncol*irow + icol]; | |||
1957 | ||||
1958 | for (j = 0; j < numPoint[i]; j++) { | |||
1959 | k = functional_map[i][j]-1; // 1-based indexing | |||
1960 | ibody = surf2tess[2*k+0]; | |||
1961 | k = surf2tess[2*k+1]; | |||
1962 | ||||
1963 | functional_dvar += functional_xyz[i][3*j+0]*dxyz[ibody][3*k + 0] // dx/dGeomIn | |||
1964 | + functional_xyz[i][3*j+1]*dxyz[ibody][3*k + 1] // dy/dGeomIn | |||
1965 | + functional_xyz[i][3*j+2]*dxyz[ibody][3*k + 2]; // dz/dGeomIn | |||
1966 | } | |||
1967 | values[i].derivs[idv].deriv[geomInVal->ncol*irow + icol] = functional_dvar; | |||
1968 | } | |||
1969 | ||||
1970 | for (ibody = 0; ibody < tacsInstance->numMesh; ibody++) | |||
1971 | AIM_FREE(dxyz[ibody]){ EG_free(dxyz[ibody]); dxyz[ibody] = ((void*)0); }; | |||
1972 | } | |||
1973 | } | |||
1974 | } | |||
1975 | ||||
1976 | /* create the dynamic output */ | |||
1977 | for (i = 0; i < numFunctional; i++) { | |||
1978 | status = aim_makeDynamicOutput(aimInfo, names[i], &values[i]); | |||
1979 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "tacsAIM.c", 1979 , __func__, 0); goto cleanup; }; | |||
1980 | } | |||
1981 | } | |||
1982 | ||||
1983 | cleanup: | |||
1984 | ||||
1985 | if (fp != NULL((void*)0)) fclose(fp); | |||
1986 | ||||
1987 | if (functional_xyz != NULL((void*)0)) | |||
1988 | for (i = 0; i < numFunctional; i++) | |||
1989 | AIM_FREE(functional_xyz[i]){ EG_free(functional_xyz[i]); functional_xyz[i] = ((void*)0); }; | |||
1990 | ||||
1991 | if (functional_map != NULL((void*)0)) | |||
1992 | for (i = 0; i < numFunctional; i++) | |||
1993 | AIM_FREE(functional_map[i]){ EG_free(functional_map[i]); functional_map[i] = ((void*)0); }; | |||
1994 | ||||
1995 | if (names != NULL((void*)0)) | |||
1996 | for (i = 0; i < numFunctional; i++) | |||
1997 | AIM_FREE(names[i]){ EG_free(names[i]); names[i] = ((void*)0); }; | |||
1998 | ||||
1999 | if (dxyz != NULL((void*)0)) | |||
2000 | for (i = 0; i < tacsInstance->numMesh; i++) | |||
2001 | AIM_FREE(dxyz[i]){ EG_free(dxyz[i]); dxyz[i] = ((void*)0); }; | |||
2002 | ||||
2003 | AIM_FREE(functional_xyz){ EG_free(functional_xyz); functional_xyz = ((void*)0); }; | |||
2004 | AIM_FREE(functional_map){ EG_free(functional_map); functional_map = ((void*)0); }; | |||
2005 | AIM_FREE(names){ EG_free(names); names = ((void*)0); }; | |||
2006 | AIM_FREE(dxyz){ EG_free(dxyz); dxyz = ((void*)0); }; | |||
2007 | AIM_FREE(values){ EG_free(values); values = ((void*)0); }; | |||
2008 | AIM_FREE(surf2tess){ EG_free(surf2tess); surf2tess = ((void*)0); }; | |||
2009 | AIM_FREE(numPoint){ EG_free(numPoint); numPoint = ((void*)0); }; | |||
2010 | ||||
2011 | return status; | |||
2012 | } | |||
2013 | ||||
2014 | ||||
2015 | // Set TACS output variables | |||
2016 | int aimOutputs(/*@unused@*/ void *instStore, /*@unused@*/ void *aimStruc, | |||
2017 | /*@unused@*/ int index, /*@unused@*/ char **aoname, /*@unused@*/ capsValue *form) | |||
2018 | { | |||
2019 | /*! \page aimOutputsTACS AIM Outputs | |||
2020 | * The following list outlines the TACS outputs available through the AIM interface. | |||
2021 | */ | |||
2022 | ||||
2023 | #ifdef DEBUG | |||
2024 | printf(" nastranAIM/aimOutputs index = %d!\n", index); | |||
2025 | #endif | |||
2026 | ||||
2027 | /*<--! \page aimOutputsTACS AIM Outputs--> | |||
2028 | * - <B>EigenValue</B> = List of Eigen-Values (\f$ \lambda\f$) after a modal solve. | |||
2029 | * - <B>EigenRadian</B> = List of Eigen-Values in terms of radians (\f$ \omega = \sqrt{\lambda}\f$ ) after a modal solve. | |||
2030 | * - <B>EigenFrequency</B> = List of Eigen-Values in terms of frequencies (\f$ f = \frac{\omega}{2\pi}\f$) after a modal solve. | |||
2031 | * - <B>EigenGeneralMass</B> = List of generalized masses for the Eigen-Values. | |||
2032 | * - <B>EigenGeneralStiffness</B> = List of generalized stiffness for the Eigen-Values. | |||
2033 | * - <B>Objective</B> = Final objective value for a design optimization case. | |||
2034 | * - <B>ObjectiveHistory</B> = List of objective value for the history of a design optimization case. | |||
2035 | */ | |||
2036 | ||||
2037 | #if 0 | |||
2038 | if (index == 1) { | |||
2039 | *aoname = EG_strdup("EigenValue"); | |||
2040 | ||||
2041 | } else if (index == 2) { | |||
2042 | *aoname = EG_strdup("EigenRadian"); | |||
2043 | ||||
2044 | } else if (index == 3) { | |||
2045 | *aoname = EG_strdup("EigenFrequency"); | |||
2046 | ||||
2047 | } else if (index == 4) { | |||
2048 | *aoname = EG_strdup("EigenGeneralMass"); | |||
2049 | ||||
2050 | } else if (index == 5) { | |||
2051 | *aoname = EG_strdup("EigenGeneralStiffness"); | |||
2052 | ||||
2053 | } else if (index == 6) { | |||
2054 | *aoname = EG_strdup("Objective"); | |||
2055 | ||||
2056 | } else if (index == 7) { | |||
2057 | *aoname = EG_strdup("ObjectiveHistory"); | |||
2058 | } | |||
2059 | ||||
2060 | form->type = Double; | |||
2061 | form->units = NULL((void*)0); | |||
2062 | form->lfixed = Change; | |||
2063 | form->sfixed = Change; | |||
2064 | form->vals.reals = NULL((void*)0); | |||
2065 | form->vals.real = 0; | |||
2066 | #endif | |||
2067 | ||||
2068 | return CAPS_SUCCESS0; | |||
2069 | } | |||
2070 | ||||
2071 | ||||
2072 | // Calculate TACS output | |||
2073 | int aimCalcOutput(/*@unused@*/ void *instStore, /*@unused@*/ void *aimInfo, /*@unused@*/ int index, | |||
2074 | /*@unused@*/ capsValue *val) | |||
2075 | { | |||
2076 | int status = CAPS_SUCCESS0; // Function return status | |||
2077 | ||||
2078 | #if 0 | |||
2079 | int i; //Indexing | |||
2080 | ||||
2081 | int numData = 0; | |||
2082 | double *dataVector = NULL((void*)0); | |||
2083 | double **dataMatrix = NULL((void*)0); | |||
2084 | aimStorage *tacsInstance; | |||
2085 | ||||
2086 | char *filename = NULL((void*)0); // File to open | |||
2087 | char extF06[] = ".f06", extOP2[] = ".op2"; | |||
2088 | FILE *fp = NULL((void*)0); // File pointer | |||
2089 | ||||
2090 | tacsInstance = (aimStorage *) instStore; | |||
2091 | ||||
2092 | if (index <= 5) { | |||
2093 | filename = (char *) EG_alloc((strlen(tacsInstance->projectName) + | |||
2094 | strlen(extF06) +1)*sizeof(char)); | |||
2095 | if (filename == NULL((void*)0)) return EGADS_MALLOC-4; | |||
2096 | ||||
2097 | sprintf(filename, "%s%s", tacsInstance->projectName, extF06); | |||
2098 | ||||
2099 | fp = aim_fopen(aimInfo, filename, "r"); | |||
2100 | ||||
2101 | EG_free(filename); // Free filename allocation | |||
2102 | ||||
2103 | if (fp == NULL((void*)0)) { | |||
2104 | #ifdef DEBUG | |||
2105 | printf(" nastranAIM/aimCalcOutput Cannot open Output file!\n"); | |||
2106 | #endif | |||
2107 | return CAPS_IOERR-332; | |||
2108 | } | |||
2109 | ||||
2110 | status = nastran_readF06EigenValue(fp, &numData, &dataMatrix); | |||
2111 | if ((status == CAPS_SUCCESS0) && (dataMatrix != NULL((void*)0))) { | |||
2112 | ||||
2113 | val->nrow = numData; | |||
2114 | val->ncol = 1; | |||
2115 | val->length = val->nrow*val->ncol; | |||
2116 | if (val->length == 1) val->dim = Scalar; | |||
2117 | else val->dim = Vector; | |||
2118 | ||||
2119 | if (val->length == 1) { | |||
2120 | val->vals.real = dataMatrix[0][index-1]; | |||
2121 | } else { | |||
2122 | ||||
2123 | val->vals.reals = (double *) EG_alloc(val->length*sizeof(double)); | |||
2124 | if (val->vals.reals != NULL((void*)0)) { | |||
2125 | ||||
2126 | for (i = 0; i < val->length; i++) { | |||
2127 | ||||
2128 | val->vals.reals[i] = dataMatrix[i][index-1]; | |||
2129 | } | |||
2130 | ||||
2131 | } else status = EGADS_MALLOC-4; | |||
2132 | } | |||
2133 | } | |||
2134 | } else if (index == 6 || index == 7) { | |||
2135 | filename = (char *) EG_alloc((strlen(tacsInstance->projectName) + | |||
2136 | strlen(extOP2) +1)*sizeof(char)); | |||
2137 | if (filename == NULL((void*)0)) return EGADS_MALLOC-4; | |||
2138 | ||||
2139 | sprintf(filename, "%s%s", tacsInstance->projectName, extOP2); | |||
2140 | ||||
2141 | status = nastran_readOP2Objective(filename, &numData, &dataVector); | |||
2142 | ||||
2143 | EG_free(filename); // Free filename allocation | |||
2144 | ||||
2145 | if (status == CAPS_SUCCESS0 && dataVector != NULL((void*)0) && numData > 0) { | |||
2146 | ||||
2147 | if (index == 6) val->nrow = 1; | |||
2148 | else val->nrow = numData; | |||
2149 | ||||
2150 | val->ncol = 1; | |||
2151 | val->length = val->nrow*val->ncol; | |||
2152 | ||||
2153 | if (val->length == 1) val->dim = Scalar; | |||
2154 | else val->dim = Vector; | |||
2155 | ||||
2156 | if (val->length == 1) { | |||
2157 | val->vals.real = dataVector[numData-1]; | |||
2158 | } else { | |||
2159 | ||||
2160 | val->vals.reals = (double *) EG_alloc(val->length*sizeof(double)); | |||
2161 | if (val->vals.reals != NULL((void*)0)) { | |||
2162 | ||||
2163 | for (i = 0; i < val->length; i++) { | |||
2164 | ||||
2165 | val->vals.reals[i] = dataVector[i]; | |||
2166 | } | |||
2167 | ||||
2168 | } else status = EGADS_MALLOC-4; | |||
2169 | } | |||
2170 | } | |||
2171 | } | |||
2172 | ||||
2173 | // Restore the path we came in with | |||
2174 | if (fp != NULL((void*)0)) fclose(fp); | |||
2175 | ||||
2176 | if (dataMatrix != NULL((void*)0)) { | |||
2177 | for (i = 0; i < numData; i++) { | |||
2178 | if (dataMatrix[i] != NULL((void*)0)) EG_free(dataMatrix[i]); | |||
2179 | } | |||
2180 | EG_free(dataMatrix); | |||
2181 | } | |||
2182 | ||||
2183 | if (dataVector != NULL((void*)0)) EG_free(dataVector); | |||
2184 | #endif | |||
2185 | return status; | |||
2186 | } | |||
2187 | ||||
2188 | ||||
2189 | void aimCleanup(void *instStore) | |||
2190 | { | |||
2191 | int status; // Returning status | |||
2192 | aimStorage *tacsInstance; | |||
2193 | ||||
2194 | #ifdef DEBUG | |||
2195 | printf(" nastranAIM/aimCleanup!\n"); | |||
2196 | #endif | |||
2197 | tacsInstance = (aimStorage *) instStore; | |||
2198 | ||||
2199 | status = destroy_aimStorage(tacsInstance); | |||
2200 | if (status != CAPS_SUCCESS0) | |||
2201 | printf("Error: Status %d during clean up of instance\n", status); | |||
2202 | ||||
2203 | EG_free(tacsInstance); | |||
2204 | } | |||
2205 | ||||
2206 | ||||
2207 | int aimDiscr(char *tname, capsDiscr *discr) | |||
2208 | { | |||
2209 | int status = CAPS_SUCCESS0; // Function return status | |||
2210 | int i; | |||
2211 | ego *tess = NULL((void*)0); | |||
2212 | capsValue *valMesh; | |||
2213 | aimStorage *tacsInstance; | |||
2214 | ||||
2215 | #ifdef DEBUG | |||
2216 | printf(" nastranAIM/aimDiscr: tname = %s!\n", tname); | |||
2217 | #endif | |||
2218 | if (tname == NULL((void*)0)) return CAPS_NOTFOUND-303; | |||
2219 | ||||
2220 | tacsInstance = (aimStorage *) discr->instStore; | |||
2221 | ||||
2222 | status = aim_getValue(discr->aInfo, Mesh, ANALYSISIN, &valMesh); | |||
2223 | AIM_STATUS(discr->aInfo, status)if (status != 0) { aim_status(discr->aInfo, status, "tacsAIM.c" , 2223, __func__, 0); goto cleanup; }; | |||
2224 | ||||
2225 | if (valMesh->nullVal == IsNull) { | |||
2226 | AIM_ANALYSISIN_ERROR(discr->aInfo, Mesh, "'Mesh' input must be linked to an output 'Surface_Mesh'"){ aim_message(discr->aInfo, CERROR, Mesh, "tacsAIM.c", 2226 , __func__, "'Mesh' input must be linked to an output 'Surface_Mesh'" ); }; | |||
2227 | status = CAPS_BADVALUE-311; | |||
2228 | goto cleanup; | |||
2229 | } | |||
2230 | ||||
2231 | // Get mesh | |||
2232 | tacsInstance->numMesh = valMesh->length; | |||
2233 | tacsInstance->feaMesh = (meshStruct *)valMesh->vals.AIMptr; | |||
2234 | AIM_NOTNULL(tacsInstance->feaMesh, discr->aInfo, status){ if (tacsInstance->feaMesh == ((void*)0)) { status = -307 ; aim_status(discr->aInfo, status, "tacsAIM.c", 2234, __func__ , 1, "%s == NULL!", "tacsInstance->feaMesh"); goto cleanup ; } }; | |||
2235 | AIM_STATUS(discr->aInfo, status)if (status != 0) { aim_status(discr->aInfo, status, "tacsAIM.c" , 2235, __func__, 0); goto cleanup; }; | |||
2236 | ||||
2237 | AIM_ALLOC(tess, tacsInstance->numMesh, ego, discr->aInfo, status){ if (tess != ((void*)0)) { status = -4; aim_status(discr-> aInfo, status, "tacsAIM.c", 2237, __func__, 1, "AIM_ALLOC: %s != NULL" , "tess"); goto cleanup; } size_t memorysize = tacsInstance-> numMesh; tess = (ego *) EG_alloc(memorysize*sizeof(ego)); if ( tess == ((void*)0)) { status = -4; aim_status(discr->aInfo , status, "tacsAIM.c", 2237, __func__, 3, "AIM_ALLOC: %s size %zu type %s" , "tess", memorysize, "ego"); goto cleanup; } }; | |||
2238 | for (i = 0; i < tacsInstance->numMesh; i++) { | |||
2239 | tess[i] = tacsInstance->feaMesh[i].egadsTess; | |||
2240 | } | |||
2241 | ||||
2242 | status = mesh_fillDiscr(tname, &tacsInstance->groupMap, tacsInstance->numMesh, tess, discr); | |||
2243 | AIM_STATUS(discr->aInfo, status)if (status != 0) { aim_status(discr->aInfo, status, "tacsAIM.c" , 2243, __func__, 0); goto cleanup; }; | |||
2244 | ||||
2245 | #ifdef DEBUG | |||
2246 | printf(" nastranAIM/aimDiscr: Instance = %d, Finished!!\n", iIndex); | |||
2247 | #endif | |||
2248 | ||||
2249 | status = CAPS_SUCCESS0; | |||
2250 | ||||
2251 | cleanup: | |||
2252 | if (status != CAPS_SUCCESS0) | |||
2253 | printf("\tPremature exit: function aimDiscr nastranAIM status = %d", | |||
2254 | status); | |||
2255 | ||||
2256 | AIM_FREE(tess){ EG_free(tess); tess = ((void*)0); }; | |||
2257 | return status; | |||
2258 | } | |||
2259 | ||||
2260 | int aimTransfer(capsDiscr *discr, const char *dataName, int numPoint, | |||
2261 | int dataRank, double *dataVal, /*@unused@*/ char **units) | |||
2262 | { | |||
2263 | ||||
2264 | /*! \page dataTransferTACS TACS Data Transfer | |||
2265 | * | |||
2266 | * The TACS AIM has the ability to transfer displacements and eigenvectors from the AIM and pressure | |||
2267 | * distributions to the AIM using the conservative and interpolative data transfer schemes in CAPS. | |||
2268 | */ | |||
2269 | ||||
2270 | /* | |||
2271 | * \section dataFromTACS Data transfer from TACS (FieldOut) | |||
2272 | * | |||
2273 | * <ul> | |||
2274 | * <li> <B>"Displacement"</B> </li> <br> | |||
2275 | * Retrieves nodal displacements from the *.f06 file. | |||
2276 | * </ul> | |||
2277 | * | |||
2278 | * <ul> | |||
2279 | * <li> <B>"EigenVector_#"</B> </li> <br> | |||
2280 | * Retrieves modal eigen-vectors from the *.f06 file, where "#" should be replaced by the | |||
2281 | * corresponding mode number for the eigen-vector (eg. EigenVector_3 would correspond to the third mode, | |||
2282 | * while EigenVector_6 would be the sixth mode). | |||
2283 | * </ul> | |||
2284 | * | |||
2285 | * \section dataToTACS Data transfer to TACS (FieldIn) | |||
2286 | * <ul> | |||
2287 | * <li> <B>"Pressure"</B> </li> <br> | |||
2288 | * Writes appropriate load cards using the provided pressure distribution. | |||
2289 | * </ul> | |||
2290 | * | |||
2291 | */ | |||
2292 | ||||
2293 | int status; // Function return status | |||
2294 | int i, j, dataPoint, bIndex; // Indexing | |||
2295 | aimStorage *tacsInstance; | |||
2296 | ||||
2297 | char *extF06 = ".f06"; | |||
2298 | ||||
2299 | // FO6 data variables | |||
2300 | int numGridPoint = 0; | |||
2301 | int numEigenVector = 0; | |||
2302 | ||||
2303 | double **dataMatrix = NULL((void*)0); | |||
2304 | ||||
2305 | // Specific EigenVector to use | |||
2306 | int eigenVectorIndex = 0; | |||
2307 | ||||
2308 | // Variables used in global node mapping | |||
2309 | //int *storage; | |||
2310 | int globalNodeID; | |||
2311 | ||||
2312 | // Filename stuff | |||
2313 | char *filename = NULL((void*)0); | |||
2314 | FILE *fp; // File pointer | |||
2315 | ||||
2316 | #ifdef DEBUG | |||
2317 | printf(" nastranAIM/aimTransfer name = %s npts = %d/%d!\n", | |||
2318 | dataName, numPoint, dataRank); | |||
2319 | #endif | |||
2320 | tacsInstance = (aimStorage *) discr->instStore; | |||
2321 | ||||
2322 | //Get the appropriate parts of the tessellation to data | |||
2323 | //storage = (int *) discr->ptrm; | |||
2324 | //capsGroupList = &storage[0]; // List of boundary ID (groupMap) in the transfer | |||
2325 | ||||
2326 | if (strcasecmp(dataName, "Displacement") != 0 && | |||
2327 | strncmp(dataName, "EigenVector", 11) != 0) { | |||
2328 | ||||
2329 | printf("Unrecognized data transfer variable - %s\n", dataName); | |||
2330 | return CAPS_NOTFOUND-303; | |||
2331 | } | |||
2332 | ||||
2333 | filename = (char *) EG_alloc((strlen(tacsInstance->projectName) + | |||
2334 | strlen(extF06) + 1)*sizeof(char)); | |||
2335 | if (filename == NULL((void*)0)) return EGADS_MALLOC-4; | |||
2336 | sprintf(filename,"%s%s", tacsInstance->projectName, extF06); | |||
2337 | ||||
2338 | // Open file | |||
2339 | fp = aim_fopen(discr->aInfo, filename, "r"); | |||
2340 | if (fp == NULL((void*)0)) { | |||
2341 | printf("Unable to open file: %s\n", filename); | |||
2342 | if (filename != NULL((void*)0)) EG_free(filename); | |||
2343 | return CAPS_IOERR-332; | |||
2344 | } | |||
2345 | ||||
2346 | if (filename != NULL((void*)0)) EG_free(filename); | |||
2347 | filename = NULL((void*)0); | |||
2348 | ||||
2349 | if (strcasecmp(dataName, "Displacement") == 0) { | |||
2350 | ||||
2351 | if (dataRank != 3) { | |||
2352 | ||||
2353 | printf("Invalid rank for dataName \"%s\" - excepted a rank of 3!!!\n", | |||
2354 | dataName); | |||
2355 | status = CAPS_BADRANK-301; | |||
2356 | ||||
2357 | } else { | |||
2358 | ||||
2359 | status = nastran_readF06Displacement(fp, | |||
2360 | -1, | |||
2361 | &numGridPoint, | |||
2362 | &dataMatrix); | |||
2363 | fclose(fp); | |||
2364 | fp = NULL((void*)0); | |||
2365 | } | |||
2366 | ||||
2367 | } else if (strncmp(dataName, "EigenVector", 11) == 0) { | |||
2368 | ||||
2369 | // Which EigenVector do we want ? | |||
2370 | for (i = 0; i < strlen(dataName); i++) { | |||
2371 | if (dataName[i] == '_' ) break; | |||
2372 | } | |||
2373 | ||||
2374 | if (i == strlen(dataName)) { | |||
2375 | eigenVectorIndex = 1; | |||
2376 | } else { | |||
2377 | ||||
2378 | status = sscanf(dataName, "EigenVector_%d", &eigenVectorIndex); | |||
2379 | if (status != 1) { | |||
2380 | printf("Unable to determine which EigenVector to use - Defaulting the first EigenVector!!!\n"); | |||
2381 | eigenVectorIndex = 1; | |||
2382 | } | |||
2383 | } | |||
2384 | ||||
2385 | if (dataRank != 3) { | |||
2386 | ||||
2387 | printf("Invalid rank for dataName \"%s\" - excepted a rank of 3!!!\n", | |||
2388 | dataName); | |||
2389 | status = CAPS_BADRANK-301; | |||
2390 | ||||
2391 | } else { | |||
2392 | ||||
2393 | status = nastran_readF06EigenVector(fp, | |||
2394 | &numEigenVector, | |||
2395 | &numGridPoint, | |||
2396 | &dataMatrix); | |||
2397 | } | |||
2398 | ||||
2399 | fclose(fp); | |||
2400 | fp = NULL((void*)0); | |||
2401 | ||||
2402 | } else { | |||
2403 | ||||
2404 | status = CAPS_NOTFOUND-303; | |||
2405 | } | |||
2406 | ||||
2407 | AIM_STATUS(discr->aInfo, status)if (status != 0) { aim_status(discr->aInfo, status, "tacsAIM.c" , 2407, __func__, 0); goto cleanup; }; | |||
2408 | ||||
2409 | ||||
2410 | // Check EigenVector range | |||
2411 | if (strncmp(dataName, "EigenVector", 11) == 0) { | |||
2412 | if (eigenVectorIndex > numEigenVector) { | |||
2413 | printf("Only %d EigenVectors found but index %d requested!\n", | |||
2414 | numEigenVector, eigenVectorIndex); | |||
2415 | status = CAPS_RANGEERR-326; | |||
2416 | goto cleanup; | |||
2417 | } | |||
2418 | ||||
2419 | if (eigenVectorIndex < 1) { | |||
2420 | printf("For EigenVector_X notation, X must be >= 1, currently X = %d\n", | |||
2421 | eigenVectorIndex); | |||
2422 | status = CAPS_RANGEERR-326; | |||
2423 | goto cleanup; | |||
2424 | } | |||
2425 | ||||
2426 | } | |||
2427 | if (dataMatrix == NULL((void*)0)) { | |||
2428 | status = CAPS_NULLVALUE-307; | |||
2429 | goto cleanup; | |||
2430 | } | |||
2431 | ||||
2432 | for (i = 0; i < numPoint; i++) { | |||
2433 | ||||
2434 | bIndex = discr->tessGlobal[2*i ]; | |||
2435 | globalNodeID = discr->tessGlobal[2*i+1] + | |||
2436 | discr->bodys[bIndex-1].globalOffset; | |||
2437 | ||||
2438 | if (strcasecmp(dataName, "Displacement") == 0) { | |||
2439 | ||||
2440 | for (dataPoint = 0; dataPoint < numGridPoint; dataPoint++) { | |||
2441 | if ((int) dataMatrix[dataPoint][0] == globalNodeID) break; | |||
2442 | } | |||
2443 | ||||
2444 | if (dataPoint == numGridPoint) { | |||
2445 | printf("Unable to locate global ID = %d in the data matrix\n", | |||
2446 | globalNodeID); | |||
2447 | status = CAPS_NOTFOUND-303; | |||
2448 | goto cleanup; | |||
2449 | } | |||
2450 | ||||
2451 | dataVal[dataRank*i+0] = dataMatrix[dataPoint][2]; // T1 | |||
2452 | dataVal[dataRank*i+1] = dataMatrix[dataPoint][3]; // T2 | |||
2453 | dataVal[dataRank*i+2] = dataMatrix[dataPoint][4]; // T3 | |||
2454 | ||||
2455 | } else if (strncmp(dataName, "EigenVector", 11) == 0) { | |||
2456 | ||||
2457 | ||||
2458 | for (dataPoint = 0; dataPoint < numGridPoint; dataPoint++) { | |||
2459 | if ((int) dataMatrix[eigenVectorIndex - 1][8*dataPoint + 0] == | |||
2460 | globalNodeID) break; | |||
2461 | } | |||
2462 | ||||
2463 | if (dataPoint == numGridPoint) { | |||
2464 | printf("Unable to locate global ID = %d in the data matrix\n", | |||
2465 | globalNodeID); | |||
2466 | status = CAPS_NOTFOUND-303; | |||
2467 | goto cleanup; | |||
2468 | } | |||
2469 | ||||
2470 | dataVal[dataRank*i+0] = dataMatrix[eigenVectorIndex- 1][8*dataPoint + 2]; // T1 | |||
2471 | dataVal[dataRank*i+1] = dataMatrix[eigenVectorIndex- 1][8*dataPoint + 3]; // T2 | |||
2472 | dataVal[dataRank*i+2] = dataMatrix[eigenVectorIndex- 1][8*dataPoint + 4]; // T3 | |||
2473 | //dataVal[dataRank*i+3] = dataMatrix[eigenVectorIndex- 1][8*dataPoint + 5]; // R1 - Don't use rotations | |||
2474 | //dataVal[dataRank*i+4] = dataMatrix[eigenVectorIndex- 1][8*dataPoint + 6]; // R2 | |||
2475 | //dataVal[dataRank*i+5] = dataMatrix[eigenVectorIndex- 1][8*dataPoint + 7]; // R3 | |||
2476 | ||||
2477 | } | |||
2478 | } | |||
2479 | ||||
2480 | status = CAPS_SUCCESS0; | |||
2481 | ||||
2482 | cleanup: | |||
2483 | ||||
2484 | if (fp != NULL((void*)0)) fclose(fp); | |||
2485 | // Free data matrix | |||
2486 | if (dataMatrix != NULL((void*)0)) { | |||
2487 | j = 0; | |||
2488 | if (strcasecmp(dataName, "Displacement") == 0) j = numGridPoint; | |||
2489 | else if (strncmp(dataName, "EigenVector", 11) == 0) j = numEigenVector; | |||
2490 | ||||
2491 | for (i = 0; i < j; i++) { | |||
2492 | if (dataMatrix[i] != NULL((void*)0)) EG_free(dataMatrix[i]); | |||
2493 | } | |||
2494 | EG_free(dataMatrix); | |||
2495 | } | |||
2496 | ||||
2497 | return status; | |||
2498 | } | |||
2499 | ||||
2500 | ||||
2501 | void aimFreeDiscrPtr(void *ptr) | |||
2502 | { | |||
2503 | // Extra information to store into the discr void pointer - just a int array | |||
2504 | EG_free(ptr); | |||
2505 | } | |||
2506 | ||||
2507 | ||||
2508 | int aimLocateElement(capsDiscr *discr, double *params, double *param, | |||
2509 | int *bIndex, int *eIndex, double *bary) | |||
2510 | { | |||
2511 | #ifdef DEBUG | |||
2512 | printf(" nastranAIM/aimLocateElement !\n"); | |||
2513 | #endif | |||
2514 | ||||
2515 | return aim_locateElement(discr, params, param, bIndex, eIndex, bary); | |||
2516 | } | |||
2517 | ||||
2518 | ||||
2519 | int aimInterpolation(capsDiscr *discr, const char *name, | |||
2520 | int bIndex, int eIndex, double *bary, | |||
2521 | int rank, double *data, double *result) | |||
2522 | { | |||
2523 | #ifdef DEBUG | |||
2524 | printf(" nastranAIM/aimInterpolation %s!\n", name); | |||
2525 | #endif | |||
2526 | ||||
2527 | return aim_interpolation(discr, name, bIndex, eIndex, bary, rank, data, | |||
2528 | result); | |||
2529 | } | |||
2530 | ||||
2531 | ||||
2532 | int aimInterpolateBar(capsDiscr *discr, const char *name, | |||
2533 | int bIndex, int eIndex, double *bary, | |||
2534 | int rank, double *r_bar, double *d_bar) | |||
2535 | { | |||
2536 | #ifdef DEBUG | |||
2537 | printf(" nastranAIM/aimInterpolateBar %s!\n", name); | |||
2538 | #endif | |||
2539 | ||||
2540 | return aim_interpolateBar(discr, name, bIndex, eIndex, bary, rank, r_bar, | |||
2541 | d_bar); | |||
2542 | } | |||
2543 | ||||
2544 | ||||
2545 | int aimIntegration(capsDiscr *discr, const char *name,int bIndex, int eIndex, | |||
2546 | int rank, double *data, double *result) | |||
2547 | { | |||
2548 | #ifdef DEBUG | |||
2549 | printf(" nastranAIM/aimIntegration %s!\n", name); | |||
2550 | #endif | |||
2551 | ||||
2552 | return aim_integration(discr, name, bIndex, eIndex, rank, data, result); | |||
2553 | } | |||
2554 | ||||
2555 | ||||
2556 | int aimIntegrateBar(capsDiscr *discr, const char *name, int bIndex, int eIndex, | |||
2557 | int rank, double *r_bar, double *d_bar) | |||
2558 | { | |||
2559 | #ifdef DEBUG | |||
2560 | printf(" nastranAIM/aimIntegrateBar %s!\n", name); | |||
2561 | #endif | |||
2562 | ||||
2563 | return aim_integrateBar(discr, name, bIndex, eIndex, rank, r_bar, d_bar); | |||
2564 | } |