File: | cbaeroAIM.c |
Warning: | line 683, column 16 Null pointer passed to 1st parameter expecting 'nonnull' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | |||
2 | * CAPS: Computational Aircraft Prototype Syntheses | |||
3 | * | |||
4 | * CBAero AIM | |||
5 | * | |||
6 | * Written by Dr. Ryan Durscher AFRL/RQVC | |||
7 | * | |||
8 | * | |||
9 | */ | |||
10 | ||||
11 | //(CHANGE \cite CBAero) | |||
12 | ||||
13 | /*!\mainpage Introduction | |||
14 | * \tableofcontents | |||
15 | * \section overviewCBAero CBAero AIM Overview | |||
16 | * A module in the Computational Aircraft Prototype Syntheses (CAPS) has been developed to interact (primarily | |||
17 | * through input files) with NASA Ames's CBAero. CBAero (Configuration Based Aerodynamics) | |||
18 | * software package is an engineering level aero-thermodynamics tool for predicting the aerodynamic and | |||
19 | * aero-thermodynamic environments of general vehicle configurations. Currently only a subset of CBAero's | |||
20 | * input options have been exposed in the analysis interface module (AIM), but features can easily be included | |||
21 | * as future needs arise. | |||
22 | * | |||
23 | * An outline of the AIM's inputs and outputs are provided in \ref aimInputsCBAero and \ref aimOutputsCBAero, respectively. | |||
24 | * | |||
25 | * Geometric attributes recognized by the AIM are provided in \ref attributeCBAero. | |||
26 | * | |||
27 | * The accepted and expected geometric representation are detailed in \ref geomRepIntentCBAero. | |||
28 | * | |||
29 | */ | |||
30 | ||||
31 | /*! \page attributeCBAero Attribution | |||
32 | * | |||
33 | * The following list of attributes drives the CBAero geometric definition. | |||
34 | * | |||
35 | * - <b> capsLength</b> This attribute defines the length units that the *.csm file is generated in. CBAero grids | |||
36 | * MUST be in units of meter, as such the geometry is scaled accordingly based on this value. | |||
37 | * | |||
38 | * - <b> capsReferenceArea</b> [Optional] This attribute may exist on any <em> Body</em>. Its | |||
39 | * value will be used as the reference area in CBAero's input file with its units assumed to be consistent with | |||
40 | * the attribute "capsLength". No conversion takes place if "capsLength" isn't set. This value may be alternatively set | |||
41 | * through an input value, "ReferenceArea" (see \ref aimInputsCBAero) | |||
42 | * | |||
43 | * - <b> capsReferenceChord</b> and <b> capsReferenceSpan</b> [Optional] These attribute may exist on any <em> Body</em>. Their | |||
44 | * value will be used as the reference moment lengths in CBAero's input file with their units assumed to be consistent with | |||
45 | * the attribute "capsLength". No conversion takes place if "capsLength" isn't set. These values may be alternatively set | |||
46 | * through an input value, "Moment_Length" (see \ref aimInputsCBAero) | |||
47 | * | |||
48 | * - <b> capsReferenceX</b>, <b> capsReferenceY</b>, and <b>capsReferenceZ</b> [Optional] | |||
49 | * These attribute may exist on any <em> Body</em>. Their | |||
50 | * value will be used as the center of gravity (CG) location in CBAero's input file with their units assumed to be consistent with | |||
51 | * the attribute "capsLength". No conversion takes place if "capsLength" isn't set. These values may be alternatively set | |||
52 | * through an input value, "Moment_Center" (see \ref aimInputsCBAero) | |||
53 | * | |||
54 | */ | |||
55 | ||||
56 | #include <string.h> | |||
57 | #include <math.h> | |||
58 | #include "capsTypes.h" | |||
59 | #include "aimUtil.h" | |||
60 | ||||
61 | #include "meshUtils.h" | |||
62 | #include "miscUtils.h" | |||
63 | ||||
64 | #include "fastWriter.h" | |||
65 | ||||
66 | #include "errno.h" | |||
67 | ||||
68 | ||||
69 | #ifdef WIN32 | |||
70 | #define getcwd _getcwd | |||
71 | #define snprintf _snprintf | |||
72 | #define strcasecmp stricmp | |||
73 | #define PATH_MAX4096 _MAX_PATH | |||
74 | ||||
75 | // For _mkdir | |||
76 | #include "direct.h" | |||
77 | ||||
78 | #else | |||
79 | #include <unistd.h> | |||
80 | #include <limits.h> | |||
81 | ||||
82 | // For mkdir | |||
83 | #include "sys/stat.h" | |||
84 | ||||
85 | #endif | |||
86 | ||||
87 | enum aimInputs | |||
88 | { | |||
89 | inProj_Name = 1, /* index is 1-based */ | |||
90 | inMach, | |||
91 | inDynamic_Pressure, | |||
92 | inAlpha, | |||
93 | inBeta, | |||
94 | inReferenceArea, | |||
95 | inReferenceChord, | |||
96 | inReferenceSpan, | |||
97 | inMoment_Center, | |||
98 | inFlow_Type, | |||
99 | inCritical_Transition, | |||
100 | inPlanet, | |||
101 | inDefault_Body_Method, | |||
102 | inDefault_Wing_Method, | |||
103 | inDefault_Low_Speed_Method, | |||
104 | inLeading_Edge_Suction, | |||
105 | inAero_Surface, | |||
106 | inMesh_Morph, | |||
107 | inSurface_Mesh, | |||
108 | NUMINPUT = inSurface_Mesh /* Total number of inputs */ | |||
109 | }; | |||
110 | ||||
111 | enum aimOutputs | |||
112 | { | |||
113 | outBeta = 1, /* index is 1-based */ | |||
114 | outAlpha, | |||
115 | outDynamic_Pressure, | |||
116 | outMach, | |||
117 | outPerTrb, | |||
118 | outCLtot, | |||
119 | outCDtot, | |||
120 | outCMYtot, | |||
121 | outLoDtot, | |||
122 | outCL_p, | |||
123 | outCD_p, | |||
124 | outCL_v, | |||
125 | outCD_v, | |||
126 | outStagnation_Temperature, | |||
127 | outStagnation_Radius, | |||
128 | outConvective_Flux, | |||
129 | outRadiative_Flux, | |||
130 | outCL_Trefftz, | |||
131 | outCD_Trefftz, | |||
132 | NUMOUTPUT = outCD_Trefftz /* Total number of outputs */ | |||
133 | }; | |||
134 | ||||
135 | #define MXCHAR255 255 | |||
136 | ||||
137 | //#define DEBUG | |||
138 | ||||
139 | typedef struct { | |||
140 | ||||
141 | // Attribute to index map | |||
142 | mapAttrToIndexStruct groupMap; | |||
143 | ||||
144 | // Project name | |||
145 | char *projectName; | |||
146 | ||||
147 | double Sref, Cref, Bref, Xref, Yref, Zref; | |||
148 | ||||
149 | // Mesh reference obtained from meshing AIM | |||
150 | aimMeshRef *meshRefIn, meshRefObj; | |||
151 | ||||
152 | } aimStorage; | |||
153 | ||||
154 | ||||
155 | static int initialize_aimStorage(aimStorage *cbaeroInstance) { | |||
156 | ||||
157 | int status; | |||
158 | ||||
159 | // Set initial values for cbaeroInstance | |||
160 | cbaeroInstance->projectName = NULL((void*)0); | |||
161 | ||||
162 | // Container for attribute to index map | |||
163 | status = initiate_mapAttrToIndexStruct(&cbaeroInstance->groupMap); | |||
164 | if (status != CAPS_SUCCESS0) return status; | |||
165 | ||||
166 | cbaeroInstance->meshRefIn = NULL((void*)0); | |||
167 | aim_initMeshRef(&cbaeroInstance->meshRefObj, aimUnknownMeshType); | |||
168 | ||||
169 | cbaeroInstance->Sref = 0; | |||
170 | cbaeroInstance->Cref = 0; | |||
171 | cbaeroInstance->Bref = 0; | |||
172 | cbaeroInstance->Xref = 0; | |||
173 | cbaeroInstance->Yref = 0; | |||
174 | cbaeroInstance->Zref = 0; | |||
175 | ||||
176 | return status; | |||
177 | } | |||
178 | ||||
179 | ||||
180 | static int destroy_aimStorage(aimStorage *cbaeroInstance) { | |||
181 | ||||
182 | int status; | |||
183 | ||||
184 | // projectName is just a reference | |||
185 | cbaeroInstance->projectName = NULL((void*)0); | |||
186 | ||||
187 | // Attribute to index map | |||
188 | status = destroy_mapAttrToIndexStruct(&cbaeroInstance->groupMap); | |||
189 | ||||
190 | // Surface Mesh | |||
191 | aim_freeMeshRef(&cbaeroInstance->meshRefObj); | |||
192 | cbaeroInstance->meshRefIn = NULL((void*)0); | |||
193 | ||||
194 | cbaeroInstance->Sref = 0; | |||
195 | cbaeroInstance->Cref = 0; | |||
196 | cbaeroInstance->Bref = 0; | |||
197 | cbaeroInstance->Xref = 0; | |||
198 | cbaeroInstance->Yref = 0; | |||
199 | cbaeroInstance->Zref = 0; | |||
200 | ||||
201 | return status; | |||
202 | } | |||
203 | ||||
204 | ||||
205 | static int cbaero_selectFlow(void *aimInfo, char * string) { | |||
206 | int value; | |||
207 | enum cbearoFlowTypeEnum {cbFreeTransition=0, cbLaminar=1, cbTurbulent=2, cbInviscid=3}; | |||
208 | ||||
209 | if (strcasecmp(string, "FreeTransition") == 0 || strcasecmp(string, "0") == 0) value = cbFreeTransition; | |||
210 | else if (strcasecmp(string, "Laminar") == 0 || strcasecmp(string, "1") == 0) value = cbLaminar; | |||
211 | else if (strcasecmp(string, "Turbulent") == 0 || strcasecmp(string, "2") == 0) value = cbTurbulent; | |||
212 | else if (strcasecmp(string, "Inviscid") == 0 || strcasecmp(string, "3") == 0) value = cbInviscid; | |||
213 | else { | |||
214 | AIM_ERROR(aimInfo, "Invalid flow type, %s, options: FreeTransition, Laminar, Turbulent, Inviscid!", string){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 214, __func__ , "Invalid flow type, %s, options: FreeTransition, Laminar, Turbulent, Inviscid!" , string); }; | |||
215 | value = CAPS_NOTFOUND-303; | |||
216 | } | |||
217 | return value; | |||
218 | } | |||
219 | ||||
220 | static int cbaero_selectHighSpeed(void *aimInfo, char * string) { | |||
221 | int value; | |||
222 | enum cbearoAeroHighMethodEnum {Base=0, ModifiedNewtonian=3, TangentCone=21, TangentConeNormalShock=22, TangentWedge=31, TangentWedgeNormalShock=32, FreeMolecular=99}; | |||
223 | ||||
224 | if (strcasecmp(string, "ModifiedNewtonian") == 0) value = ModifiedNewtonian; | |||
225 | else if (strcasecmp(string, "TangentCone") == 0) value = TangentCone; | |||
226 | else if (strcasecmp(string, "TangentConeNormalShock") == 0) value = TangentConeNormalShock; | |||
227 | else if (strcasecmp(string, "TangentWedge") == 0) value = TangentWedge; | |||
228 | else if (strcasecmp(string, "TangentWedgeNormalShock")== 0) value = TangentWedgeNormalShock; | |||
229 | else if (strcasecmp(string, "FreeMolecular") == 0) value = FreeMolecular; | |||
230 | else if (strcasecmp(string, "Base") == 0) value = Base; | |||
231 | else { | |||
232 | AIM_ERROR(aimInfo, "Invalid high speed method, %s, options: ModifiedNewtonian, TangentCone, TangentConeNormalShock, TangentWedge, TangentWedgeNormalShock, FreeMolecular!\n", string){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 232, __func__ , "Invalid high speed method, %s, options: ModifiedNewtonian, TangentCone, TangentConeNormalShock, TangentWedge, TangentWedgeNormalShock, FreeMolecular!\n" , string); }; | |||
233 | value = CAPS_NOTFOUND-303; | |||
234 | } | |||
235 | return value; | |||
236 | } | |||
237 | ||||
238 | static int cbaero_selectLowSpeed(void *aimInfo, char * string) { | |||
239 | int value; | |||
240 | enum cbearoAeroLowMethodEnum {FastPanel=1, LowAR=2}; | |||
241 | ||||
242 | if (strcasecmp(string, "FastPanel") == 0) value = FastPanel; | |||
243 | else if (strcasecmp(string, "LowAR") == 0) value = LowAR; | |||
244 | else { | |||
245 | AIM_ERROR(aimInfo, "Invalid low speed method, %s, options: FastPanel, TangLowARentCone!", string){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 245, __func__ , "Invalid low speed method, %s, options: FastPanel, TangLowARentCone!" , string); }; | |||
246 | value = CAPS_NOTFOUND-303; | |||
247 | } | |||
248 | return value; | |||
249 | } | |||
250 | ||||
251 | static int cbearo_writeTag(void *aimInfo, const char *projectName, | |||
252 | const mapAttrToIndexStruct *groupMap, aimMeshRef *meshRef) { | |||
253 | int status; // Function status return | |||
254 | ||||
255 | int i, j; // Indexing | |||
256 | ||||
257 | char filename[PATH_MAX4096]; | |||
258 | ||||
259 | int state, nglobal; | |||
260 | ego body; | |||
261 | ||||
262 | int itri; | |||
263 | int iface, nFace; | |||
264 | ego *efaces=NULL((void*)0); | |||
265 | ||||
266 | int plen, tlen; | |||
267 | const double *points, *uv; | |||
268 | const int *ptypes, *pindexs, *tris, *tric; | |||
269 | const char *groupName = NULL((void*)0); | |||
270 | int groupIndex, elementID = 1; | |||
271 | ||||
272 | char tagFolder[] = "TaggedRegions"; | |||
273 | char tagExt[] = ".tag"; | |||
274 | char tagAll[] = ".ALL.taglist"; | |||
275 | ||||
276 | FILE *fp = NULL((void*)0); | |||
277 | ||||
278 | int numTagElement = 0; | |||
279 | int *tagElement=NULL((void*)0); | |||
280 | FILE **tagFiles=NULL((void*)0); | |||
281 | ||||
282 | printf("Writing CBAero tagged regions - %s\n", tagFolder); | |||
283 | ||||
284 | // Determine number of elements that have a given index | |||
285 | numTagElement = groupMap->numAttribute; | |||
286 | AIM_ALLOC(tagElement, numTagElement, int, aimInfo, status){ if (tagElement != ((void*)0)) { status = -4; aim_status(aimInfo , status, "cbaeroAIM.c", 286, __func__, 1, "AIM_ALLOC: %s != NULL" , "tagElement"); goto cleanup; } size_t memorysize = numTagElement ; tagElement = (int *) EG_alloc(memorysize*sizeof(int)); if ( tagElement == ((void*)0)) { status = -4; aim_status(aimInfo, status , "cbaeroAIM.c", 286, __func__, 3, "AIM_ALLOC: %s size %zu type %s" , "tagElement", memorysize, "int"); goto cleanup; } }; | |||
287 | for (i = 0; i < numTagElement; i++) tagElement[i] = 0; | |||
288 | ||||
289 | // Figure out how many elements for each tag | |||
290 | for (i = 0; i < meshRef->nmap; i++) { | |||
291 | status = EG_statusTessBody(meshRef->maps[i].tess, &body, &state, &nglobal); | |||
292 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 292, __func__, 0); goto cleanup; }; | |||
293 | ||||
294 | status = EG_getBodyTopos(body, NULL((void*)0), FACE23, &nFace, &efaces); | |||
295 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 295, __func__, 0); goto cleanup; }; | |||
296 | AIM_NOTNULL(efaces, aimInfo, status){ if (efaces == ((void*)0)) { status = -307; aim_status(aimInfo , status, "cbaeroAIM.c", 296, __func__, 1, "%s == NULL!", "efaces" ); goto cleanup; } }; | |||
297 | ||||
298 | for (iface = 0; iface < nFace; iface++) { | |||
299 | status = EG_getTessFace(meshRef->maps[i].tess, iface + 1, &plen, &points, &uv, &ptypes, &pindexs, | |||
300 | &tlen, &tris, &tric); | |||
301 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 301, __func__, 0); goto cleanup; }; | |||
302 | ||||
303 | status = retrieve_CAPSGroupAttr(efaces[iface], &groupName); | |||
304 | AIM_STATUS (aimInfo, status )if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 304, __func__, 0); goto cleanup; }; | |||
305 | AIM_NOTNULL(groupName, aimInfo, status){ if (groupName == ((void*)0)) { status = -307; aim_status(aimInfo , status, "cbaeroAIM.c", 305, __func__, 1, "%s == NULL!", "groupName" ); goto cleanup; } }; | |||
306 | status = get_mapAttrToIndexIndex(groupMap, groupName, &groupIndex); | |||
307 | if (status != CAPS_SUCCESS0) { | |||
308 | AIM_ERROR(aimInfo, "No capsGroup \"%s\" not found in attribute map", groupName){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 308, __func__ , "No capsGroup \"%s\" not found in attribute map", groupName ); }; | |||
309 | AIM_ADDLINE(aimInfo, "Available capsGroup attributes:"){ aim_addLine(aimInfo, "Available capsGroup attributes:"); }; | |||
310 | for (j = 0; j < groupMap->numAttribute; j++) { | |||
311 | AIM_ADDLINE(aimInfo, "\t%s", groupMap->attributeName[j]){ aim_addLine(aimInfo, "\t%s", groupMap->attributeName[j]) ; }; | |||
312 | } | |||
313 | goto cleanup; | |||
314 | } | |||
315 | ||||
316 | tagElement[groupIndex-1] += tlen; | |||
317 | } | |||
318 | AIM_FREE(efaces){ EG_free(efaces); efaces = ((void*)0); }; | |||
319 | } | |||
320 | ||||
321 | // Write tagged files | |||
322 | // Folder - TaggedRegions | |||
323 | // File - "ProjectName".ALL.taglist | |||
324 | // -- contains a list of all files in folder | |||
325 | // --- #numElement projectname.tagName | |||
326 | /// --- ...... | |||
327 | // File - "projectname.tagName.tag" | |||
328 | // -- #numElement | |||
329 | // -- elementID | |||
330 | // -- .... | |||
331 | ||||
332 | // TaggedRegions folder | |||
333 | status = aim_mkDir(aimInfo, tagFolder); | |||
334 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 334, __func__, 0); goto cleanup; }; | |||
335 | ||||
336 | // ALL.taglist | |||
337 | #ifdef WIN32 | |||
338 | snprintf(filename, PATH_MAX4096, "%s\\%s%s", tagFolder, projectName, tagAll); | |||
339 | #else | |||
340 | snprintf(filename, PATH_MAX4096, "%s/%s%s", tagFolder, projectName, tagAll); | |||
341 | #endif | |||
342 | ||||
343 | fp = aim_fopen(aimInfo, filename, "w"); | |||
344 | if (fp == NULL((void*)0)) { | |||
345 | AIM_ERROR(aimInfo, "Unable to open file: %s", filename){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 345, __func__ , "Unable to open file: %s", filename); }; | |||
346 | status = CAPS_IOERR-332; | |||
347 | goto cleanup; | |||
348 | } | |||
349 | ||||
350 | for (i = 0; i < groupMap->numAttribute; i++) { | |||
351 | fprintf(fp, "%d %s.%s", tagElement[i], projectName, groupMap->attributeName[i]); | |||
352 | if (i-1 != groupMap->numAttribute) fprintf(fp, "\n"); | |||
353 | } | |||
354 | ||||
355 | if (fp != NULL((void*)0)) fclose(fp); | |||
356 | fp = NULL((void*)0); | |||
357 | ||||
358 | // Write tag files | |||
359 | /*@+voidabstract@*/ | |||
360 | AIM_ALLOC(tagFiles, numTagElement, FILE*, aimInfo, status){ if (tagFiles != ((void*)0)) { status = -4; aim_status(aimInfo , status, "cbaeroAIM.c", 360, __func__, 1, "AIM_ALLOC: %s != NULL" , "tagFiles"); goto cleanup; } size_t memorysize = numTagElement ; tagFiles = (FILE* *) EG_alloc(memorysize*sizeof(FILE*)); if (tagFiles == ((void*)0)) { status = -4; aim_status(aimInfo, status , "cbaeroAIM.c", 360, __func__, 3, "AIM_ALLOC: %s size %zu type %s" , "tagFiles", memorysize, "FILE*"); goto cleanup; } }; | |||
361 | /*@-voidabstract@*/ | |||
362 | for (i = 0; i < numTagElement; i++) tagFiles[i] = NULL((void*)0); | |||
363 | ||||
364 | for (i = 0; i < numTagElement; i++ ) { | |||
365 | ||||
366 | #ifdef WIN32 | |||
367 | snprintf(filename, PATH_MAX4096, "%s\\%s.%s%s", tagFolder, projectName, groupMap->attributeName[i], tagExt); | |||
368 | #else | |||
369 | snprintf(filename, PATH_MAX4096, "%s/%s.%s%s", tagFolder, projectName, groupMap->attributeName[i], tagExt); | |||
370 | #endif | |||
371 | ||||
372 | tagFiles[i] = aim_fopen(aimInfo, filename, "w"); | |||
373 | if (tagFiles[i] == NULL((void*)0)) { | |||
374 | AIM_ERROR(aimInfo, "Unable to open file: %s", filename){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 374, __func__ , "Unable to open file: %s", filename); }; | |||
375 | status = CAPS_IOERR-332; | |||
376 | goto cleanup; | |||
377 | } | |||
378 | } | |||
379 | ||||
380 | // Write total number of elements in tag files | |||
381 | for (i = 0; i < numTagElement; i++ ) { | |||
382 | fprintf(tagFiles[i], "%d\n", tagElement[i]); | |||
383 | } | |||
384 | ||||
385 | // Write element indexes to tag files | |||
386 | for (i = 0; i < meshRef->nmap; i++) { | |||
387 | status = EG_statusTessBody(meshRef->maps[i].tess, &body, &state, &nglobal); | |||
388 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 388, __func__, 0); goto cleanup; }; | |||
389 | ||||
390 | status = EG_getBodyTopos(body, NULL((void*)0), FACE23, &nFace, &efaces); | |||
391 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 391, __func__, 0); goto cleanup; }; | |||
392 | AIM_NOTNULL(efaces, aimInfo, status){ if (efaces == ((void*)0)) { status = -307; aim_status(aimInfo , status, "cbaeroAIM.c", 392, __func__, 1, "%s == NULL!", "efaces" ); goto cleanup; } }; | |||
393 | ||||
394 | for (iface = 0; iface < nFace; iface++) { | |||
395 | status = EG_getTessFace(meshRef->maps[i].tess, iface + 1, &plen, &points, &uv, &ptypes, &pindexs, | |||
396 | &tlen, &tris, &tric); | |||
397 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 397, __func__, 0); goto cleanup; }; | |||
398 | ||||
399 | status = retrieve_CAPSGroupAttr(efaces[iface], &groupName); | |||
400 | AIM_STATUS (aimInfo, status )if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 400, __func__, 0); goto cleanup; }; | |||
401 | AIM_NOTNULL(groupName, aimInfo, status){ if (groupName == ((void*)0)) { status = -307; aim_status(aimInfo , status, "cbaeroAIM.c", 401, __func__, 1, "%s == NULL!", "groupName" ); goto cleanup; } }; | |||
402 | status = get_mapAttrToIndexIndex(groupMap, groupName, &groupIndex); | |||
403 | if (status != CAPS_SUCCESS0) { | |||
404 | AIM_ERROR(aimInfo, "No capsGroup \"%s\" not found in attribute map", groupName){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 404, __func__ , "No capsGroup \"%s\" not found in attribute map", groupName ); }; | |||
405 | goto cleanup; | |||
406 | } | |||
407 | ||||
408 | for (itri = 0; itri < tlen; itri++, elementID++) | |||
409 | fprintf(tagFiles[groupIndex-1], "%d\n", elementID); | |||
410 | } | |||
411 | AIM_FREE(efaces){ EG_free(efaces); efaces = ((void*)0); }; | |||
412 | } | |||
413 | ||||
414 | status = CAPS_SUCCESS0; | |||
415 | ||||
416 | cleanup: | |||
417 | ||||
418 | AIM_FREE(tagElement){ EG_free(tagElement); tagElement = ((void*)0); }; | |||
419 | AIM_FREE(efaces){ EG_free(efaces); efaces = ((void*)0); }; | |||
420 | ||||
421 | if (tagFiles != NULL((void*)0)) { | |||
422 | for (i = 0; i < numTagElement; i++) if (tagFiles[i] != NULL((void*)0)) fclose(tagFiles[i]); | |||
423 | AIM_FREE(tagFiles){ EG_free(tagFiles); tagFiles = ((void*)0); }; | |||
424 | } | |||
425 | ||||
426 | return status; | |||
427 | } | |||
428 | ||||
429 | static void write_InputArray(enum aimInputs varName, FILE *fp, capsValue *aimInputs) { | |||
430 | ||||
431 | int i; // Indexing | |||
432 | ||||
433 | double value; | |||
434 | ||||
435 | fprintf(fp,"%d\n", aimInputs[varName-1].length); | |||
436 | for (i = 0; i < aimInputs[varName-1].length; i++) { | |||
437 | ||||
438 | if (aimInputs[varName-1].length == 1) { | |||
439 | ||||
440 | value = aimInputs[varName-1].vals.real; | |||
441 | ||||
442 | } else { | |||
443 | value = aimInputs[varName-1].vals.reals[i]; | |||
444 | } | |||
445 | ||||
446 | if (i+1 == aimInputs[varName-1].length){ | |||
447 | fprintf(fp, "%.18e", value); // No space afterwards | |||
448 | ||||
449 | } else { | |||
450 | fprintf(fp, "%.18e ", value); | |||
451 | ||||
452 | } | |||
453 | } | |||
454 | ||||
455 | fprintf(fp, "\n"); | |||
456 | } | |||
457 | ||||
458 | static int cbaero_writeInput(void *aimInfo, const aimStorage *cbaeroInstance, capsValue *aimInputs) | |||
459 | { | |||
460 | ||||
461 | int status; // Function return status | |||
462 | char filename[PATH_MAX4096]; | |||
463 | ||||
464 | FILE *fp = NULL((void*)0); | |||
465 | char fileExt[] = ".cbaero"; | |||
466 | ||||
467 | printf("Writing CBAero input file - %s%s\n", cbaeroInstance->projectName, fileExt); | |||
468 | ||||
469 | snprintf(filename, PATH_MAX4096, "%s%s", cbaeroInstance->projectName, fileExt); | |||
470 | ||||
471 | fp = aim_fopen(aimInfo, filename, "w"); | |||
472 | if (fp == NULL((void*)0)) { | |||
473 | AIM_ERROR(aimInfo, "Unable to open file: %s", filename){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 473, __func__ , "Unable to open file: %s", filename); }; | |||
474 | status = CAPS_IOERR-332; | |||
475 | goto cleanup; | |||
476 | } | |||
477 | ||||
478 | // Mesh format | |||
479 | fprintf(fp, "FileType = fast\n"); | |||
480 | ||||
481 | // Reference values | |||
482 | fprintf(fp, "Sref = %.18e\n", cbaeroInstance->Sref); | |||
483 | fprintf(fp, "Cref = %.18e\n", cbaeroInstance->Cref); | |||
484 | fprintf(fp, "Bref = %.18e\n", cbaeroInstance->Bref); | |||
485 | ||||
486 | fprintf(fp, "X_cg = %.18e\n", cbaeroInstance->Xref); | |||
487 | fprintf(fp, "Y_cg = %.18e\n", cbaeroInstance->Yref); | |||
488 | fprintf(fp, "Z_cg = %.18e\n", cbaeroInstance->Zref); | |||
489 | ||||
490 | fprintf(fp, "scale = %.18e\n", 1.0); | |||
491 | ||||
492 | status = cbaero_selectFlow(aimInfo, aimInputs[inFlow_Type-1].vals.string); | |||
493 | if (status < CAPS_SUCCESS0) AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 493, __func__, 0); goto cleanup; }; | |||
494 | fprintf(fp, "flotyp = %d\n", status); | |||
495 | ||||
496 | fprintf(fp, "retm_c = %.18e\n", aimInputs[inCritical_Transition-1].vals.real); | |||
497 | fprintf(fp, "retm_t = %.18e\n", 0.0); | |||
498 | fprintf(fp, "strm_line_dt = %.18e\n", 0.25); | |||
499 | ||||
500 | fprintf(fp, "Planet = %s\n", aimInputs[inPlanet-1].vals.string); | |||
501 | ||||
502 | fprintf(fp, "Mach Number\n"); | |||
503 | (void) write_InputArray(inMach, fp, aimInputs); | |||
504 | ||||
505 | fprintf(fp, "Dynamic Pressure (Bars)\n"); | |||
506 | (void) write_InputArray(inDynamic_Pressure, fp, aimInputs); | |||
507 | ||||
508 | fprintf(fp, "Angle of Attack\n"); | |||
509 | (void) write_InputArray(inAlpha, fp, aimInputs); | |||
510 | ||||
511 | fprintf(fp, "Angle of SideSlip\n"); | |||
512 | (void) write_InputArray(inBeta, fp, aimInputs); | |||
513 | ||||
514 | //fprintf(fp, "Control Surfaces\n"); | |||
515 | //fprintf(fp, "%d\n", 0); | |||
516 | ||||
517 | status = CAPS_SUCCESS0; | |||
518 | ||||
519 | cleanup: | |||
520 | ||||
521 | if (fp != NULL((void*)0)) fclose(fp); | |||
522 | ||||
523 | return status; | |||
524 | } | |||
525 | ||||
526 | static int cbaero_appendSetupControl(FILE *fp, /*@unused@*/ aimMeshRef *meshRef, /*@unused@*/ const mapAttrToIndexStruct *groupMap){//, int numTuple, capsTuple controlTuple[]) { | |||
527 | ||||
528 | int status; | |||
529 | ||||
530 | fprintf(fp,"Control Surfaces:\n"); | |||
531 | fprintf(fp,"0\n"); | |||
532 | ||||
533 | status = CAPS_SUCCESS0; | |||
534 | ||||
535 | //cleanup: | |||
536 | return status; | |||
537 | } | |||
538 | ||||
539 | ||||
540 | static int cbaero_appendSetupAero(void *aimInfo, FILE *fp, aimMeshRef *meshRef, | |||
541 | const mapAttrToIndexStruct *groupMap, | |||
542 | int numTuple, capsTuple *panelTuple, | |||
543 | char *bodyMethod, char *wingMethod) { | |||
544 | ||||
545 | int status; // Status return | |||
546 | ||||
547 | int i, j; // Indexing | |||
548 | ||||
549 | int index; | |||
550 | int value, value2; | |||
551 | ||||
552 | int state, nglobal, nTri = 0; | |||
553 | ego body; | |||
554 | ||||
555 | int itri; | |||
556 | int iface, nFace; | |||
557 | ego *efaces=NULL((void*)0); | |||
558 | ||||
559 | int plen, tlen; | |||
560 | const double *points, *uv; | |||
561 | const int *ptypes, *pindexs, *tris, *tric; | |||
562 | const char *groupName = NULL((void*)0); | |||
563 | char *tupleValue = NULL((void*)0); | |||
| ||||
564 | int groupIndex, elementID = 1; | |||
565 | ||||
566 | enum cbearoAeroSurfaceIndexEnum {Body=1010, Base=1030, Wing=1020, Inlet=9000, Cowl=11000, Nozzle=10000}; | |||
567 | ||||
568 | int numBaseTri = 0; | |||
569 | int *baseTri = NULL((void*)0); | |||
570 | ||||
571 | for (i = 0; i < meshRef->nmap; i++) { | |||
572 | status = EG_statusTessBody(meshRef->maps[i].tess, &body, &state, &nglobal); | |||
573 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 573, __func__, 0); goto cleanup; }; | |||
574 | ||||
575 | status = EG_getBodyTopos(body, NULL((void*)0), FACE23, &nFace, NULL((void*)0)); | |||
576 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 576, __func__, 0); goto cleanup; }; | |||
577 | ||||
578 | for (iface = 0; iface < nFace; iface++) { | |||
579 | status = EG_getTessFace(meshRef->maps[i].tess, iface + 1, &plen, &points, &uv, &ptypes, &pindexs, | |||
580 | &tlen, &tris, &tric); | |||
581 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 581, __func__, 0); goto cleanup; }; | |||
582 | ||||
583 | nTri += tlen; | |||
584 | } | |||
585 | } | |||
586 | ||||
587 | ||||
588 | AIM_ALLOC(baseTri, nTri, int, aimInfo, status){ if (baseTri != ((void*)0)) { status = -4; aim_status(aimInfo , status, "cbaeroAIM.c", 588, __func__, 1, "AIM_ALLOC: %s != NULL" , "baseTri"); goto cleanup; } size_t memorysize = nTri; baseTri = (int *) EG_alloc(memorysize*sizeof(int)); if (baseTri == ( (void*)0)) { status = -4; aim_status(aimInfo, status, "cbaeroAIM.c" , 588, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "baseTri" , memorysize, "int"); goto cleanup; } }; | |||
589 | for (i = 0; i < nTri; i++) baseTri[i] = 0; | |||
590 | ||||
591 | fprintf(fp, "Independent Panel Method flags:\n"); | |||
592 | ||||
593 | for (i = 0; i
| |||
594 | status = EG_statusTessBody(meshRef->maps[i].tess, &body, &state, &nglobal); | |||
595 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 595, __func__, 0); goto cleanup; }; | |||
596 | ||||
597 | status = EG_getBodyTopos(body, NULL((void*)0), FACE23, &nFace, &efaces); | |||
598 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 598, __func__, 0); goto cleanup; }; | |||
599 | AIM_NOTNULL(efaces, aimInfo, status){ if (efaces == ((void*)0)) { status = -307; aim_status(aimInfo , status, "cbaeroAIM.c", 599, __func__, 1, "%s == NULL!", "efaces" ); goto cleanup; } }; | |||
600 | ||||
601 | for (iface = 0; iface < nFace; iface++) { | |||
602 | status = EG_getTessFace(meshRef->maps[i].tess, iface + 1, &plen, &points, &uv, &ptypes, &pindexs, | |||
603 | &tlen, &tris, &tric); | |||
604 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 604, __func__, 0); goto cleanup; }; | |||
605 | ||||
606 | status = retrieve_CAPSGroupAttr(efaces[iface], &groupName); | |||
607 | AIM_STATUS (aimInfo, status )if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 607, __func__, 0); goto cleanup; }; | |||
608 | AIM_NOTNULL(groupName, aimInfo, status){ if (groupName == ((void*)0)) { status = -307; aim_status(aimInfo , status, "cbaeroAIM.c", 608, __func__, 1, "%s == NULL!", "groupName" ); goto cleanup; } }; | |||
609 | status = get_mapAttrToIndexIndex(groupMap, groupName, &groupIndex); | |||
610 | if (status != CAPS_SUCCESS0) { | |||
611 | AIM_ERROR(aimInfo, "No capsGroup \"%s\" not found in attribute map", groupName){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 611, __func__ , "No capsGroup \"%s\" not found in attribute map", groupName ); }; | |||
612 | goto cleanup; | |||
613 | } | |||
614 | ||||
615 | index = CAPSMAGIC1234321; | |||
616 | for (j = 0; j < numTuple; j++) { | |||
617 | status = get_mapAttrToIndexIndex(groupMap, panelTuple[j].name, &index); | |||
618 | if (status != CAPS_SUCCESS0) { | |||
619 | AIM_ERROR(aimInfo, "Attribute name '%s' not found in capsGroup map!\n", panelTuple[j].name){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 619, __func__ , "Attribute name '%s' not found in capsGroup map!\n", panelTuple [j].name); }; | |||
620 | goto cleanup; | |||
621 | } | |||
622 | if (groupIndex == index) { | |||
623 | tupleValue = string_removeQuotation(panelTuple[j].value); | |||
624 | break; | |||
625 | } | |||
626 | } | |||
627 | ||||
628 | if (index == CAPSMAGIC1234321) value = cbaero_selectHighSpeed(aimInfo, bodyMethod); // Default to Body | |||
629 | else if (strcasecmp(tupleValue, "Body") == 0) value = cbaero_selectHighSpeed(aimInfo, bodyMethod); | |||
630 | else if (strcasecmp(tupleValue, "Base") == 0) { | |||
631 | for (itri = 0; itri < tlen; itri++) { | |||
632 | baseTri[numBaseTri+itri] = elementID + itri; | |||
633 | } | |||
634 | numBaseTri += tlen; | |||
635 | value = cbaero_selectHighSpeed(aimInfo, "Base"); | |||
636 | } | |||
637 | else if (strcasecmp(tupleValue, "Wing") == 0) value = cbaero_selectHighSpeed(aimInfo, wingMethod); | |||
638 | else if (strcasecmp(tupleValue, "Inlet") == 0) value = cbaero_selectHighSpeed(aimInfo, bodyMethod); | |||
639 | else if (strcasecmp(tupleValue, "Cowl") == 0) value = cbaero_selectHighSpeed(aimInfo, bodyMethod); | |||
640 | else if (strcasecmp(tupleValue, "Nozzle")== 0) value = cbaero_selectHighSpeed(aimInfo, bodyMethod); | |||
641 | else { | |||
642 | AIM_ERROR(aimInfo, "Invalid aero. type, '%s', options: Body, Base, Wing, Inlet, Cowl, Nozzle!", panelTuple[j].value){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 642, __func__ , "Invalid aero. type, '%s', options: Body, Base, Wing, Inlet, Cowl, Nozzle!" , panelTuple[j].value); }; | |||
643 | status = CAPS_NOTFOUND-303; | |||
644 | goto cleanup; | |||
645 | } | |||
646 | AIM_FREE(tupleValue){ EG_free(tupleValue); tupleValue = ((void*)0); }; | |||
647 | ||||
648 | if (value < 0) { | |||
649 | status = value; | |||
650 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 650, __func__, 0); goto cleanup; }; | |||
651 | } | |||
652 | ||||
653 | for (itri = 0; itri < tlen; itri++) { | |||
654 | fprintf(fp,"%d\n", value); | |||
655 | } | |||
656 | elementID += tlen; | |||
657 | } | |||
658 | AIM_FREE(efaces){ EG_free(efaces); efaces = ((void*)0); }; | |||
659 | } | |||
660 | ||||
661 | ||||
662 | // Groups | |||
663 | fprintf(fp,"%d\n", groupMap->numAttribute); // Number of groups | |||
664 | for (i = 0; i < groupMap->numAttribute; i++) { | |||
665 | ||||
666 | index = CAPSMAGIC1234321; | |||
667 | for (j = 0; j < numTuple; j++) { | |||
668 | ||||
669 | status = get_mapAttrToIndexIndex(groupMap, panelTuple[j].name, &index); | |||
670 | if (status != CAPS_SUCCESS0) { | |||
671 | AIM_ERROR(aimInfo, "Attribute name '%s' not found in capsGroup map!\n", panelTuple[j].name){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 671, __func__ , "Attribute name '%s' not found in capsGroup map!\n", panelTuple [j].name); }; | |||
672 | goto cleanup; | |||
673 | } | |||
674 | if (groupMap->attributeIndex[i] == index) { | |||
675 | tupleValue = string_removeQuotation(panelTuple[j].value); | |||
676 | break; | |||
677 | } | |||
678 | } | |||
679 | ||||
680 | if (index == CAPSMAGIC1234321) { | |||
681 | value2 = Body; | |||
682 | value = cbaero_selectHighSpeed(aimInfo, bodyMethod); // Default to Body | |||
683 | } else if (strcasecmp(tupleValue, "Body") == 0) { | |||
| ||||
684 | value2 = Body; | |||
685 | value = cbaero_selectHighSpeed(aimInfo, bodyMethod); | |||
686 | } else if (strcasecmp(tupleValue, "Base") == 0) { | |||
687 | value2 = Base; | |||
688 | value = cbaero_selectHighSpeed(aimInfo, "Base"); | |||
689 | } else if (strcasecmp(tupleValue, "Wing") == 0) { | |||
690 | value2 = Wing; | |||
691 | value = cbaero_selectHighSpeed(aimInfo, wingMethod); | |||
692 | } else if (strcasecmp(tupleValue, "Inlet") == 0) { | |||
693 | value2 = Inlet; | |||
694 | value = cbaero_selectHighSpeed(aimInfo, bodyMethod); | |||
695 | } else if (strcasecmp(tupleValue, "Cowl") == 0) { | |||
696 | value2 = Cowl; | |||
697 | value = cbaero_selectHighSpeed(aimInfo, bodyMethod); | |||
698 | } else if (strcasecmp(tupleValue, "Nozzle")== 0) { | |||
699 | value2 = Nozzle; | |||
700 | value = cbaero_selectHighSpeed(aimInfo, bodyMethod); | |||
701 | } else { | |||
702 | AIM_ERROR(aimInfo, "Invalid aero. type, '%s', options: Body, Base, Wing, Inlet, Cowl, Nozzle!\n", panelTuple[j].value){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 702, __func__ , "Invalid aero. type, '%s', options: Body, Base, Wing, Inlet, Cowl, Nozzle!\n" , panelTuple[j].value); }; | |||
703 | status = CAPS_NOTFOUND-303; | |||
704 | goto cleanup; | |||
705 | } | |||
706 | AIM_FREE(tupleValue){ EG_free(tupleValue); tupleValue = ((void*)0); }; | |||
707 | ||||
708 | if (value < 0) { | |||
709 | status = value; | |||
710 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 710, __func__, 0); goto cleanup; }; | |||
711 | } | |||
712 | ||||
713 | fprintf(fp, "%d\n", value2); // cbearoAeroSurfaceIndexEnum | |||
714 | fprintf(fp, "%s\n", groupMap->attributeName[i]); | |||
715 | fprintf(fp, "%d\n", value); | |||
716 | } | |||
717 | ||||
718 | // Surface IDs - Which group | |||
719 | fprintf(fp,"Surface IDs\n"); | |||
720 | for (i = 0; i < meshRef->nmap; i++) { | |||
721 | status = EG_statusTessBody(meshRef->maps[i].tess, &body, &state, &nglobal); | |||
722 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 722, __func__, 0); goto cleanup; }; | |||
723 | ||||
724 | status = EG_getBodyTopos(body, NULL((void*)0), FACE23, &nFace, &efaces); | |||
725 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 725, __func__, 0); goto cleanup; }; | |||
726 | AIM_NOTNULL(efaces, aimInfo, status){ if (efaces == ((void*)0)) { status = -307; aim_status(aimInfo , status, "cbaeroAIM.c", 726, __func__, 1, "%s == NULL!", "efaces" ); goto cleanup; } }; | |||
727 | ||||
728 | for (iface = 0; iface < nFace; iface++) { | |||
729 | status = EG_getTessFace(meshRef->maps[i].tess, iface + 1, &plen, &points, &uv, &ptypes, &pindexs, | |||
730 | &tlen, &tris, &tric); | |||
731 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 731, __func__, 0); goto cleanup; }; | |||
732 | ||||
733 | status = retrieve_CAPSGroupAttr(efaces[iface], &groupName); | |||
734 | AIM_STATUS (aimInfo, status )if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 734, __func__, 0); goto cleanup; }; | |||
735 | AIM_NOTNULL(groupName, aimInfo, status){ if (groupName == ((void*)0)) { status = -307; aim_status(aimInfo , status, "cbaeroAIM.c", 735, __func__, 1, "%s == NULL!", "groupName" ); goto cleanup; } }; | |||
736 | status = get_mapAttrToIndexIndex(groupMap, groupName, &groupIndex); | |||
737 | if (status != CAPS_SUCCESS0) { | |||
738 | AIM_ERROR(aimInfo, "No capsGroup \"%s\" not found in attribute map", groupName){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 738, __func__ , "No capsGroup \"%s\" not found in attribute map", groupName ); }; | |||
739 | goto cleanup; | |||
740 | } | |||
741 | ||||
742 | for (itri = 0; itri < tlen; itri++) | |||
743 | fprintf(fp, "%d\n", groupIndex); | |||
744 | } | |||
745 | AIM_FREE(efaces){ EG_free(efaces); efaces = ((void*)0); }; | |||
746 | } | |||
747 | ||||
748 | // Base Triangles | |||
749 | fprintf(fp,"Base Triangles:\n"); | |||
750 | fprintf(fp, "%d\n", numBaseTri); | |||
751 | for (i = 0; i < numBaseTri; i++) { | |||
752 | fprintf(fp, "%d\n", baseTri[i]); | |||
753 | } | |||
754 | ||||
755 | status = CAPS_SUCCESS0; | |||
756 | ||||
757 | cleanup: | |||
758 | AIM_FREE(efaces){ EG_free(efaces); efaces = ((void*)0); }; | |||
759 | AIM_FREE(baseTri){ EG_free(baseTri); baseTri = ((void*)0); }; | |||
760 | AIM_FREE(tupleValue){ EG_free(tupleValue); tupleValue = ((void*)0); }; | |||
761 | return status; | |||
762 | } | |||
763 | ||||
764 | static int cbaero_writeSetup(void *aimInfo, const aimStorage *cbaeroInstance, capsValue *aimInputs) | |||
765 | { | |||
766 | int status; // Function return status | |||
767 | ||||
768 | int i; // Indexing | |||
769 | ||||
770 | char filename[PATH_MAX4096]; | |||
771 | ||||
772 | int state, nglobal; | |||
773 | ego body; | |||
774 | ||||
775 | int itri; | |||
776 | int iface, nFace; | |||
777 | ||||
778 | int plen, tlen; | |||
779 | const double *points, *uv; | |||
780 | const int *ptypes, *pindexs, *tris, *tric; | |||
781 | ||||
782 | FILE *fp = NULL((void*)0); | |||
783 | char fileExt[] = ".stp"; | |||
784 | ||||
785 | aimMeshRef *meshRef; | |||
786 | const mapAttrToIndexStruct *groupMap; | |||
787 | ||||
788 | printf("Writing CBAero setup file - %s%s\n", cbaeroInstance->projectName, fileExt); | |||
789 | ||||
790 | meshRef = cbaeroInstance->meshRefIn; // Get pointer to simplify writing | |||
791 | groupMap = &cbaeroInstance->groupMap; | |||
792 | ||||
793 | snprintf(filename, PATH_MAX4096, "%s%s", cbaeroInstance->projectName, fileExt); | |||
794 | ||||
795 | fp = aim_fopen(aimInfo, filename, "w"); | |||
796 | if (fp == NULL((void*)0)) { | |||
797 | AIM_ERROR(aimInfo, "Unable to open file: %s", filename){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 797, __func__ , "Unable to open file: %s", filename); }; | |||
798 | status = CAPS_IOERR-332; | |||
799 | goto cleanup; | |||
800 | } | |||
801 | ||||
802 | status = cbaero_selectHighSpeed(aimInfo, aimInputs[inDefault_Body_Method-1].vals.string); | |||
803 | if (status < CAPS_SUCCESS0) AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 803, __func__, 0); goto cleanup; }; | |||
804 | fprintf(fp, "HypersonicBodyMethod: %d\n", status); | |||
805 | ||||
806 | status = cbaero_selectHighSpeed(aimInfo, aimInputs[inDefault_Wing_Method-1].vals.string); | |||
807 | if (status < CAPS_SUCCESS0) AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 807, __func__, 0); goto cleanup; }; | |||
808 | fprintf(fp, "HypersonicWingMethod: %d\n", status); | |||
809 | ||||
810 | status = cbaero_selectLowSpeed(aimInfo, aimInputs[inDefault_Low_Speed_Method-1].vals.string); | |||
811 | if (status < CAPS_SUCCESS0) AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 811, __func__, 0); goto cleanup; }; | |||
812 | fprintf(fp, "LowSpeedMethod: %d\n", status); | |||
813 | ||||
814 | fprintf(fp, "Leading Edge Suction: %.6f\n", aimInputs[inLeading_Edge_Suction-1].vals.real); | |||
815 | fprintf(fp, "Mangler Setting: 2\n"); | |||
816 | ||||
817 | status = cbaero_appendSetupAero(aimInfo, fp, meshRef, | |||
818 | groupMap, | |||
819 | aimInputs[inAero_Surface-1].length, | |||
820 | aimInputs[inAero_Surface-1].vals.tuple, | |||
821 | aimInputs[inDefault_Body_Method-1].vals.string, | |||
822 | aimInputs[inDefault_Wing_Method-1].vals.string); | |||
823 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 823, __func__, 0); goto cleanup; }; | |||
824 | ||||
825 | // TPS - Needs to be enhanced | |||
826 | fprintf(fp,"TPS Zones.v.3.4:\n"); | |||
827 | fprintf(fp,"1\n"); | |||
828 | fprintf(fp,"0\n"); | |||
829 | fprintf(fp,"0\n"); | |||
830 | fprintf(fp,"5\n"); | |||
831 | fprintf(fp,"DefaultZone\n"); | |||
832 | fprintf(fp,"StackUpFile\n"); | |||
833 | fprintf(fp,"StructuresStackUpFile\n"); | |||
834 | fprintf(fp,"MarginsFile\n"); | |||
835 | fprintf(fp,"MarginsFile\n"); | |||
836 | fprintf(fp,"None\n"); | |||
837 | ||||
838 | // Write element indexes to tag files | |||
839 | for (i = 0; i < meshRef->nmap; i++) { | |||
840 | status = EG_statusTessBody(meshRef->maps[i].tess, &body, &state, &nglobal); | |||
841 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 841, __func__, 0); goto cleanup; }; | |||
842 | ||||
843 | status = EG_getBodyTopos(body, NULL((void*)0), FACE23, &nFace, NULL((void*)0)); | |||
844 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 844, __func__, 0); goto cleanup; }; | |||
845 | ||||
846 | for (iface = 0; iface < nFace; iface++) { | |||
847 | status = EG_getTessFace(meshRef->maps[i].tess, iface + 1, &plen, &points, &uv, &ptypes, &pindexs, | |||
848 | &tlen, &tris, &tric); | |||
849 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 849, __func__, 0); goto cleanup; }; | |||
850 | ||||
851 | for (itri = 0; itri < tlen; itri++) | |||
852 | fprintf(fp,"1\n"); | |||
853 | } | |||
854 | } | |||
855 | ||||
856 | fprintf(fp,"Trajectories:\n"); | |||
857 | fprintf(fp,"0\n"); | |||
858 | fprintf(fp,"Wake Edges:\n"); | |||
859 | fprintf(fp,"0\n"); | |||
860 | fprintf(fp,"0\n"); | |||
861 | ||||
862 | //if (aimInputs[aim_getIndex(aimInfo, "Control_Surface", ANALYSISIN)-1].nullVal == NotNull) { | |||
863 | status = cbaero_appendSetupControl(fp, meshRef, groupMap);//, | |||
864 | //aimInputs[aim_getIndex(aimInfo, "Control_Surface", ANALYSISIN)-1].length, | |||
865 | //aimInputs[aim_getIndex(aimInfo, "Control_Surface", ANALYSISIN)-1].vals.tuple); | |||
866 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 866, __func__, 0); goto cleanup; }; | |||
867 | ||||
868 | ||||
869 | fprintf(fp,"Trajectory Constraint Triangles:\n"); | |||
870 | fprintf(fp,"0\n"); | |||
871 | /*fprintf(fp,"Optimization Data:\n"); | |||
872 | for (i = 0; i < cbaeroInstance->surfaceMesh->numElement; i++) { | |||
873 | ||||
874 | if (cbaeroInstance->surfaceMesh->element[i].elementType != Triangle) continue; | |||
875 | fprintf(fp,"0\n"); | |||
876 | } | |||
877 | */ | |||
878 | status = CAPS_SUCCESS0; | |||
879 | ||||
880 | cleanup: | |||
881 | if (fp != NULL((void*)0)) fclose(fp); | |||
882 | ||||
883 | return status; | |||
884 | } | |||
885 | ||||
886 | /* ********************** Exposed AIM Functions ***************************** */ | |||
887 | ||||
888 | int aimInitialize(int inst, /*@unused@*/ const char *unitSys, void *aimInfo, | |||
889 | /*@unused@*/ void **instStore, /*@unused@*/ int *major, | |||
890 | /*@unused@*/ int *minor, int *nIn, int *nOut, | |||
891 | int *nFields, char ***fnames, int **franks, int **fInOut) | |||
892 | { | |||
893 | ||||
894 | int status = CAPS_SUCCESS0; // Function status return | |||
895 | ||||
896 | aimStorage *cbaeroInstance = NULL((void*)0); | |||
897 | ||||
898 | #ifdef DEBUG | |||
899 | printf("\n cbaeroAIM/aimInitialize ngIn = %d!\n", ngIn); | |||
900 | #endif | |||
901 | ||||
902 | /* specify the number of analysis input and out "parameters" */ | |||
903 | *nIn = NUMINPUT; | |||
904 | *nOut = NUMOUTPUT; | |||
905 | if (inst == -1) return CAPS_SUCCESS0; | |||
906 | ||||
907 | /*! \page geomRepIntentCBAero Geometry Representation | |||
908 | * The geometric representation for the CBAero AIM requires that the body be either a solid | |||
909 | * body (SOLIDBODY) or a manifold sheet body (SHEETBODY). | |||
910 | */ | |||
911 | ||||
912 | /* specify the field variables this analysis can generate */ | |||
913 | *nFields = 0; | |||
914 | *franks = NULL((void*)0); | |||
915 | *fnames = NULL((void*)0); | |||
916 | *fInOut = NULL((void*)0); | |||
917 | ||||
918 | // Allocate cbaeroInstance | |||
919 | AIM_ALLOC(cbaeroInstance, 1, aimStorage, aimInfo, status){ if (cbaeroInstance != ((void*)0)) { status = -4; aim_status (aimInfo, status, "cbaeroAIM.c", 919, __func__, 1, "AIM_ALLOC: %s != NULL" , "cbaeroInstance"); goto cleanup; } size_t memorysize = 1; cbaeroInstance = (aimStorage *) EG_alloc(memorysize*sizeof(aimStorage)); if (cbaeroInstance == ((void*)0)) { status = -4; aim_status(aimInfo , status, "cbaeroAIM.c", 919, __func__, 3, "AIM_ALLOC: %s size %zu type %s" , "cbaeroInstance", memorysize, "aimStorage"); goto cleanup; } }; | |||
920 | ||||
921 | // Set initial values for cbaeroInstance | |||
922 | status = initialize_aimStorage(cbaeroInstance); | |||
923 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 923, __func__, 0); goto cleanup; }; | |||
924 | ||||
925 | *instStore = cbaeroInstance; | |||
926 | ||||
927 | status = CAPS_SUCCESS0; | |||
928 | ||||
929 | cleanup: | |||
930 | return status; | |||
931 | } | |||
932 | ||||
933 | ||||
934 | // ********************** AIM Function Break ***************************** | |||
935 | int aimInputs(/*@unused@*/ void *instStore, /*@unused@*/ void *aimInfo, | |||
936 | int index, char **ainame, capsValue *defval) | |||
937 | { | |||
938 | /*! \page aimInputsCBAero AIM Inputs | |||
939 | * The following list outlines the CBAero inputs along with their default values available | |||
940 | * through the AIM interface. | |||
941 | */ | |||
942 | int status = CAPS_SUCCESS0; | |||
943 | ||||
944 | #ifdef DEBUG | |||
945 | printf(" cbaeroAIM/aimInputs instance = %d index = %d!\n", iIndex, index); | |||
946 | #endif | |||
947 | ||||
948 | *ainame = NULL((void*)0); | |||
949 | ||||
950 | // CBAero Inputs | |||
951 | if (index == inProj_Name) { | |||
952 | *ainame = EG_strdup("Proj_Name"); | |||
953 | defval->type = String; | |||
954 | defval->nullVal = NotNull; | |||
955 | defval->vals.string = EG_strdup("cbaero_CAPS"); | |||
956 | defval->lfixed = Change; | |||
957 | ||||
958 | /*! \page aimInputsCBAero | |||
959 | * - <B> Proj_Name = "cbaero_CAPS"</B> <br> | |||
960 | * This corresponds to the project "root" name. | |||
961 | */ | |||
962 | } else if (index == inMach) { | |||
963 | *ainame = EG_strdup("Mach"); // Mach number | |||
964 | defval->type = Double; | |||
965 | defval->nullVal = IsNull; | |||
966 | defval->units = NULL((void*)0); | |||
967 | defval->lfixed = Change; | |||
968 | defval->sfixed = Fixed; | |||
969 | defval->dim = 1; | |||
970 | defval->vals.real = 0.0; | |||
971 | ||||
972 | /*! \page aimInputsCBAero | |||
973 | * - <B> Mach = 0.0 (default) or [0.0, ... , 0.0] </B> <br> | |||
974 | * Mach number (can be a single or array of values). | |||
975 | * | |||
976 | */ | |||
977 | } else if (index == inDynamic_Pressure) { | |||
978 | *ainame = EG_strdup("Dynamic_Pressure"); // Dynamic pressure | |||
979 | defval->type = Double; | |||
980 | defval->nullVal = IsNull; | |||
981 | defval->units = NULL((void*)0); | |||
982 | defval->lfixed = Change; | |||
983 | defval->sfixed = Fixed; | |||
984 | defval->dim = 1; | |||
985 | defval->units = EG_strdup("bar"); | |||
986 | defval->vals.real = 0.0; | |||
987 | ||||
988 | /*! \page aimInputsCBAero | |||
989 | * - <B> Dynamic_Pressure = 0.0 (default) or [0.0, ... , 0.0] </B> <br> | |||
990 | * Dynamic pressure [bar] value (can be a single or array of values). | |||
991 | * | |||
992 | */ | |||
993 | } else if (index == inAlpha) { | |||
994 | *ainame = EG_strdup("Alpha"); | |||
995 | defval->type = Double; | |||
996 | defval->nullVal = IsNull; | |||
997 | defval->units = EG_strdup("degree"); | |||
998 | defval->lfixed = Change; | |||
999 | defval->sfixed = Fixed; | |||
1000 | defval->dim = 1; | |||
1001 | defval->vals.real = 0.0; | |||
1002 | ||||
1003 | /*! \page aimInputsCBAero | |||
1004 | * - <B> Alpha = 0.0 (default) or [0.0, ... , 0.0] </B> <br> | |||
1005 | * Angle of attack [degree] (can be a single or array of values). | |||
1006 | */ | |||
1007 | } else if (index == inBeta) { | |||
1008 | *ainame = EG_strdup("Beta"); | |||
1009 | defval->type = Double; | |||
1010 | defval->nullVal = NotNull; | |||
1011 | defval->units = EG_strdup("degree"); | |||
1012 | defval->lfixed = Change; | |||
1013 | defval->sfixed = Fixed; | |||
1014 | defval->dim = 1; | |||
1015 | defval->vals.real = 0.0; | |||
1016 | /*! \page aimInputsCBAero | |||
1017 | * - <B> Beta = 0.0 (default) or [0.0, ... , 0.0] </B> <br> | |||
1018 | * Sideslip angle (can be a single or array of values). | |||
1019 | */ | |||
1020 | } else if (index == inReferenceArea) { | |||
1021 | *ainame = EG_strdup("ReferenceArea"); | |||
1022 | defval->type = Double; | |||
1023 | defval->nullVal = IsNull; | |||
1024 | defval->units = EG_strdup("meter^2"); | |||
1025 | defval->lfixed = Fixed; | |||
1026 | defval->dim = 0; | |||
1027 | defval->vals.real = 0.0; | |||
1028 | ||||
1029 | /*! \page aimInputsCBAero | |||
1030 | * - <B>ReferenceArea = NULL </B> <br> | |||
1031 | * This sets the reference area for used in force and moment calculations. | |||
1032 | * Alternatively, the geometry (body) attribute (see \ref attributeCBAero) "capsReferenceArea" maybe used to specify this variable | |||
1033 | * (note: values set through the AIM input will supersede the attribution value). | |||
1034 | */ | |||
1035 | } else if (index == inReferenceChord) { | |||
1036 | *ainame = EG_strdup("ReferenceChord"); | |||
1037 | defval->type = Double; | |||
1038 | defval->nullVal = IsNull; | |||
1039 | defval->units = EG_strdup("meter"); | |||
1040 | defval->lfixed = Fixed; | |||
1041 | defval->dim = 0; | |||
1042 | defval->vals.real = 0.0; | |||
1043 | ||||
1044 | /*! \page aimInputsCBAero | |||
1045 | * - <B>ReferenceChord = NULL </B> <br> | |||
1046 | * This sets the reference chord for used in force and moment calculations. | |||
1047 | * Alternatively, the geometry (body) attribute (see \ref attributeCBAero) "capsReferenceChord" maybe used to specify this variable | |||
1048 | * (note: values set through the AIM input will supersede the attribution value). | |||
1049 | */ | |||
1050 | ||||
1051 | } else if (index == inReferenceSpan) { | |||
1052 | *ainame = EG_strdup("ReferenceSpan"); | |||
1053 | defval->type = Double; | |||
1054 | defval->nullVal = IsNull; | |||
1055 | defval->units = EG_strdup("meter"); | |||
1056 | defval->lfixed = Fixed; | |||
1057 | defval->dim = 0; | |||
1058 | defval->vals.real = 0.0; | |||
1059 | ||||
1060 | /*! \page aimInputsCBAero | |||
1061 | * - <B>ReferenceSpan = NULL </B> <br> | |||
1062 | * This sets the reference span for used in force and moment calculations. | |||
1063 | * Alternatively, the geometry (body) attribute (see \ref attributeCBAero) "capsReferenceSpan" maybe used to specify this variable | |||
1064 | * (note: values set through the AIM input will supersede the attribution value). | |||
1065 | */ | |||
1066 | ||||
1067 | } else if (index == inMoment_Center) { | |||
1068 | *ainame = EG_strdup("Moment_Center"); | |||
1069 | defval->type = Double; | |||
1070 | defval->dim = 1; | |||
1071 | defval->length = 3; | |||
1072 | defval->nrow = 3; | |||
1073 | defval->ncol = 1; | |||
1074 | defval->units = EG_strdup("meter"); | |||
1075 | AIM_ALLOC(defval->vals.reals, defval->length, double, aimInfo, status){ if (defval->vals.reals != ((void*)0)) { status = -4; aim_status (aimInfo, status, "cbaeroAIM.c", 1075, __func__, 1, "AIM_ALLOC: %s != NULL" , "defval->vals.reals"); goto cleanup; } size_t memorysize = defval->length; defval->vals.reals = (double *) EG_alloc (memorysize*sizeof(double)); if (defval->vals.reals == ((void *)0)) { status = -4; aim_status(aimInfo, status, "cbaeroAIM.c" , 1075, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "defval->vals.reals" , memorysize, "double"); goto cleanup; } }; | |||
1076 | defval->vals.reals[0] = 0.0; | |||
1077 | defval->vals.reals[1] = 0.0; | |||
1078 | defval->vals.reals[2] = 0.0; | |||
1079 | defval->nullVal = IsNull; | |||
1080 | defval->lfixed = Fixed; | |||
1081 | ||||
1082 | /*! \page aimInputsCBAero | |||
1083 | * - <B>Moment_Center = [0.0, 0.0, 0.0] (NULL)</B> <br> | |||
1084 | * Array values correspond to the x, y, and z center of gravity (CG) locations [meter]. | |||
1085 | * Alternatively, the geometry (body) attributes (see \ref attributeCBAero) "capsReferenceX", "capsReferenceY", | |||
1086 | * and "capsReferenceZ" may be used to specify the center of gravity, respectively | |||
1087 | * (note: values set through the AIM input will supersede the attribution values). | |||
1088 | */ | |||
1089 | } else if (index == inFlow_Type) { | |||
1090 | *ainame = EG_strdup("Flow_Type"); | |||
1091 | defval->type = String; | |||
1092 | defval->nullVal = NotNull; | |||
1093 | defval->vals.string = EG_strdup("Inviscid"); | |||
1094 | defval->lfixed = Change; | |||
1095 | /*! \page aimInputsCBAero | |||
1096 | * - <B>Flow_Type = "Inviscid" </B> <br> | |||
1097 | * Type of flow to consider. Options (=corresponding integer code): FreeTransition(=0), Laminar(=1), Turbulent(=2), Inviscid(=3). | |||
1098 | */ | |||
1099 | } else if (index == inCritical_Transition) { | |||
1100 | *ainame = EG_strdup("Critical_Transition"); | |||
1101 | defval->type = Double; | |||
1102 | defval->nullVal = NotNull; | |||
1103 | defval->units = NULL((void*)0); | |||
1104 | defval->lfixed = Fixed; | |||
1105 | defval->sfixed = Fixed; | |||
1106 | defval->dim = 0; | |||
1107 | defval->vals.real = 220.0; | |||
1108 | /*! \page aimInputsCBAero | |||
1109 | * - <B>Critical_Transition = 220.0 </B> <br> | |||
1110 | * Critical ratio of Re-theta (Reynolds based on momentum thickness) and Ma (Mach number) for transition. | |||
1111 | */ | |||
1112 | } else if (index == inPlanet) { | |||
1113 | *ainame = EG_strdup("Planet"); | |||
1114 | defval->type = String; | |||
1115 | defval->nullVal = NotNull; | |||
1116 | defval->vals.string = EG_strdup("EARTH"); | |||
1117 | defval->lfixed = Change; | |||
1118 | ||||
1119 | /*! \page aimInputsCBAero | |||
1120 | * - <B> Planet = "EARTH"</B> <br> | |||
1121 | * Planet type. Options include “MERCURY”, “VENUS”, “EARTH”, “MARS”, “JUPITER”, “SATURN”, | |||
1122 | * “URANUS”, “NEPTUNE”, and “PLUTO”. | |||
1123 | * | |||
1124 | */ | |||
1125 | } else if (index == inDefault_Body_Method) { | |||
1126 | *ainame = EG_strdup("Default_Body_Method"); | |||
1127 | defval->type = String; | |||
1128 | defval->nullVal = NotNull; | |||
1129 | defval->vals.string = EG_strdup("ModifiedNewtonian"); | |||
1130 | defval->lfixed = Change; | |||
1131 | ||||
1132 | /*! \page aimInputsCBAero | |||
1133 | * - <B> Default_Body_Method = "ModifiedNewtonian"</B> <br> | |||
1134 | * Default hypersonic base method. Options (=corresponding integer code): ModifiedNewtonian(=3), | |||
1135 | * TangentCone(=21), TangentConeNormalShock(=22), TangentWedge(=31), TangentWedgeNormalShock(=32), FreeMolecular(=99). | |||
1136 | */ | |||
1137 | } else if (index == inDefault_Wing_Method) { | |||
1138 | *ainame = EG_strdup("Default_Wing_Method"); | |||
1139 | defval->type = String; | |||
1140 | defval->nullVal = NotNull; | |||
1141 | defval->vals.string = EG_strdup("ModifiedNewtonian"); | |||
1142 | defval->lfixed = Change; | |||
1143 | ||||
1144 | /*! \page aimInputsCBAero | |||
1145 | * - <B> Default_Wing_Method = "ModifiedNewtonian"</B> <br> | |||
1146 | * Default hypersonic aerodynamic wing method. Options (=corresponding integer code): ModifiedNewtonian(=3), | |||
1147 | * TangentCone(=21), TangentConeNormalShock(=22), TangentWedge(=31), TangentWedgeNormalShock(=32), FreeMolecular(=99). | |||
1148 | */ | |||
1149 | } else if (index == inDefault_Low_Speed_Method) { | |||
1150 | *ainame = EG_strdup("Default_Low_Speed_Method"); | |||
1151 | defval->type = String; | |||
1152 | defval->nullVal = NotNull; | |||
1153 | defval->vals.string = EG_strdup("FastPanel"); | |||
1154 | defval->lfixed = Change; | |||
1155 | ||||
1156 | /*! \page aimInputsCBAero | |||
1157 | * - <B> Default_Low_Speed_Method = "FastPanel"</B> <br> | |||
1158 | * Default low speed method. Options (=corresponding integer code): FastPanel(=1), LowAR(=2). | |||
1159 | * | |||
1160 | */ | |||
1161 | } else if (index == inLeading_Edge_Suction) { | |||
1162 | *ainame = EG_strdup("Leading_Edge_Suction"); | |||
1163 | defval->type = Double; | |||
1164 | defval->nullVal = NotNull; | |||
1165 | defval->units = NULL((void*)0); | |||
1166 | defval->lfixed = Fixed; | |||
1167 | defval->sfixed = Fixed; | |||
1168 | defval->dim = Scalar; | |||
1169 | defval->vals.real = 1.0; | |||
1170 | defval->limits.dlims[0] = -1.0; // Limit of accepted values | |||
1171 | defval->limits.dlims[1] = 1.0; | |||
1172 | ||||
1173 | /*! \page aimInputsCBAero | |||
1174 | * - <B> Leading_Edge_Suction = 1.00</B> <br> | |||
1175 | * Default low speed method integer tag. Range [-1.0, 1.0] | |||
1176 | */ | |||
1177 | ||||
1178 | } else if (index == inAero_Surface) { | |||
1179 | *ainame = EG_strdup("Aero_Surface"); | |||
1180 | defval->type = Tuple; | |||
1181 | defval->nullVal = IsNull; | |||
1182 | defval->dim = Vector; | |||
1183 | defval->lfixed = Change; | |||
1184 | defval->vals.tuple = NULL((void*)0); | |||
1185 | ||||
1186 | /*! \page aimInputsCBAero | |||
1187 | * - <B> Aero_Surface = NULL</B> <br> | |||
1188 | * Defines the type of aero. surface by associating a "capsGroups" attribute name with a particular panel method - ("capsGroup Name", "Value"), | |||
1189 | * where "Value" can either be "Body", "Base", "Wing", "Inlet", "Cowl", or "Nozzle". If a capsGroup panel method is not defined it will be assumed | |||
1190 | * to be a "Body". | |||
1191 | * | |||
1192 | */ | |||
1193 | ||||
1194 | } else if (index == inMesh_Morph) { | |||
1195 | *ainame = EG_strdup("Mesh_Morph"); | |||
1196 | defval->type = Boolean; | |||
1197 | defval->lfixed = Fixed; | |||
1198 | defval->vals.integer = (int) false0; | |||
1199 | defval->dim = Scalar; | |||
1200 | defval->nullVal = NotNull; | |||
1201 | ||||
1202 | /*! \page aimInputsCBAero | |||
1203 | * - <B> Mesh_Morph = False</B> <br> | |||
1204 | * Project previous surface mesh onto new geometry. | |||
1205 | */ | |||
1206 | ||||
1207 | } else if (index == inSurface_Mesh) { | |||
1208 | *ainame = EG_strdup("Surface_Mesh"); | |||
1209 | defval->type = PointerMesh; | |||
1210 | defval->dim = Vector; | |||
1211 | defval->lfixed = Change; | |||
1212 | defval->sfixed = Change; | |||
1213 | defval->vals.AIMptr = NULL((void*)0); | |||
1214 | defval->nullVal = IsNull; | |||
1215 | defval->units = EG_strdup("meter"); | |||
1216 | AIM_STRDUP(defval->meshWriter, MESHWRITER, aimInfo, status){ if (defval->meshWriter != ((void*)0)) { status = -4; aim_status (aimInfo, status, "cbaeroAIM.c", 1216, __func__, 1, "AIM_STRDUP: %s != NULL!" , "defval->meshWriter"); goto cleanup; } defval->meshWriter = EG_strdup("fastWriter"); if (defval->meshWriter == ((void *)0)) { status = -4; aim_status(aimInfo, status, "cbaeroAIM.c" , 1216, __func__, 2, "AIM_STRDUP: %s %s", "defval->meshWriter" , "fastWriter"); goto cleanup; } }; | |||
1217 | ||||
1218 | /*! \page aimInputsCBAero | |||
1219 | * - <B>Surface_Mesh = NULL</B> <br> | |||
1220 | * A Surface_Mesh link. | |||
1221 | */ | |||
1222 | } else { | |||
1223 | AIM_ERROR(aimInfo, "Unkonw input index $%d", index){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 1223, __func__ , "Unkonw input index $%d", index); }; | |||
1224 | status = CAPS_RANGEERR-326; | |||
1225 | goto cleanup; | |||
1226 | } | |||
1227 | ||||
1228 | AIM_NOTNULL(*ainame, aimInfo, status){ if (*ainame == ((void*)0)) { status = -307; aim_status(aimInfo , status, "cbaeroAIM.c", 1228, __func__, 1, "%s == NULL!", "*ainame" ); goto cleanup; } }; | |||
1229 | ||||
1230 | cleanup: | |||
1231 | if (status != CAPS_SUCCESS0) AIM_FREE(*ainame){ EG_free(*ainame); *ainame = ((void*)0); }; | |||
1232 | return CAPS_SUCCESS0; | |||
1233 | } | |||
1234 | ||||
1235 | ||||
1236 | // ********************** AIM Function Break ***************************** | |||
1237 | int aimUpdateState(void *instStore, void *aimInfo, | |||
1238 | capsValue *aimInputs) | |||
1239 | { | |||
1240 | // Function return flag | |||
1241 | int status = CAPS_SUCCESS0; | |||
1242 | ||||
1243 | int i; | |||
1244 | int foundSref=(int)false0, foundCref=(int)false0, foundBref=(int)false0; | |||
1245 | int foundXref=(int)false0, foundYref=(int)false0, foundZref=(int)false0; | |||
1246 | ||||
1247 | // AIM input bodies | |||
1248 | const char *intent; | |||
1249 | int numBody; | |||
1250 | ego *bodies = NULL((void*)0); | |||
1251 | ||||
1252 | // EGADS return values | |||
1253 | int atype, alen; | |||
1254 | const int *ints; | |||
1255 | const char *string; | |||
1256 | const double *reals; | |||
1257 | ||||
1258 | const char *lengthUnits=NULL((void*)0); | |||
1259 | double scaleFactor = 1.0; | |||
1260 | ||||
1261 | aimStorage *cbaeroInstance = (aimStorage *)instStore; | |||
1262 | ||||
1263 | AIM_NOTNULL(aimInputs, aimInfo, status){ if (aimInputs == ((void*)0)) { status = -307; aim_status(aimInfo , status, "cbaeroAIM.c", 1263, __func__, 1, "%s == NULL!", "aimInputs" ); goto cleanup; } }; | |||
1264 | ||||
1265 | // Free our meshRef | |||
1266 | (void) aim_freeMeshRef(&cbaeroInstance->meshRefObj); | |||
1267 | ||||
1268 | if (aimInputs[inSurface_Mesh-1].nullVal == IsNull && | |||
1269 | aimInputs[inMesh_Morph-1].vals.integer == (int) false0) { | |||
1270 | AIM_ANALYSISIN_ERROR(aimInfo, inSurface_Mesh, "'Surface_Mesh' input must be linked to an output 'Surface_Mesh'"){ aim_message(aimInfo, CERROR, inSurface_Mesh, "cbaeroAIM.c", 1270, __func__, "'Surface_Mesh' input must be linked to an output 'Surface_Mesh'" ); }; | |||
1271 | status = CAPS_BADVALUE-311; | |||
1272 | goto cleanup; | |||
1273 | } | |||
1274 | ||||
1275 | // Get AIM bodies | |||
1276 | status = aim_getBodies(aimInfo, &intent, &numBody, &bodies); | |||
1277 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 1277, __func__, 0); goto cleanup; }; | |||
1278 | ||||
1279 | #ifdef DEBUG | |||
1280 | printf(" cbaeroAIM/aimUpdateState instance = %d numBody = %d!\n", iIndex, numBody); | |||
1281 | #endif | |||
1282 | ||||
1283 | if ((numBody <= 0) || (bodies == NULL((void*)0))) { | |||
1284 | AIM_ERROR(aimInfo, "No body!\n"){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 1284, __func__ , "No body!\n"); }; | |||
1285 | return CAPS_SOURCEERR-330; | |||
1286 | } | |||
1287 | ||||
1288 | if (numBody > 1) { | |||
1289 | AIM_ERROR(aimInfo, "CBAero can only accept a single body! numBody = %d\n", numBody){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 1289, __func__ , "CBAero can only accept a single body! numBody = %d\n", numBody ); }; | |||
1290 | return CAPS_SOURCEERR-330; | |||
1291 | } | |||
1292 | ||||
1293 | status = aim_capsLength(aimInfo, &lengthUnits); | |||
1294 | AIM_NOTFOUND(aimInfo, status)if (status != 0 && status != -303 && status != -1) { aim_status(aimInfo, status, "cbaeroAIM.c", 1294, __func__ , 0); goto cleanup; }; | |||
1295 | if (status == CAPS_NOTFOUND-303) { | |||
1296 | AIM_ERROR(aimInfo, "capsLength attribute must be specified for CBAero"){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 1296, __func__ , "capsLength attribute must be specified for CBAero"); }; | |||
1297 | goto cleanup; | |||
1298 | } | |||
1299 | AIM_NOTNULL(lengthUnits, aimInfo, status){ if (lengthUnits == ((void*)0)) { status = -307; aim_status( aimInfo, status, "cbaeroAIM.c", 1299, __func__, 1, "%s == NULL!" , "lengthUnits"); goto cleanup; } }; | |||
1300 | ||||
1301 | status = aim_convert(aimInfo, 1, lengthUnits, &scaleFactor, "meter", &scaleFactor); | |||
1302 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 1302, __func__, 0); goto cleanup; }; | |||
1303 | ||||
1304 | // Loop over bodies and look for reference quantity attributes | |||
1305 | for (i=0; i < numBody; i++) { | |||
1306 | status = EG_attributeRet(bodies[i], "capsReferenceArea", | |||
1307 | &atype, &alen, &ints, &reals, &string); | |||
1308 | if (status == EGADS_SUCCESS0) { | |||
1309 | if (atype == ATTRREAL2 && alen == 1) { | |||
1310 | cbaeroInstance->Sref = reals[0] * scaleFactor * scaleFactor; | |||
1311 | foundSref = (int)true1; | |||
1312 | } else { | |||
1313 | AIM_ERROR(aimInfo, "capsReferenceArea should be followed by a single real value!\n"){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 1313, __func__ , "capsReferenceArea should be followed by a single real value!\n" ); }; | |||
1314 | status = CAPS_BADVALUE-311; | |||
1315 | goto cleanup; | |||
1316 | } | |||
1317 | } | |||
1318 | ||||
1319 | status = EG_attributeRet(bodies[i], "capsReferenceChord", | |||
1320 | &atype, &alen, &ints, &reals, &string); | |||
1321 | if (status == EGADS_SUCCESS0) { | |||
1322 | if (atype == ATTRREAL2 && alen == 1) { | |||
1323 | cbaeroInstance->Cref = reals[0] * scaleFactor; | |||
1324 | foundCref = (int)true1; | |||
1325 | } else { | |||
1326 | AIM_ERROR(aimInfo, "capsReferenceChord should be followed by a single real value!\n"){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 1326, __func__ , "capsReferenceChord should be followed by a single real value!\n" ); }; | |||
1327 | status = CAPS_BADVALUE-311; | |||
1328 | goto cleanup; | |||
1329 | } | |||
1330 | } | |||
1331 | ||||
1332 | status = EG_attributeRet(bodies[i], "capsReferenceSpan", | |||
1333 | &atype, &alen, &ints, &reals, &string); | |||
1334 | if (status == EGADS_SUCCESS0) { | |||
1335 | if (atype == ATTRREAL2 && alen == 1) { | |||
1336 | cbaeroInstance->Bref = reals[0] * scaleFactor; | |||
1337 | foundBref = (int)true1; | |||
1338 | } else { | |||
1339 | AIM_ERROR(aimInfo, "capsReferenceSpan should be followed by a single real value!\n"){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 1339, __func__ , "capsReferenceSpan should be followed by a single real value!\n" ); }; | |||
1340 | status = CAPS_BADVALUE-311; | |||
1341 | goto cleanup; | |||
1342 | } | |||
1343 | } | |||
1344 | ||||
1345 | status = EG_attributeRet(bodies[i], "capsReferenceX", | |||
1346 | &atype, &alen, &ints, &reals, &string); | |||
1347 | if (status == EGADS_SUCCESS0) { | |||
1348 | ||||
1349 | if (atype == ATTRREAL2 && alen == 1) { | |||
1350 | cbaeroInstance->Xref = reals[0] * scaleFactor; | |||
1351 | foundXref = (int)true1; | |||
1352 | } else { | |||
1353 | AIM_ERROR(aimInfo, "capsReferenceX should be followed by a single real value!\n"){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 1353, __func__ , "capsReferenceX should be followed by a single real value!\n" ); }; | |||
1354 | status = CAPS_BADVALUE-311; | |||
1355 | goto cleanup; | |||
1356 | } | |||
1357 | } | |||
1358 | ||||
1359 | status = EG_attributeRet(bodies[i], "capsReferenceY", | |||
1360 | &atype, &alen, &ints, &reals, &string); | |||
1361 | if (status == EGADS_SUCCESS0) { | |||
1362 | ||||
1363 | if (atype == ATTRREAL2 && alen == 1) { | |||
1364 | cbaeroInstance->Yref = reals[0] * scaleFactor; | |||
1365 | foundYref = (int)true1; | |||
1366 | } else { | |||
1367 | AIM_ERROR(aimInfo, "capsReferenceY should be followed by a single real value!\n"){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 1367, __func__ , "capsReferenceY should be followed by a single real value!\n" ); }; | |||
1368 | status = CAPS_BADVALUE-311; | |||
1369 | goto cleanup; | |||
1370 | } | |||
1371 | } | |||
1372 | ||||
1373 | status = EG_attributeRet(bodies[i], "capsReferenceZ", | |||
1374 | &atype, &alen, &ints, &reals, &string); | |||
1375 | if (status == EGADS_SUCCESS0){ | |||
1376 | ||||
1377 | if (atype == ATTRREAL2 && alen == 1) { | |||
1378 | cbaeroInstance->Zref = reals[0] * scaleFactor; | |||
1379 | foundZref = (int)true1; | |||
1380 | } else { | |||
1381 | AIM_ERROR(aimInfo, "capsReferenceZ should be followed by a single real value!\n"){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 1381, __func__ , "capsReferenceZ should be followed by a single real value!\n" ); }; | |||
1382 | status = CAPS_BADVALUE-311; | |||
1383 | goto cleanup; | |||
1384 | } | |||
1385 | } | |||
1386 | } | |||
1387 | ||||
1388 | if (aimInputs[inReferenceArea-1].nullVal == NotNull) { | |||
1389 | cbaeroInstance->Sref = aimInputs[inReferenceArea-1].vals.real; | |||
1390 | foundSref = (int)true1; | |||
1391 | } | |||
1392 | if (aimInputs[inReferenceChord-1].nullVal == NotNull) { | |||
1393 | cbaeroInstance->Cref = aimInputs[inReferenceChord-1].vals.real; | |||
1394 | foundCref = (int)true1; | |||
1395 | } | |||
1396 | if (aimInputs[inReferenceSpan-1].nullVal == NotNull) { | |||
1397 | cbaeroInstance->Bref = aimInputs[inReferenceSpan-1].vals.real; | |||
1398 | foundBref = (int)true1; | |||
1399 | } | |||
1400 | ||||
1401 | if (foundSref == (int)false0) { | |||
1402 | AIM_ERROR(aimInfo, "capsReferenceArea is not set on any body and 'ReferenceArea' input not set!"){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 1402, __func__ , "capsReferenceArea is not set on any body and 'ReferenceArea' input not set!" ); }; | |||
1403 | status = CAPS_BADVALUE-311; | |||
1404 | goto cleanup; | |||
1405 | } | |||
1406 | if (foundCref == (int)false0) { | |||
1407 | AIM_ERROR(aimInfo, "capsReferenceChord is not set on any body and 'ReferenceChord' input not set!"){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 1407, __func__ , "capsReferenceChord is not set on any body and 'ReferenceChord' input not set!" ); }; | |||
1408 | status = CAPS_BADVALUE-311; | |||
1409 | goto cleanup; | |||
1410 | } | |||
1411 | if (foundBref == (int)false0) { | |||
1412 | AIM_ERROR(aimInfo, "capsReferenceSpan is not set on any body and 'ReferenceSpan' input not set!"){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 1412, __func__ , "capsReferenceSpan is not set on any body and 'ReferenceSpan' input not set!" ); }; | |||
1413 | status = CAPS_BADVALUE-311; | |||
1414 | goto cleanup; | |||
1415 | } | |||
1416 | ||||
1417 | // Check for moment reference overwrites | |||
1418 | if (aimInputs[inMoment_Center-1].nullVal == NotNull) { | |||
1419 | ||||
1420 | cbaeroInstance->Xref = aimInputs[inMoment_Center-1].vals.reals[0]; | |||
1421 | cbaeroInstance->Yref = aimInputs[inMoment_Center-1].vals.reals[1]; | |||
1422 | cbaeroInstance->Zref = aimInputs[inMoment_Center-1].vals.reals[2]; | |||
1423 | } else { | |||
1424 | if (foundXref == (int)false0) { | |||
1425 | AIM_ERROR(aimInfo, "capsReferenceX is not set on any body and 'Moment_Center' input not set!"){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 1425, __func__ , "capsReferenceX is not set on any body and 'Moment_Center' input not set!" ); }; | |||
1426 | status = CAPS_BADVALUE-311; | |||
1427 | goto cleanup; | |||
1428 | } | |||
1429 | if (foundYref == (int)false0) { | |||
1430 | AIM_ERROR(aimInfo, "capsReferenceY is not set on any body and 'Moment_Center' input not set!"){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 1430, __func__ , "capsReferenceY is not set on any body and 'Moment_Center' input not set!" ); }; | |||
1431 | status = CAPS_BADVALUE-311; | |||
1432 | goto cleanup; | |||
1433 | } | |||
1434 | if (foundZref == (int)false0) { | |||
1435 | AIM_ERROR(aimInfo, "capsReferenceZ is not set on any body and 'Moment_Center' input not set!"){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 1435, __func__ , "capsReferenceZ is not set on any body and 'Moment_Center' input not set!" ); }; | |||
1436 | status = CAPS_BADVALUE-311; | |||
1437 | goto cleanup; | |||
1438 | } | |||
1439 | } | |||
1440 | ||||
1441 | // Get project name | |||
1442 | cbaeroInstance->projectName = aimInputs[inProj_Name-1].vals.string; | |||
1443 | ||||
1444 | // Get mesh | |||
1445 | cbaeroInstance->meshRefIn = (aimMeshRef *) aimInputs[inSurface_Mesh-1].vals.AIMptr; | |||
1446 | ||||
1447 | if ( aimInputs[inMesh_Morph-1].vals.integer == (int) true1 && | |||
1448 | cbaeroInstance->meshRefIn == NULL((void*)0)) { // If we are mighty morphing | |||
1449 | ||||
1450 | // Lets "load" the meshRef now since it's not linked | |||
1451 | status = aim_loadMeshRef(aimInfo, &cbaeroInstance->meshRefObj); | |||
1452 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 1452, __func__, 0); goto cleanup; }; | |||
1453 | ||||
1454 | // Mighty Morph the mesh | |||
1455 | status = aim_morphMeshUpdate(aimInfo, &cbaeroInstance->meshRefObj, numBody, bodies); | |||
1456 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 1456, __func__, 0); goto cleanup; }; | |||
1457 | /*@-immediatetrans@*/ | |||
1458 | cbaeroInstance->meshRefIn = &cbaeroInstance->meshRefObj; | |||
1459 | /*@+immediatetrans@*/ | |||
1460 | } | |||
1461 | AIM_NOTNULL(cbaeroInstance->meshRefIn, aimInfo, status){ if (cbaeroInstance->meshRefIn == ((void*)0)) { status = - 307; aim_status(aimInfo, status, "cbaeroAIM.c", 1461, __func__ , 1, "%s == NULL!", "cbaeroInstance->meshRefIn"); goto cleanup ; } }; | |||
1462 | ||||
1463 | // Get attribute to index mapping | |||
1464 | status = create_MeshRefToIndexMap(aimInfo, cbaeroInstance->meshRefIn, &cbaeroInstance->groupMap); | |||
1465 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 1465, __func__, 0); goto cleanup; }; | |||
1466 | ||||
1467 | cleanup: | |||
1468 | ||||
1469 | return status; | |||
1470 | } | |||
1471 | ||||
1472 | // ********************** AIM Function Break ***************************** | |||
1473 | int aimPreAnalysis(const void *instStore, void *aimInfo, capsValue *aimInputs) | |||
1474 | { | |||
1475 | // Function return flag | |||
1476 | int status = CAPS_SUCCESS0; | |||
1477 | ||||
1478 | int i; | |||
1479 | ||||
1480 | char filename[PATH_MAX4096]; | |||
1481 | char gridfile[PATH_MAX4096]; | |||
1482 | ||||
1483 | const aimStorage *cbaeroInstance = (const aimStorage *)instStore; | |||
1484 | ||||
1485 | AIM_NOTNULL(aimInputs, aimInfo, status){ if (aimInputs == ((void*)0)) { status = -307; aim_status(aimInfo , status, "cbaeroAIM.c", 1485, __func__, 1, "%s == NULL!", "aimInputs" ); goto cleanup; } }; | |||
1486 | ||||
1487 | /* symlink the mesh file */ | |||
1488 | snprintf(gridfile, PATH_MAX4096, "%s%s", cbaeroInstance->meshRefIn->fileName, MESHEXTENSION".fast.msh"); | |||
1489 | snprintf(filename, PATH_MAX4096, "%s%s", cbaeroInstance->projectName, ".msh"); | |||
1490 | ||||
1491 | status = aim_symLink(aimInfo, gridfile, filename); | |||
1492 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 1492, __func__, 0); goto cleanup; }; | |||
1493 | ||||
1494 | for (i = 1; i <= NUMINPUT; i++) { | |||
1495 | if (aim_newAnalysisIn(aimInfo, i) == CAPS_SUCCESS0) { | |||
1496 | status = cbaero_writeInput(aimInfo, cbaeroInstance, aimInputs); | |||
1497 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 1497, __func__, 0); goto cleanup; }; | |||
1498 | break; | |||
1499 | } | |||
1500 | } | |||
1501 | ||||
1502 | // Write Tag files | |||
1503 | status = cbearo_writeTag(aimInfo, | |||
1504 | cbaeroInstance->projectName, | |||
1505 | &cbaeroInstance->groupMap, | |||
1506 | cbaeroInstance->meshRefIn); | |||
1507 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 1507, __func__, 0); goto cleanup; }; | |||
1508 | ||||
1509 | status = cbaero_writeSetup(aimInfo, cbaeroInstance, aimInputs); | |||
1510 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "cbaeroAIM.c", 1510, __func__, 0); goto cleanup; }; | |||
1511 | ||||
1512 | status = CAPS_SUCCESS0; | |||
1513 | ||||
1514 | cleanup: | |||
1515 | ||||
1516 | return status; | |||
1517 | } | |||
1518 | ||||
1519 | // ********************** AIM Function Break ***************************** | |||
1520 | int aimPostAnalysis(/*@unused@*/ void *instStore, /*@unused@*/ void *aimInfo, | |||
1521 | /*@unused@*/ int restart, /*@unused@*/ capsValue *inputs) | |||
1522 | { | |||
1523 | return CAPS_SUCCESS0; | |||
1524 | } | |||
1525 | ||||
1526 | // ********************** AIM Function Break ***************************** | |||
1527 | int aimOutputs(/*@unused@*/ void *instStore, /*@unused@*/ void *aimInfo, | |||
1528 | /*@unused@*/ int index, /*@unused@*/ char **aoname, /*@unused@*/ capsValue *form) | |||
1529 | { | |||
1530 | /*! \page aimOutputsCBAero AIM Outputs | |||
1531 | * The following list outlines the CBAero outputs available through the AIM interface. All variables currently | |||
1532 | * correspond to values found in the *.plt file | |||
1533 | */ | |||
1534 | int status = CAPS_SUCCESS0; | |||
1535 | ||||
1536 | #ifdef DEBUG | |||
1537 | printf(" cbaeroAIM/aimOutputs instance = %d index = %d!\n", iIndex, index); | |||
1538 | #endif | |||
1539 | ||||
1540 | form->type = Double; | |||
1541 | form->lfixed = Change; | |||
1542 | form->sfixed = Fixed; | |||
1543 | form->dim = 1; | |||
1544 | form->length = 1; | |||
1545 | form->nrow = 1; | |||
1546 | form->ncol = 1; | |||
1547 | form->vals.real = 0.0; | |||
1548 | form->vals.reals = NULL((void*)0); | |||
1549 | ||||
1550 | if (index == outBeta) { | |||
1551 | *aoname = EG_strdup("Beta"); | |||
1552 | form->units = EG_strdup("degree"); | |||
1553 | } | |||
1554 | else if (index == outAlpha) { | |||
1555 | *aoname = EG_strdup("Alpha"); | |||
1556 | form->units = EG_strdup("degree"); | |||
1557 | } | |||
1558 | else if (index == outDynamic_Pressure) { | |||
1559 | *aoname = EG_strdup("Dynamic_Pressure"); | |||
1560 | form->units = EG_strdup("bar"); | |||
1561 | } | |||
1562 | else if (index == outMach) { | |||
1563 | *aoname = EG_strdup("Mach"); | |||
1564 | } | |||
1565 | else if (index == outPerTrb) { | |||
1566 | *aoname = EG_strdup("PerTrb"); | |||
1567 | } | |||
1568 | ||||
1569 | /*! \page aimOutputsCBAero | |||
1570 | * Reiterate inputs (based on cases): | |||
1571 | * - <B>Beta</B> = Sideslip [degree]. | |||
1572 | * - <B>Alpha</B> = Angle of attack [degree]. | |||
1573 | * - <B>Dynamic_Pressure</B> = Dynamic pressure [bar]. | |||
1574 | * - <B>Mach</B> = Mach number. | |||
1575 | */ | |||
1576 | ||||
1577 | else if (index == outPerTrb) *aoname = EG_strdup("PerTrb"); | |||
1578 | /*! \page aimOutputsCBAero | |||
1579 | * Per-Trb: | |||
1580 | * - <B>PerTrb</B> = PerTrb. | |||
1581 | */ | |||
1582 | ||||
1583 | // Total Forces - Pressure + Viscous | |||
1584 | else if (index == outCLtot) *aoname = EG_strdup("CLtot"); | |||
1585 | else if (index == outCDtot) *aoname = EG_strdup("CDtot"); | |||
1586 | else if (index == outCMYtot) *aoname = EG_strdup("CMYtot"); | |||
1587 | else if (index == outLoDtot) *aoname = EG_strdup("LoDtot"); | |||
1588 | ||||
1589 | /*! \page aimOutputsCBAero | |||
1590 | * Net Forces - Pressure + Viscous: | |||
1591 | * - <B>CLtot</B> = The lift coefficient. | |||
1592 | * - <B>CDtot</B> = The drag coefficient. | |||
1593 | * - <B>CMYtot</B> = The moment coefficient about the y-axis. | |||
1594 | * - <B>LoDtot</B> = Lift to drag ratio. | |||
1595 | */ | |||
1596 | ||||
1597 | // Pressure Forces | |||
1598 | else if (index == outCL_p) *aoname = EG_strdup("CL_p"); | |||
1599 | else if (index == outCD_p) *aoname = EG_strdup("CD_p"); | |||
1600 | ||||
1601 | /*! \page aimOutputsCBAero | |||
1602 | * Pressure Forces: | |||
1603 | * - <B>CL_p</B> = The lift coefficient - pressure contribution only. | |||
1604 | * - <B>CD_p</B> = The drag coefficient - pressure contribution only. | |||
1605 | */ | |||
1606 | ||||
1607 | // Viscous Forces | |||
1608 | else if (index == outCL_v) *aoname = EG_strdup("CL_v"); | |||
1609 | else if (index == outCD_v) *aoname = EG_strdup("CD_v"); | |||
1610 | ||||
1611 | /*! \page aimOutputsCBAero | |||
1612 | * Viscous Forces: | |||
1613 | * - <B>CL_v</B> = The lift coefficient - viscous contribution only. | |||
1614 | * - <B>CD_v</B> = The drag coefficient - viscous contribution only. | |||
1615 | */ | |||
1616 | ||||
1617 | // Heating | |||
1618 | else if (index == outStagnation_Temperature) { | |||
1619 | *aoname = EG_strdup("Stagnation_Temperature"); | |||
1620 | form->units = EG_strdup("kelvin"); | |||
1621 | } | |||
1622 | else if (index == outStagnation_Radius) { | |||
1623 | *aoname = EG_strdup("Stagnation_Radius"); | |||
1624 | form->units = EG_strdup("meter"); | |||
1625 | } | |||
1626 | else if (index == outConvective_Flux) { | |||
1627 | *aoname = EG_strdup("Convective_Flux"); | |||
1628 | form->units = EG_strdup("watt per centimeter^2"); | |||
1629 | } | |||
1630 | else if (index == outRadiative_Flux) { | |||
1631 | *aoname = EG_strdup("Radiative_Flux"); | |||
1632 | form->units = EG_strdup("watt per centimeter^2"); | |||
1633 | } | |||
1634 | ||||
1635 | /*! \page aimOutputsCBAero | |||
1636 | * Aero-thermal: | |||
1637 | * - <B>Stagnation_Temperature</B> = Stagnation temperature [K]. | |||
1638 | * - <B>Stagnation_Radius</B> = = Stagnation radius [m]. | |||
1639 | * - <B>Convective_Flux</B> = Convective heat flux [W/cm<sup>2</sup>]. | |||
1640 | * - <B>Radiative_Flux</B> = Radiation heat flux [W/cm<sup>2</sup>]. | |||
1641 | */ | |||
1642 | ||||
1643 | // Trefftz | |||
1644 | else if (index == outCL_Trefftz) *aoname = EG_strdup("CL_Trefftz"); | |||
1645 | else if (index == outCD_Trefftz) *aoname = EG_strdup("CD_Trefftz"); | |||
1646 | ||||
1647 | /*! \page aimOutputsCBAero | |||
1648 | * Trefftz: | |||
1649 | * - <B>CL_Trefftz</B> = Trefftz lift coefficient. | |||
1650 | * - <B>CD_Trefftz</B> = Trefftz drag coefficient. | |||
1651 | */ | |||
1652 | ||||
1653 | else { | |||
1654 | ||||
1655 | printf(" cbaeroAIM/aimOutputs index = %d NOT Found!\n", index); | |||
1656 | return CAPS_NOTFOUND-303; | |||
1657 | } | |||
1658 | ||||
1659 | AIM_NOTNULL(*aoname, aimInfo, status){ if (*aoname == ((void*)0)) { status = -307; aim_status(aimInfo , status, "cbaeroAIM.c", 1659, __func__, 1, "%s == NULL!", "*aoname" ); goto cleanup; } }; | |||
1660 | ||||
1661 | cleanup: | |||
1662 | return status; | |||
1663 | } | |||
1664 | ||||
1665 | ||||
1666 | // ********************** AIM Function Break ***************************** | |||
1667 | // Calculate CBAero output | |||
1668 | int aimCalcOutput(/*@unused@*/ void *instStore, /*@unused@*/ void *aimInfo, /*@unused@*/ int index, | |||
1669 | /*@unused@*/ capsValue *val) | |||
1670 | { | |||
1671 | int status; // Function status; | |||
1672 | ||||
1673 | // excess data entries in case future versions of xfoil change | |||
1674 | #define MAX_DATA_ENTRY25 25 | |||
1675 | int numDataEntry = 0; | |||
1676 | double dataLine[MAX_DATA_ENTRY25]; | |||
1677 | char headers[MAX_DATA_ENTRY25][40]; | |||
1678 | const char *valHeader; | |||
1679 | int valIndex; | |||
1680 | ||||
1681 | int i; // Indexing | |||
1682 | ||||
1683 | size_t linecap = 0; | |||
1684 | char *line = NULL((void*)0), *rest = NULL((void*)0), *token = NULL((void*)0); // Temporary line holder | |||
1685 | ||||
1686 | char filename[PATH_MAX4096]; // File to open | |||
1687 | char fileExt[] = ".plt"; | |||
1688 | ||||
1689 | FILE *fp = NULL((void*)0); // File pointer | |||
1690 | ||||
1691 | int numCase = 0; | |||
1692 | double *tempVal = NULL((void*)0); | |||
1693 | ||||
1694 | aimStorage *cbaeroInstance = (aimStorage *)instStore; | |||
1695 | ||||
1696 | #ifdef DEBUG | |||
1697 | printf(" cbaeroAIM/aimCalcOutput instance = %d index = %d!\n", iIndex, index); | |||
1698 | #endif | |||
1699 | ||||
1700 | if (val->length > 1) { | |||
1701 | AIM_FREE(val->vals.reals){ EG_free(val->vals.reals); val->vals.reals = ((void*)0 ); }; | |||
1702 | } else { | |||
1703 | val->vals.real = 0.0; | |||
1704 | } | |||
1705 | ||||
1706 | val->nrow = 1; | |||
1707 | val->ncol = 1; | |||
1708 | val->length = val->nrow*val->ncol; | |||
1709 | ||||
1710 | // Open cbaero plt file | |||
1711 | snprintf(filename, PATH_MAX4096, "%s%s", cbaeroInstance->projectName, fileExt); | |||
1712 | ||||
1713 | fp = aim_fopen(aimInfo, filename, "r"); | |||
1714 | if (fp == NULL((void*)0)) { | |||
1715 | AIM_ERROR(aimInfo, "Unable to open file: %s\n", filename){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 1715, __func__ , "Unable to open file: %s\n", filename); }; | |||
1716 | status = CAPS_IOERR-332; | |||
1717 | goto cleanup; | |||
1718 | } | |||
1719 | ||||
1720 | status = getline(&line, &linecap, fp); | |||
1721 | if (status <= 0) AIM_STATUS(aimInfo, (status = CAPS_IOERR))if ((status = -332) != 0) { aim_status(aimInfo, (status = -332 ), "cbaeroAIM.c", 1721, __func__, 0); goto cleanup; }; | |||
1722 | ||||
1723 | // Parse the header information, | |||
1724 | rest = line; | |||
1725 | ||||
1726 | numDataEntry = 0; | |||
1727 | while ((token = strtok_r(rest, " ", &rest))) { | |||
1728 | if (token[0] == '\n') continue; | |||
1729 | strcpy(headers[numDataEntry], token); | |||
1730 | //printf("'%s'\n", headers[numDataEntry]); | |||
1731 | numDataEntry++; | |||
1732 | if (numDataEntry > MAX_DATA_ENTRY25) { | |||
1733 | AIM_ERROR(aimInfo, "More than %d columns in %s is not expected!",{ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 1734, __func__ , "More than %d columns in %s is not expected!", 25, filename ); } | |||
1734 | MAX_DATA_ENTRY, filename){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 1734, __func__ , "More than %d columns in %s is not expected!", 25, filename ); }; | |||
1735 | status = CAPS_IOERR-332; | |||
1736 | goto cleanup; | |||
1737 | } | |||
1738 | } | |||
1739 | ||||
1740 | // Headers expected in output file that correspond to the AIM output names | |||
1741 | ||||
1742 | if (index == outBeta) | |||
1743 | valHeader = "Beta"; | |||
1744 | else if (index == outAlpha) | |||
1745 | valHeader = "Alpha"; | |||
1746 | else if (index == outDynamic_Pressure) | |||
1747 | valHeader = "Bars"; | |||
1748 | else if (index == outMach) | |||
1749 | valHeader = "Mach"; | |||
1750 | else if (index == outPerTrb) | |||
1751 | valHeader = "PerTrb"; | |||
1752 | else if (index == outCLtot) | |||
1753 | valHeader = "CL"; | |||
1754 | else if (index == outCDtot) | |||
1755 | valHeader = "CD"; | |||
1756 | else if (index == outCMYtot) | |||
1757 | valHeader = "Cm"; | |||
1758 | else if (index == outLoDtot) | |||
1759 | valHeader = "LoD"; | |||
1760 | else if (index == outCL_p) | |||
1761 | valHeader = "CLp"; | |||
1762 | else if (index == outCD_p) | |||
1763 | valHeader = "CDp"; | |||
1764 | else if (index == outCL_v) | |||
1765 | valHeader = "CLf"; | |||
1766 | else if (index == outCD_v) | |||
1767 | valHeader = "CDf"; | |||
1768 | else if (index == outStagnation_Temperature) | |||
1769 | valHeader = "StagTemp"; | |||
1770 | else if (index == outConvective_Flux) | |||
1771 | valHeader = "QdotConv"; | |||
1772 | else if (index == outRadiative_Flux) | |||
1773 | valHeader = "QdotRad"; | |||
1774 | else if (index == outStagnation_Radius) | |||
1775 | valHeader = "StagRadius"; | |||
1776 | else if (index == outCL_Trefftz) | |||
1777 | valHeader = "CL_Trefftz"; | |||
1778 | else if (index == outCD_Trefftz) | |||
1779 | valHeader = "CD_Trefftz"; | |||
1780 | else { | |||
1781 | AIM_ERROR(aimInfo, "Developer error: Unknown variable index %d", index){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 1781, __func__ , "Developer error: Unknown variable index %d", index); }; | |||
1782 | status = CAPS_BADINDEX-304; | |||
1783 | goto cleanup; | |||
1784 | } | |||
1785 | ||||
1786 | // Find which column contains the requested data | |||
1787 | valIndex = 0; | |||
1788 | while( valIndex < numDataEntry && | |||
1789 | strncasecmp(headers[valIndex], valHeader, strlen(valHeader)) != 0 ) valIndex++; | |||
1790 | if (valIndex == numDataEntry) { | |||
1791 | AIM_ERROR(aimInfo, "Could not find '%s' header in %s", valHeader, filename){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 1791, __func__ , "Could not find '%s' header in %s", valHeader, filename); }; | |||
1792 | status = CAPS_NOTFOUND-303; | |||
1793 | goto cleanup; | |||
1794 | } | |||
1795 | ||||
1796 | // Scan the file for the BLOCK string | |||
1797 | while (getline(&line, &linecap, fp) >= 0) { | |||
1798 | ||||
1799 | if (line == NULL((void*)0)) continue; | |||
1800 | ||||
1801 | if (strncmp(line, "BLOCK", 5) == 0) { | |||
1802 | while (getline(&line, &linecap, fp) >= 0) { | |||
1803 | if (strlen(line) == 1) break; | |||
1804 | numCase += 1; | |||
1805 | } | |||
1806 | continue; | |||
1807 | } | |||
1808 | } | |||
1809 | ||||
1810 | // Did we find any cases? | |||
1811 | if (numCase <= 0) { | |||
1812 | AIM_ERROR(aimInfo, "No BLOCK Case found in CBAero outout!"){ aim_message(aimInfo, CERROR, 0 , "cbaeroAIM.c", 1812, __func__ , "No BLOCK Case found in CBAero outout!"); }; | |||
1813 | status = CAPS_NOTFOUND-303; | |||
1814 | goto cleanup; | |||
1815 | } | |||
1816 | ||||
1817 | AIM_ALLOC(tempVal, numCase, double, aimInfo, status){ if (tempVal != ((void*)0)) { status = -4; aim_status(aimInfo , status, "cbaeroAIM.c", 1817, __func__, 1, "AIM_ALLOC: %s != NULL" , "tempVal"); goto cleanup; } size_t memorysize = numCase; tempVal = (double *) EG_alloc(memorysize*sizeof(double)); if (tempVal == ((void*)0)) { status = -4; aim_status(aimInfo, status, "cbaeroAIM.c" , 1817, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "tempVal" , memorysize, "double"); goto cleanup; } }; | |||
1818 | ||||
1819 | rewind(fp); | |||
1820 | ||||
1821 | numCase = 0; | |||
1822 | // Scan the file for the string | |||
1823 | while (getline(&line, &linecap, fp) >= 0) { | |||
1824 | AIM_NOTNULL(line, aimInfo, status){ if (line == ((void*)0)) { status = -307; aim_status(aimInfo , status, "cbaeroAIM.c", 1824, __func__, 1, "%s == NULL!", "line" ); goto cleanup; } }; | |||
1825 | ||||
1826 | if (strncmp(line, "BLOCK", 5) == 0) { | |||
1827 | ||||
1828 | while (getline(&line, &linecap, fp) >= 0) { | |||
1829 | ||||
1830 | if (strlen(line) == 1) break; | |||
1831 | ||||
1832 | rest = line; | |||
1833 | for (i = 0; i < numDataEntry; i++) { | |||
1834 | token = strtok_r(rest, " ", &rest); | |||
1835 | status = sscanf(token, "%lf", &dataLine[i]); | |||
1836 | if (status <= 0) AIM_STATUS(aimInfo, (status = CAPS_IOERR))if ((status = -332) != 0) { aim_status(aimInfo, (status = -332 ), "cbaeroAIM.c", 1836, __func__, 0); goto cleanup; }; | |||
1837 | } | |||
1838 | ||||
1839 | tempVal[numCase] = dataLine[valIndex]; | |||
1840 | numCase += 1; | |||
1841 | } | |||
1842 | } | |||
1843 | } | |||
1844 | ||||
1845 | // Transfer value(s) | |||
1846 | if (numCase > 1) { | |||
1847 | ||||
1848 | AIM_ALLOC(val->vals.reals, numCase, double, aimInfo, status){ if (val->vals.reals != ((void*)0)) { status = -4; aim_status (aimInfo, status, "cbaeroAIM.c", 1848, __func__, 1, "AIM_ALLOC: %s != NULL" , "val->vals.reals"); goto cleanup; } size_t memorysize = numCase ; val->vals.reals = (double *) EG_alloc(memorysize*sizeof( double)); if (val->vals.reals == ((void*)0)) { status = -4 ; aim_status(aimInfo, status, "cbaeroAIM.c", 1848, __func__, 3 , "AIM_ALLOC: %s size %zu type %s", "val->vals.reals", memorysize , "double"); goto cleanup; } }; | |||
1849 | ||||
1850 | for (i = 0; i < numCase; i++) { | |||
1851 | val->vals.reals[i] = tempVal[i]; | |||
1852 | } | |||
1853 | ||||
1854 | } else { | |||
1855 | ||||
1856 | val->vals.real = tempVal[0]; | |||
1857 | } | |||
1858 | ||||
1859 | val->nrow = numCase; | |||
1860 | val->ncol = 1; | |||
1861 | val->length = val->nrow*val->ncol; | |||
1862 | ||||
1863 | status = CAPS_SUCCESS0; | |||
1864 | ||||
1865 | cleanup: | |||
1866 | ||||
1867 | if (fp != NULL((void*)0)) fclose(fp); | |||
1868 | if (line != NULL((void*)0)) free(line); | |||
1869 | ||||
1870 | AIM_FREE(tempVal){ EG_free(tempVal); tempVal = ((void*)0); }; | |||
1871 | ||||
1872 | return status; | |||
1873 | } | |||
1874 | ||||
1875 | // ********************** AIM Function Break ***************************** | |||
1876 | void aimCleanup(void *instStore) | |||
1877 | { | |||
1878 | int status; // Returning status | |||
1879 | ||||
1880 | #ifdef DEBUG | |||
1881 | printf(" egadsTessAIM/aimClenup!\n"); | |||
1882 | #endif | |||
1883 | ||||
1884 | aimStorage *cbaeroInstance = (aimStorage *)instStore; | |||
1885 | ||||
1886 | // Clean up cbaeroInstance data | |||
1887 | status = destroy_aimStorage(cbaeroInstance); | |||
1888 | if (status != CAPS_SUCCESS0) printf("Status %d during destroy_aimStorage", status); | |||
1889 | ||||
1890 | AIM_FREE(cbaeroInstance){ EG_free(cbaeroInstance); cbaeroInstance = ((void*)0); }; | |||
1891 | } | |||
1892 |