File: | feaUtils.c |
Warning: | line 526, column 10 Value stored to 'refLen' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | // This software has been cleared for public release on 05 Nov 2020, case number 88ABW-2020-3462. |
2 | |
3 | #include <string.h> |
4 | #include <math.h> |
5 | |
6 | #include "aimUtil.h" // Bring in AIM utility functions |
7 | |
8 | #include "miscUtils.h" // Bring in misc. utility functions |
9 | #include "meshUtils.h" // Bring in mesh utility functions |
10 | #include "vlmUtils.h" // Bring in vortex lattice method utility functions |
11 | |
12 | #include "arrayUtils.h" // Bring in array utility functions |
13 | |
14 | #include "feaTypes.h" // Bring in FEA structures |
15 | #include "meshTypes.h" // Bring in mesh structures |
16 | #include "capsTypes.h" // Bring in CAPS types |
17 | |
18 | #include "feaUtils.h" |
19 | #include "jsonUtils.h" |
20 | |
21 | #ifdef WIN32 |
22 | #define strcasecmp stricmp |
23 | #endif |
24 | |
25 | //#define MIN(A,B) (((A) < (B)) ? (A) : (B)) |
26 | #define MAX(A,B)(((A) < (B)) ? (B) : (A)) (((A) < (B)) ? (B) : (A)) |
27 | |
28 | |
29 | |
30 | int fea_createMesh(void *aimInfo, |
31 | /*@null@*/ double paramTess[3], // (in) Tessellation parameters |
32 | int edgePointMin, // (in) minimum points along any Edge |
33 | int edgePointMax, // (in) maximum points along any Edge |
34 | int quadMesh, // (in) only do tris-for faces |
35 | mapAttrToIndexStruct *groupMap, // (in) map from CAPSGroup names to indexes |
36 | mapAttrToIndexStruct *constraintMap, // (in) map from CAPSConstraint names to indexes |
37 | mapAttrToIndexStruct *loadMap, // (in) map from CAPSLoad names to indexes |
38 | mapAttrToIndexStruct *transferMap, // (in) map from CAPSTransfer names to indexes |
39 | mapAttrToIndexStruct *connectMap, // (in) map from CAPSConnect names to indexes |
40 | mapAttrToIndexStruct *responseMap, // (in) map from CAPSResponse names to indexes |
41 | /*@null@*/ mapAttrToIndexStruct *referenceMap, // (in) map from CAPSReference names to indexes |
42 | int *numMesh, // (out) total number of FEA mesh structures |
43 | meshStruct **feaMesh, // (out) FEA mesh structure |
44 | feaProblemStruct *feaProblem ) { // (out) FEA problem structure |
45 | |
46 | int status; // Function return status |
47 | |
48 | int i, body; // Indexing |
49 | |
50 | // Bodies |
51 | const char *intents; |
52 | int numBody; // Number of Bodies |
53 | ego *bodies; |
54 | const char *discipline; |
55 | int stat, nGlobal; |
56 | |
57 | // Coordinate system |
58 | mapAttrToIndexStruct coordSystemMap, attrMapTemp1, attrMapTemp2, meshMap; |
59 | |
60 | int meshInd; |
61 | capsValue *meshVal, *meshMorphVal; |
62 | |
63 | meshStruct *feaMeshes = NULL((void*)0), tempMesh; |
64 | int *feaMeshList = NULL((void*)0); // List to seperate structural meshes for aero |
65 | |
66 | ego tempBody; |
67 | double capsMeshLength = 0, bbox[6], refLen; |
68 | |
69 | // Inherited fea/volume mesh related variables |
70 | int numFEAMesh = 0; |
71 | int feaMeshInherited = (int) false0; |
72 | |
73 | // Destroy feaMeshes |
74 | if ((*feaMesh) != NULL((void*)0)) { |
75 | |
76 | for (i = 0; i < *numMesh; i++) { |
77 | status = destroy_meshStruct(&(*feaMesh)[i]); |
78 | if (status != CAPS_SUCCESS0) printf("Error: Status %d during destroy_meshStruct!\n", status); |
79 | } |
80 | |
81 | AIM_FREE(*feaMesh){ EG_free(*feaMesh); *feaMesh = ((void*)0); }; |
82 | } |
83 | |
84 | (*feaMesh) = NULL((void*)0); |
85 | *numMesh = 0; |
86 | |
87 | // Get AIM bodies |
88 | status = aim_getBodies(aimInfo, &intents, &numBody, &bodies); |
89 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 89 , __func__, 0); goto cleanup; }; |
90 | |
91 | if ((numBody <= 0) || (bodies == NULL((void*)0))) { |
92 | AIM_ERROR(aimInfo, "No Bodies!\n"){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 92, __func__ , "No Bodies!\n"); }; |
93 | return CAPS_SOURCEERR-330; |
94 | } |
95 | |
96 | initiate_meshStruct(&tempMesh); |
97 | |
98 | // Initiate our maps |
99 | status = initiate_mapAttrToIndexStruct(&coordSystemMap); |
100 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 100 , __func__, 0); goto cleanup; }; |
101 | |
102 | status = initiate_mapAttrToIndexStruct(&attrMapTemp1); |
103 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 103 , __func__, 0); goto cleanup; }; |
104 | |
105 | status = initiate_mapAttrToIndexStruct(&attrMapTemp2); |
106 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 106 , __func__, 0); goto cleanup; }; |
107 | |
108 | status = initiate_mapAttrToIndexStruct(&meshMap); |
109 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 109 , __func__, 0); goto cleanup; }; |
110 | |
111 | // Alloc feaMesh list |
112 | AIM_ALLOC(feaMeshList, numBody, int, aimInfo ,status){ if (feaMeshList != ((void*)0)) { status = -4; aim_status(aimInfo , status, "feaUtils.c", 112, __func__, 1, "AIM_ALLOC: %s != NULL" , "feaMeshList"); goto cleanup; } size_t memorysize = numBody ; feaMeshList = (int *) EG_alloc(memorysize*sizeof(int)); if ( feaMeshList == ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 112, __func__, 3, "AIM_ALLOC: %s size %zu type %s" , "feaMeshList", memorysize, "int"); goto cleanup; } }; |
113 | |
114 | // Set all indexes to true |
115 | for (i = 0; i < numBody; i++ ) feaMeshList[i] = (int) true1; |
116 | |
117 | // Check for capsDiscipline consistency |
118 | i = 0; |
119 | for (body = 0; body < numBody; body++) { |
120 | |
121 | status = retrieve_CAPSDisciplineAttr(bodies[body], &discipline); |
122 | if (status != CAPS_SUCCESS0) continue; // Need to add an error code |
123 | |
124 | if (strcasecmp(discipline, "structure") != 0) { |
125 | feaMeshList[body] = (int) false0; |
126 | i++; |
127 | } |
128 | } |
129 | |
130 | if (i == numBody) { |
131 | AIM_ERROR(aimInfo, "No bodies with capsDiscipline Structure!"){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 131, __func__ , "No bodies with capsDiscipline Structure!"); }; |
132 | status = CAPS_BADVALUE-311; |
133 | goto cleanup; |
134 | } |
135 | |
136 | //for (body = 0; body< numBody; body++) printf("Body %i, FeaMeshList = %i\n", body, feaMeshList[body]); |
137 | |
138 | // Get CoordSystem attribute to index mapping |
139 | status = create_CoordSystemAttrToIndexMap(numBody, |
140 | bodies, |
141 | 3, //>2 - search the body, faces, edges, and all the nodes |
142 | &coordSystemMap); |
143 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 143 , __func__, 0); goto cleanup; }; |
144 | |
145 | status = fea_getCoordSystem(numBody, |
146 | bodies, |
147 | coordSystemMap, |
148 | &feaProblem->numCoordSystem, |
149 | &feaProblem->feaCoordSystem); |
150 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 150 , __func__, 0); goto cleanup; }; |
151 | |
152 | // Get capsConstraint name and index mapping |
153 | status = create_CAPSConstraintAttrToIndexMap(numBody, |
154 | bodies, |
155 | 3, //>2 - search the body, faces, edges, and all the nodes |
156 | constraintMap); |
157 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 157 , __func__, 0); goto cleanup; }; |
158 | |
159 | // Get capsLoad name and index mapping |
160 | status = create_CAPSLoadAttrToIndexMap(numBody, |
161 | bodies, |
162 | 3, //>2 - search the body, faces, edges, and all the nodes |
163 | loadMap); |
164 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 164 , __func__, 0); goto cleanup; }; |
165 | |
166 | // Get transfer to index mapping |
167 | status = create_CAPSBoundAttrToIndexMap(numBody, |
168 | bodies, |
169 | 3, //>2 - search the body, faces, edges, and all the nodes |
170 | transferMap); |
171 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 171 , __func__, 0); goto cleanup; }; |
172 | |
173 | if (connectMap != NULL((void*)0)) { |
174 | // Get connect to index mapping |
175 | status = create_CAPSConnectAttrToIndexMap(numBody, |
176 | bodies, |
177 | 3, //>2 - search the body, faces, edges, and all the nodes |
178 | connectMap); |
179 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 179 , __func__, 0); goto cleanup; }; |
180 | } |
181 | |
182 | if (responseMap != NULL((void*)0)) { |
183 | // Get response to index mapping |
184 | status = create_CAPSResponseAttrToIndexMap(numBody, |
185 | bodies, |
186 | 3, //>2 - search the body, faces, edges, and all the nodes |
187 | responseMap); |
188 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 188 , __func__, 0); goto cleanup; }; |
189 | } |
190 | |
191 | if (referenceMap != NULL((void*)0)) { |
192 | // Get response to index mapping |
193 | status = create_CAPSReferenceAttrToIndexMap(numBody, |
194 | bodies, |
195 | 3, //>2 - search the body, faces, edges, and all the nodes |
196 | referenceMap); |
197 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 197 , __func__, 0); goto cleanup; }; |
198 | } |
199 | |
200 | // Get capsGroup name and index mapping to make sure all faces have a capsGroup value |
201 | status = create_CAPSGroupAttrToIndexMap(numBody, |
202 | bodies, |
203 | 3, //>2 - search the body, faces, edges, and all the nodes |
204 | groupMap); |
205 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 205 , __func__, 0); goto cleanup; }; |
206 | |
207 | // Get the Mesh input Value |
208 | meshInd = aim_getIndex(aimInfo, "Mesh", ANALYSISIN); |
209 | if (meshInd < 1) |
210 | meshInd = aim_getIndex(aimInfo, "Surface_Mesh", ANALYSISIN); |
211 | if (meshInd < 1) { |
212 | AIM_ERROR(aimInfo, "Developer error: No 'Mesh' or 'Surface_Mesh' ANALYSISIN Index!"){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 212, __func__ , "Developer error: No 'Mesh' or 'Surface_Mesh' ANALYSISIN Index!" ); }; |
213 | status = CAPS_BADINDEX-304; |
214 | goto cleanup; |
215 | } |
216 | |
217 | status = aim_getValue(aimInfo, meshInd, ANALYSISIN, &meshVal); |
218 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 218 , __func__, 0); goto cleanup; }; |
219 | |
220 | if (meshVal->type != PointerMesh) { |
221 | AIM_ERROR(aimInfo, "Developer error! Mesh is not a PointerMesh!"){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 221, __func__ , "Developer error! Mesh is not a PointerMesh!"); }; |
222 | status = CAPS_NOTIMPLEMENT-334; |
223 | goto cleanup; |
224 | } |
225 | |
226 | // Get the Mesh_Morph input Value |
227 | meshInd = aim_getIndex(aimInfo, "Mesh_Morph", ANALYSISIN); |
228 | if (meshInd < 1) { |
229 | AIM_ERROR(aimInfo, "Developer error: No 'Mesh_Morph' ANALYSISIN Index!"){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 229, __func__ , "Developer error: No 'Mesh_Morph' ANALYSISIN Index!"); }; |
230 | status = CAPS_BADINDEX-304; |
231 | goto cleanup; |
232 | } |
233 | |
234 | status = aim_getValue(aimInfo, meshInd, ANALYSISIN, &meshMorphVal); |
235 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 235 , __func__, 0); goto cleanup; }; |
236 | |
237 | |
238 | feaMeshInherited = (int) false0; |
239 | |
240 | if ((meshVal->nullVal == NotNull) || |
241 | (meshMorphVal->vals.integer == (int) true1 && |
242 | meshVal->nullVal == IsNull)) { |
243 | |
244 | if ( meshMorphVal->vals.integer == (int) true1 && |
245 | meshVal->nullVal == IsNull ) { // If we are mighty morphing |
246 | |
247 | if (aim_newGeometry(aimInfo) == CAPS_SUCCESS0 || |
248 | feaProblem->meshRefIn == NULL((void*)0) || |
249 | feaProblem->meshRefIn != &feaProblem->meshRefObj) { |
250 | |
251 | // Lets "load" the meshRef now since it's not linked |
252 | status = aim_loadMeshRef(aimInfo, &feaProblem->meshRefObj); |
253 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 253 , __func__, 0); goto cleanup; }; |
254 | |
255 | // Mighty Morph the mesh |
256 | status = aim_morphMeshUpdate(aimInfo, &feaProblem->meshRefObj, numBody, bodies); |
257 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 257 , __func__, 0); goto cleanup; }; |
258 | } |
259 | /*@-immediatetrans@*/ |
260 | feaProblem->meshRefIn = &feaProblem->meshRefObj; |
261 | /*@+immediatetrans@*/ |
262 | } else { |
263 | feaProblem->meshRefIn = (aimMeshRef *) meshVal->vals.AIMptr; |
264 | } |
265 | |
266 | numFEAMesh = feaProblem->meshRefIn->nmap; |
267 | |
268 | // See if a FEA mesh is available from parent |
269 | if (feaProblem->meshRefIn->type == aimAreaMesh || |
270 | feaProblem->meshRefIn->type == aimSurfaceMesh) { |
271 | |
272 | if (numFEAMesh != numBody) { // May not be an error if we are doing aero-struct |
273 | |
274 | // Check for capsDiscipline consistency |
275 | for (body = 0; body < numFEAMesh; body++) { |
276 | // Dummy arguments |
277 | status = EG_statusTessBody(feaProblem->meshRefIn->maps[body].tess, &tempBody, &stat, &nGlobal); |
278 | if (status != EGADS_SUCCESS0) goto cleanup; |
279 | |
280 | status = retrieve_CAPSDisciplineAttr(tempBody, &discipline); |
281 | if (status != EGADS_SUCCESS0) { |
282 | AIM_ERROR (aimInfo, "Failed to find a capsDiscipline attribute!\n"){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 282, __func__ , "Failed to find a capsDiscipline attribute!\n"); }; |
283 | AIM_ADDLINE(aimInfo, "Number of linked surface meshes does not match the number of bodies, this is only allowed if doing aero-struct analysis\n"){ aim_addLine(aimInfo, "Number of linked surface meshes does not match the number of bodies, this is only allowed if doing aero-struct analysis\n" ); }; |
284 | status= CAPS_SOURCEERR-330; |
285 | goto cleanup; |
286 | } |
287 | |
288 | if (strcasecmp(discipline, "structure") != 0) { |
289 | AIM_ERROR (aimInfo, "Failed to find a capsDiscipline attribute - 'structure'!\n"){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 289, __func__ , "Failed to find a capsDiscipline attribute - 'structure'!\n" ); }; |
290 | AIM_ADDLINE(aimInfo, "Number of linked surface meshes does not match the number of bodies, this is only allowed if doing aero-struct analysis\n"){ aim_addLine(aimInfo, "Number of linked surface meshes does not match the number of bodies, this is only allowed if doing aero-struct analysis\n" ); }; |
291 | status= CAPS_SOURCEERR-330; |
292 | goto cleanup; |
293 | } |
294 | |
295 | // need a check to make sure all tempMesh->groupMap are identical |
296 | } |
297 | |
298 | // We need to update our capsGroup attribute map |
299 | |
300 | // Get capsGroup name and index mapping to make sure all faces have a capsGroup value |
301 | status = create_CAPSGroupAttrToIndexMap(numBody, |
302 | bodies, |
303 | 3, //>2 - search the body, faces, edges, and all the nodes |
304 | &attrMapTemp2); |
305 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 305 , __func__, 0); goto cleanup; }; |
306 | |
307 | // Get attribute to index mapping |
308 | status = create_MeshRefToIndexMap(aimInfo, feaProblem->meshRefIn, &attrMapTemp1); |
309 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 309 , __func__, 0); goto cleanup; }; |
310 | |
311 | status = merge_mapAttrToIndexStruct(&attrMapTemp1, &attrMapTemp2, groupMap); |
312 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 312 , __func__, 0); goto cleanup; }; |
313 | } |
314 | |
315 | AIM_ALLOC(feaMeshes, numFEAMesh, meshStruct, aimInfo, status){ if (feaMeshes != ((void*)0)) { status = -4; aim_status(aimInfo , status, "feaUtils.c", 315, __func__, 1, "AIM_ALLOC: %s != NULL" , "feaMeshes"); goto cleanup; } size_t memorysize = numFEAMesh ; feaMeshes = (meshStruct *) EG_alloc(memorysize*sizeof(meshStruct )); if (feaMeshes == ((void*)0)) { status = -4; aim_status(aimInfo , status, "feaUtils.c", 315, __func__, 3, "AIM_ALLOC: %s size %zu type %s" , "feaMeshes", memorysize, "meshStruct"); goto cleanup; } }; |
316 | for (body = 0; body < numFEAMesh; body++) (void) initiate_meshStruct(&feaMeshes[body]); |
317 | |
318 | for (body = 0; body < numFEAMesh; body++) { |
319 | |
320 | status = copy_mapAttrToIndexStruct( groupMap, |
321 | &tempMesh.groupMap ); |
322 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 322 , __func__, 0); goto cleanup; }; |
323 | |
324 | tempMesh.egadsTess = feaProblem->meshRefIn->maps[body].tess; |
325 | status = mesh_surfaceMeshEGADSTess(aimInfo, &tempMesh, (int)(feaProblem->meshRefIn->type == aimAreaMesh)); |
326 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 326 , __func__, 0); goto cleanup; }; |
327 | |
328 | // Create a new mesh with topology tagged with capsIgnore being removed, if capsIgnore isn't found the mesh is simply copied. |
329 | status = mesh_createIgnoreMesh(&tempMesh, &feaMeshes[body]); |
330 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 330 , __func__, 0); goto cleanup; }; |
331 | |
332 | destroy_meshStruct(&tempMesh); |
333 | |
334 | // Change the analysis type of the mesh |
335 | status = mesh_setAnalysisType(MeshStructure, &feaMeshes[body]); |
336 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 336 , __func__, 0); goto cleanup; }; |
337 | |
338 | |
339 | // Get FEA Problem from EGADs body |
340 | status = fea_setAnalysisData(aimInfo, |
341 | groupMap, |
342 | &coordSystemMap, |
343 | constraintMap, |
344 | loadMap, |
345 | transferMap, |
346 | connectMap, |
347 | responseMap, |
348 | referenceMap, |
349 | &feaMeshes[body]); |
350 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 350 , __func__, 0); goto cleanup; }; |
351 | |
352 | status = mesh_fillQuickRefList( &feaMeshes[body]); |
353 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 353 , __func__, 0); goto cleanup; }; |
354 | |
355 | printf("\tMesh for body = %d\n", body); |
356 | printf("\tNumber of nodal coordinates = %d\n", feaMeshes[body].numNode); |
357 | printf("\tNumber of elements = %d\n", feaMeshes[body].numElement); |
358 | printf("\tElemental Nodes = %d\n", feaMeshes[body].meshQuickRef.numNode); |
359 | printf("\tElemental Rods = %d\n", feaMeshes[body].meshQuickRef.numLine); |
360 | printf("\tElemental Tria3 = %d\n", feaMeshes[body].meshQuickRef.numTriangle); |
361 | printf("\tElemental Quad4 = %d\n", feaMeshes[body].meshQuickRef.numQuadrilateral); |
362 | } |
363 | |
364 | |
365 | if (numFEAMesh > 1) { |
366 | printf("Combining multiple FEA meshes!\n"); |
367 | } |
368 | |
369 | status = mesh_combineMeshStruct(numFEAMesh, |
370 | feaMeshes, |
371 | &feaProblem->feaMesh); |
372 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 372 , __func__, 0); goto cleanup; }; |
373 | |
374 | if (numFEAMesh > 1) { |
375 | printf("\tCombined Number of nodal coordinates = %d\n", feaProblem->feaMesh.numNode); |
376 | printf("\tCombined Number of elements = %d\n", feaProblem->feaMesh.numElement); |
377 | printf("\tCombined Elemental Nodes = %d\n", feaProblem->feaMesh.meshQuickRef.numNode); |
378 | printf("\tCombined Elemental Rods = %d\n", feaProblem->feaMesh.meshQuickRef.numLine); |
379 | printf("\tCombined Elemental Tria3 = %d\n", feaProblem->feaMesh.meshQuickRef.numTriangle); |
380 | printf("\tCombined Elemental Quad4 = %d\n", feaProblem->feaMesh.meshQuickRef.numQuadrilateral); |
381 | } |
382 | |
383 | // Set output meshes |
384 | *numMesh = numFEAMesh; |
385 | *feaMesh = feaMeshes; |
386 | feaMeshes = NULL((void*)0); |
387 | |
388 | // Set reference meshes |
389 | feaProblem->feaMesh.numReferenceMesh = *numMesh; |
390 | feaProblem->feaMesh.referenceMesh = (meshStruct *) EG_alloc(*numMesh*sizeof(meshStruct)); |
391 | if (feaProblem->feaMesh.referenceMesh == NULL((void*)0)) { |
392 | status = EGADS_MALLOC-4; |
393 | goto cleanup; |
394 | } |
395 | |
396 | for (body = 0; body < *numMesh; body++) { |
397 | feaProblem->feaMesh.referenceMesh[body] = (*feaMesh)[body]; |
398 | } |
399 | |
400 | } else { // Check to see if a general unstructured volume mesh is available |
401 | |
402 | printf("Found link for a volume mesh (Volume_Mesh) from parent\n"); |
403 | |
404 | numFEAMesh = 1; |
405 | if (numFEAMesh != 1) { |
406 | AIM_ERROR(aimInfo, "Can not accept multiple volume meshes"){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 406, __func__ , "Can not accept multiple volume meshes"); }; |
407 | status = CAPS_BADVALUE-311; |
408 | goto cleanup; |
409 | } |
410 | |
411 | if (numFEAMesh != numBody) { |
412 | printf("Number of inherited volume meshes does not match the number of bodies - assuming volume mesh is already combined\n"); |
413 | } |
414 | |
415 | AIM_ERROR(aimInfo, "Volume meshes not yet supported for structural analysis"){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 415, __func__ , "Volume meshes not yet supported for structural analysis"); }; |
416 | status = CAPS_BADVALUE-311; |
417 | goto cleanup; |
418 | |
419 | #if 0 |
420 | tempMesh = (meshStruct *) meshVal->vals.AIMptr; |
421 | status = mesh_copyMeshStruct( tempMesh, &feaProblem->feaMesh); |
422 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 422 , __func__, 0); goto cleanup; }; |
423 | |
424 | //feaProblem->feaMesh.egadsTess = |
425 | status = mesh_surfaceMeshEGADSTess(aimInfo, &feaProblem->feaMesh.egadsTess, (int)false0); |
426 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 426 , __func__, 0); goto cleanup; }; |
427 | |
428 | |
429 | // Set reference meshes |
430 | feaProblem->feaMesh.numReferenceMesh = tempMesh->numReferenceMesh; |
431 | feaProblem->feaMesh.referenceMesh = (meshStruct *) EG_alloc(tempMesh->numReferenceMesh*sizeof(meshStruct)); |
432 | if (feaProblem->feaMesh.referenceMesh == NULL((void*)0)) { |
433 | status = EGADS_MALLOC-4; |
434 | goto cleanup; |
435 | } |
436 | |
437 | for (body = 0; body < tempMesh->numReferenceMesh; body++) { |
438 | feaProblem->feaMesh.referenceMesh[body] = tempMesh->referenceMesh[body]; |
439 | } |
440 | |
441 | for (i = 0; i < feaProblem->feaMesh.numReferenceMesh; i++) { |
442 | |
443 | status = aim_newTess(aimInfo, |
444 | feaProblem->feaMesh.referenceMesh[i].egadsTess); |
445 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 445 , __func__, 0); goto cleanup; }; |
446 | } |
447 | |
448 | // Update/change the analysis data in a meshStruct |
449 | status = change_meshAnalysis(&feaProblem->feaMesh, MeshStructure); |
450 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 450 , __func__, 0); goto cleanup; }; |
451 | |
452 | // Get FEA Problem from EGADs body |
453 | status = fea_setAnalysisData(aimInfo, |
454 | groupMap, |
455 | &coordSystemMap, |
456 | constraintMap, |
457 | loadMap, |
458 | transferMap, |
459 | connectMap, |
460 | responseMap, |
461 | referenceMap, |
462 | &feaProblem->feaMesh); |
463 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 463 , __func__, 0); goto cleanup; }; |
464 | #endif |
465 | } |
466 | |
467 | feaMeshInherited = (int) true1; |
468 | } |
469 | |
470 | // If we didn't inherit a FEA mesh we need to get one ourselves |
471 | if (feaMeshInherited == (int) false0) { |
472 | |
473 | status = check_CAPSMeshLength(numBody, bodies, &capsMeshLength); |
474 | |
475 | if (status == CAPS_NOTFOUND-303) capsMeshLength = -1; |
476 | else AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 476 , __func__, 0); goto cleanup; }; |
477 | |
478 | /* |
479 | if (capsMeshLength <= 0 || status != CAPS_SUCCESS) { |
480 | printf("**********************************************************\n"); |
481 | if (status != CAPS_SUCCESS) |
482 | printf("capsMeshLength is not set on any body.\n"); |
483 | else |
484 | printf("capsMeshLength: %f\n", capsMeshLength); |
485 | printf("\n"); |
486 | printf("The capsMeshLength attribute must\n" |
487 | "present on at least one body.\n" |
488 | "\n" |
489 | "capsMeshLength should be a a positive value representative\n" |
490 | "of a characteristic length of the geometry,\n" |
491 | "e.g. the MAC of a wing or diameter of a fuselage.\n"); |
492 | printf("**********************************************************\n"); |
493 | status = CAPS_BADVALUE; |
494 | goto cleanup; |
495 | }*/ |
496 | |
497 | if (paramTess == NULL((void*)0)) { |
498 | AIM_ERROR(aimInfo, "Developer error paramTess == NULL"){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 498, __func__ , "Developer error paramTess == NULL"); }; |
499 | status = CAPS_BADVALUE-311; |
500 | goto cleanup; |
501 | } |
502 | |
503 | if (edgePointMin < 2) { |
504 | printf("The minimum number of allowable edge points is 2 not %d\n", edgePointMin); |
505 | edgePointMin = 2; |
506 | } |
507 | |
508 | if (edgePointMax < edgePointMin) { |
509 | printf("The maximum number of edge points must be greater than the current minimum (%d)\n", edgePointMin); |
510 | edgePointMax = edgePointMin+1; |
511 | } |
512 | |
513 | if (capsMeshLength <= 0) { |
514 | refLen = 0; |
515 | for (body = 0; body < numBody; body++) { |
516 | if (feaMeshList[body] != (int) true1) continue; |
517 | |
518 | status = EG_getBoundingBox(bodies[body], bbox); |
519 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 519 , __func__, 0); goto cleanup; }; |
520 | |
521 | refLen = MAX(refLen, sqrt( (bbox[3] - bbox[0]) * (bbox[3] - bbox[0])(((refLen) < (sqrt( (bbox[3] - bbox[0]) * (bbox[3] - bbox[ 0]) +(bbox[4] - bbox[1]) * (bbox[4] - bbox[1]) +(bbox[5] - bbox [2]) * (bbox[5] - bbox[2])))) ? (sqrt( (bbox[3] - bbox[0]) * ( bbox[3] - bbox[0]) +(bbox[4] - bbox[1]) * (bbox[4] - bbox[1]) +(bbox[5] - bbox[2]) * (bbox[5] - bbox[2]))) : (refLen)) |
522 | +(bbox[4] - bbox[1]) * (bbox[4] - bbox[1])(((refLen) < (sqrt( (bbox[3] - bbox[0]) * (bbox[3] - bbox[ 0]) +(bbox[4] - bbox[1]) * (bbox[4] - bbox[1]) +(bbox[5] - bbox [2]) * (bbox[5] - bbox[2])))) ? (sqrt( (bbox[3] - bbox[0]) * ( bbox[3] - bbox[0]) +(bbox[4] - bbox[1]) * (bbox[4] - bbox[1]) +(bbox[5] - bbox[2]) * (bbox[5] - bbox[2]))) : (refLen)) |
523 | +(bbox[5] - bbox[2]) * (bbox[5] - bbox[2])))(((refLen) < (sqrt( (bbox[3] - bbox[0]) * (bbox[3] - bbox[ 0]) +(bbox[4] - bbox[1]) * (bbox[4] - bbox[1]) +(bbox[5] - bbox [2]) * (bbox[5] - bbox[2])))) ? (sqrt( (bbox[3] - bbox[0]) * ( bbox[3] - bbox[0]) +(bbox[4] - bbox[1]) * (bbox[4] - bbox[1]) +(bbox[5] - bbox[2]) * (bbox[5] - bbox[2]))) : (refLen)); |
524 | } |
525 | } else { |
526 | refLen = capsMeshLength; |
Value stored to 'refLen' is never read | |
527 | } |
528 | |
529 | // Modify the EGADS body tessellation based on given inputs |
530 | /*@-nullpass@*/ |
531 | status = mesh_modifyBodyTess(0, |
532 | NULL((void*)0), |
533 | edgePointMin, |
534 | edgePointMax, |
535 | quadMesh, |
536 | &capsMeshLength, |
537 | paramTess, |
538 | meshMap, |
539 | numBody, |
540 | bodies); |
541 | /*@+nullpass@*/ |
542 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 542 , __func__, 0); goto cleanup; }; |
543 | |
544 | for (body = 0; body < numBody; body++) { |
545 | if (feaMeshList[body] != (int) true1) continue; |
546 | |
547 | if (capsMeshLength > 0) { |
548 | refLen = capsMeshLength; |
549 | } else { |
550 | status = EG_getBoundingBox(bodies[body], bbox); |
551 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 551 , __func__, 0); goto cleanup; }; |
552 | |
553 | refLen = sqrt( (bbox[3] - bbox[0]) * (bbox[3] - bbox[0]) |
554 | +(bbox[4] - bbox[1]) * (bbox[4] - bbox[1]) |
555 | +(bbox[5] - bbox[2]) * (bbox[5] - bbox[2])); |
556 | } |
557 | |
558 | status = copy_mapAttrToIndexStruct( groupMap, |
559 | &tempMesh.groupMap ); |
560 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 560 , __func__, 0); goto cleanup; }; |
561 | |
562 | status = mesh_surfaceMeshEGADSBody(aimInfo, |
563 | bodies[body], |
564 | refLen, |
565 | paramTess, |
566 | quadMesh, |
567 | &tempMesh.egadsTess); |
568 | AIM_STATUS(aimInfo, status, "Problem during surface meshing of body %d", body+1)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 568 , __func__, 2, "Problem during surface meshing of body %d", body +1); goto cleanup; }; |
569 | AIM_NOTNULL(tempMesh.egadsTess, aimInfo, status){ if (tempMesh.egadsTess == ((void*)0)) { status = -307; aim_status (aimInfo, status, "feaUtils.c", 569, __func__, 1, "%s == NULL!" , "tempMesh.egadsTess"); goto cleanup; } }; |
570 | |
571 | status = mesh_surfaceMeshEGADSTess(aimInfo, &tempMesh, (int)false0); |
572 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 572 , __func__, 0); goto cleanup; }; |
573 | |
574 | *numMesh += 1; |
575 | AIM_REALL(*feaMesh, *numMesh, meshStruct, aimInfo, status){ size_t memorysize = *numMesh; *feaMesh = (meshStruct *) EG_reall (*feaMesh, memorysize*sizeof(meshStruct)); if (*feaMesh == (( void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c" , 575, __func__, 3, "AIM_REALL: %s size %zu type %s", "*feaMesh" , memorysize, "meshStruct"); goto cleanup; } }; |
576 | |
577 | status = initiate_meshStruct(&(*feaMesh)[*numMesh-1]); |
578 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 578 , __func__, 0); goto cleanup; }; |
579 | |
580 | // Create a new mesh with topology tagged with capsIgnore being removed, if capsIgnore isn't found the mesh is simply copied. |
581 | status = mesh_createIgnoreMesh(&tempMesh, &(*feaMesh)[*numMesh-1]); |
582 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 582 , __func__, 0); goto cleanup; }; |
583 | |
584 | destroy_meshStruct(&tempMesh); |
585 | |
586 | // Change the analysis type of the mesh |
587 | status = mesh_setAnalysisType(MeshStructure, &(*feaMesh)[*numMesh-1]); |
588 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 588 , __func__, 0); goto cleanup; }; |
589 | |
590 | // Get FEA Problem from EGADs body |
591 | status = fea_setAnalysisData(aimInfo, |
592 | groupMap, |
593 | &coordSystemMap, |
594 | constraintMap, |
595 | loadMap, |
596 | transferMap, |
597 | connectMap, |
598 | responseMap, |
599 | referenceMap, |
600 | &(*feaMesh)[*numMesh-1]); |
601 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 601 , __func__, 0); goto cleanup; }; |
602 | |
603 | status = mesh_fillQuickRefList( &(*feaMesh)[*numMesh-1]); |
604 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 604 , __func__, 0); goto cleanup; }; |
605 | |
606 | |
607 | #if 0 |
608 | // Get FEA Problem from EGADs body |
609 | status = fea_bodyToBEM(aimInfo, |
610 | bodies[body], // (in) EGADS Body |
611 | paramTess, // (in) Tessellation parameters |
612 | edgePointMin, // (in) minimum points along any Edge |
613 | edgePointMax, // (in) maximum points along any Edge |
614 | quadMesh, |
615 | groupMap, |
616 | &coordSystemMap, |
617 | constraintMap, |
618 | loadMap, |
619 | transferMap, |
620 | connectMap, |
621 | responseMap, |
622 | referenceMap, |
623 | &(*feaMesh)[*numMesh-1]); |
624 | #endif |
625 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 625 , __func__, 0); goto cleanup; }; |
626 | printf("\tMesh for body = %d\n", body); |
627 | printf("\tNumber of nodal coordinates = %d\n", (*feaMesh)[*numMesh-1].numNode); |
628 | printf("\tNumber of elements = %d\n", (*feaMesh)[*numMesh-1].numElement); |
629 | printf("\tElemental Nodes = %d\n", (*feaMesh)[*numMesh-1].meshQuickRef.numNode); |
630 | printf("\tElemental Rods = %d\n", (*feaMesh)[*numMesh-1].meshQuickRef.numLine); |
631 | printf("\tElemental Tria3 = %d\n", (*feaMesh)[*numMesh-1].meshQuickRef.numTriangle); |
632 | printf("\tElemental Quad4 = %d\n", (*feaMesh)[*numMesh-1].meshQuickRef.numQuadrilateral); |
633 | |
634 | // set the resulting tessellation |
635 | status = aim_newTess(aimInfo, (*feaMesh)[*numMesh-1].egadsTess); |
636 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 636 , __func__, 0); goto cleanup; }; |
637 | } |
638 | |
639 | // Only compbine if there are actual meshes |
640 | if (*numMesh > 0) { |
641 | if (*numMesh > 1) printf("Combining multiple FEA meshes!\n"); |
642 | |
643 | // Combine fea meshes into a single mesh for the problem |
644 | status = mesh_combineMeshStruct(*numMesh, |
645 | (*feaMesh), |
646 | &feaProblem->feaMesh); |
647 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 647 , __func__, 0); goto cleanup; }; |
648 | |
649 | if (*numMesh > 1) { |
650 | printf("\tCombined Number of nodal coordinates = %d\n", feaProblem->feaMesh.numNode); |
651 | printf("\tCombined Number of elements = %d\n", feaProblem->feaMesh.numElement); |
652 | printf("\tCombined Elemental Nodes = %d\n", feaProblem->feaMesh.meshQuickRef.numNode); |
653 | printf("\tCombined Elemental Rods = %d\n", feaProblem->feaMesh.meshQuickRef.numLine); |
654 | printf("\tCombined Elemental Tria3 = %d\n", feaProblem->feaMesh.meshQuickRef.numTriangle); |
655 | printf("\tCombined Elemental Quad4 = %d\n", feaProblem->feaMesh.meshQuickRef.numQuadrilateral); |
656 | } |
657 | |
658 | // Set reference meshes |
659 | feaProblem->feaMesh.numReferenceMesh = *numMesh; |
660 | feaProblem->feaMesh.referenceMesh = (meshStruct *) EG_alloc(*numMesh*sizeof(meshStruct)); |
661 | if (feaProblem->feaMesh.referenceMesh == NULL((void*)0)) { |
662 | status = EGADS_MALLOC-4; |
663 | goto cleanup; |
664 | } |
665 | |
666 | for (body = 0; body < *numMesh; body++) { |
667 | feaProblem->feaMesh.referenceMesh[body] = (*feaMesh)[body]; |
668 | } |
669 | } |
670 | } |
671 | status = CAPS_SUCCESS0; |
672 | |
673 | cleanup: |
674 | |
675 | AIM_FREE(feaMeshes){ EG_free(feaMeshes); feaMeshes = ((void*)0); }; |
676 | AIM_FREE(feaMeshList){ EG_free(feaMeshList); feaMeshList = ((void*)0); }; |
677 | |
678 | (void ) destroy_mapAttrToIndexStruct(&coordSystemMap); |
679 | |
680 | (void ) destroy_mapAttrToIndexStruct(&attrMapTemp1); |
681 | (void ) destroy_mapAttrToIndexStruct(&attrMapTemp2); |
682 | |
683 | return status; |
684 | } |
685 | |
686 | // Convert an EGADS body to a boundary element model, modified by Ryan Durscher (AFRL) |
687 | // from code originally written by John Dannenhoffer @ Syracuse University, patterned after code |
688 | // written by Bob Haimes @ MIT |
689 | int fea_bodyToBEM(void *aimInfo, // (in) AIM structure |
690 | ego ebody, // (in) EGADS Body |
691 | double paramTess[3], // (in) Tessellation parameters |
692 | int edgePointMin, // (in) minimum points along any Edge |
693 | int edgePointMax, // (in) maximum points along any Edge |
694 | int quadMesh, // (in) 0 - only do tris-for faces, 1 - mixed quad/tri, 2 - regularized quads |
695 | mapAttrToIndexStruct *attrMap, // (in) map from CAPSGroup names to indexes |
696 | mapAttrToIndexStruct *coordSystemMap,// (in) map from CoordSystem names to indexes |
697 | mapAttrToIndexStruct *constraintMap, // (in) map from CAPSConstraint names to indexes |
698 | mapAttrToIndexStruct *loadMap, // (in) map from CAPSLoad names to indexes |
699 | mapAttrToIndexStruct *transferMap, // (in) map from CAPSTransfer names to indexes |
700 | mapAttrToIndexStruct *connectMap, // (in) map from CAPSConnect names to indexes |
701 | mapAttrToIndexStruct *responseMap, // (in) map from CAPSResponse names to indexes |
702 | mapAttrToIndexStruct *referenceMap, // (in) map from CAPSReference names to indexes |
703 | meshStruct *feaMesh) // (out) FEA mesh structure |
704 | { |
705 | int status = 0; // Function return status |
706 | |
707 | int isNodeBody; |
708 | int i, j, k, face, edge, patch; // Indexing |
709 | double scale; |
710 | |
711 | // Body entities |
712 | int numNode = 0, numEdge = 0, numFace = 0; |
713 | ego *enodes=NULL((void*)0), *eedges=NULL((void*)0), *efaces=NULL((void*)0); |
714 | |
715 | int atype, alen; // EGADS return variables |
716 | const int *ints; |
717 | const double *reals; |
718 | const char *string; |
719 | |
720 | // Meshing |
721 | int numPoint = 0, numTri = 0; |
722 | const int *triConn = NULL((void*)0), *triNeighbor = NULL((void*)0); // Triangle |
723 | |
724 | int numPatch = 0; // Patching |
725 | int n1, n2, *qints = NULL((void*)0); |
726 | |
727 | int gID; // Global id |
728 | |
729 | const double *xyz, *uv; |
730 | |
731 | const int *ptype = NULL((void*)0), *pindex = NULL((void*)0), *pvindex = NULL((void*)0), *pbounds = NULL((void*)0); |
732 | |
733 | int periodic, nchange, oclass, mtype, nchild, nchild2, *senses; |
734 | |
735 | // Edge point distributions |
736 | int *points=NULL((void*)0), *isouth=NULL((void*)0), *ieast=NULL((void*)0), *inorth=NULL((void*)0), *iwest=NULL((void*)0); |
737 | double params[3], bbox[6], size, range[2], arclen, data[4], eval[18], eval2[18]; |
738 | double *rpos=NULL((void*)0); |
739 | ego eref, *echilds, *echilds2, eloop, tempBody, topObj, prev, next; |
740 | |
741 | int bodySubType = 0; // Body classification |
742 | |
743 | int pointType, pointTopoIndex; |
744 | double xyzPoint[3], xyzNode[3]; |
745 | |
746 | // Attributues |
747 | const char *attrName; |
748 | int attrIndex, coordSystemIndex, loadIndex; |
749 | |
750 | int numElement = 0; // Number of elements |
751 | int coordID = 0; // Default coordinate id for mesh |
752 | |
753 | feaMeshDataStruct *feaData; |
754 | |
755 | meshElementStruct *tempElement = NULL((void*)0); |
756 | |
757 | // In case our geometry has ignores |
758 | int ignoreFound = (int) false0; |
759 | |
760 | // --------------------------------------------------------------- |
761 | |
762 | printf("Creating FEA BEM\n"); |
763 | |
764 | // Check for contradiction where quading is requested but dissabled on the body |
765 | if (quadMesh == (int)true1) { |
766 | status = EG_attributeRet(ebody, ".qParams", &atype, &alen, &ints, &reals, &string); |
767 | if (status == EGADS_SUCCESS0 && (atype != ATTRREAL2 || (atype == ATTRREAL2 && reals[0] <= 0 ))) { |
768 | printf("\tQuading on all faces disabled with .qParams attribute on the body\n"); |
769 | quadMesh = (int) false0; |
770 | } |
771 | } |
772 | |
773 | // Get number of Nodes, Edges, and Faces in ebody |
774 | status = EG_getBodyTopos(ebody, NULL((void*)0), NODE20, &numNode, &enodes); |
775 | if (status < EGADS_SUCCESS0) goto cleanup; |
776 | |
777 | status = EG_getBodyTopos(ebody, NULL((void*)0), EDGE21, &numEdge, &eedges); |
778 | if (status != EGADS_SUCCESS0) goto cleanup; |
779 | |
780 | status = EG_getBodyTopos(ebody, NULL((void*)0), FACE23, &numFace, &efaces); |
781 | if (status < EGADS_SUCCESS0) goto cleanup; |
782 | |
783 | // What type of BODY do we have? |
784 | isNodeBody = aim_isNodeBody(ebody, xyzNode); |
785 | if (isNodeBody < EGADS_SUCCESS0) goto cleanup; |
786 | if (isNodeBody == EGADS_SUCCESS0) { |
787 | // all attributes are on the body rather than the node for a node body |
788 | enodes[0] = ebody; |
789 | } |
790 | |
791 | // Determine the nominal number of points along each Edge |
792 | points = (int *) EG_alloc((numEdge+1) *sizeof(int )); |
793 | rpos = (double *) EG_alloc((edgePointMax)*sizeof(double)); |
794 | if (points == NULL((void*)0) || rpos == NULL((void*)0)) { |
795 | status = EGADS_MALLOC-4; |
796 | printf("\tError in fea_bodyToBEM: EG_alloc\n"); |
797 | goto cleanup; |
798 | } |
799 | |
800 | status = EG_getBoundingBox(ebody, bbox); |
801 | if (status < EGADS_SUCCESS0) { |
802 | printf("\tError in fea_bodyToBEM: EG_getBoundingBox\n"); |
803 | goto cleanup; |
804 | } |
805 | |
806 | size = sqrt( (bbox[3] - bbox[0]) * (bbox[3] - bbox[0]) |
807 | +(bbox[4] - bbox[1]) * (bbox[4] - bbox[1]) |
808 | +(bbox[5] - bbox[2]) * (bbox[5] - bbox[2])); |
809 | |
810 | params[0] = paramTess[0] * size; |
811 | params[1] = paramTess[1] * size; |
812 | params[2] = paramTess[2]; |
813 | |
814 | status = EG_attributeAdd(ebody, ".tParam", ATTRREAL2, 3, NULL((void*)0), params, NULL((void*)0)); |
815 | if (status < EGADS_SUCCESS0) { |
816 | printf("\tError in fea_bodyToBEM: EG_attributeAdd\n"); |
817 | goto cleanup; |
818 | } |
819 | |
820 | if (isNodeBody == EGADS_SUCCESS0) |
821 | params[0] = 1; // does not matter but can't be zero |
822 | |
823 | if (params[0] <= 0.0) { |
824 | printf("\tError in fea_bodyToBEM: params[0] = %f must be a positive number!\n", params[0]); |
825 | status = CAPS_BADVALUE-311; |
826 | goto cleanup; |
827 | } |
828 | |
829 | for (i = 1; i <= numEdge; i++) { |
830 | status = EG_getRange(eedges[i-1], range, &periodic); |
831 | if (status < EGADS_SUCCESS0) { |
832 | printf("\tError in fea_bodyToBEM: EG_getRange\n"); |
833 | goto cleanup; |
834 | } |
835 | |
836 | status = EG_arcLength(eedges[i-1], range[0], range[1], &arclen); |
837 | if (status < EGADS_SUCCESS0) { |
838 | printf("\tError in fea_bodyToBEM: EG_arcLength\n"); |
839 | goto cleanup; |
840 | } |
841 | |
842 | //points[i] = MIN(MAX(MAX(edgePointMin,2), (int)(1+arclen/params[0])), edgePointMax); |
843 | points[i] = (int) min_DoubleVal( |
844 | max_DoubleVal( |
845 | max_DoubleVal( (double) edgePointMin, 2.0), |
846 | (double) (1+arclen/params[0])), |
847 | (double) edgePointMax); |
848 | } |
849 | |
850 | |
851 | // make arrays for "opposite" sides of four-sided Faces (with only one loop) |
852 | isouth = (int *) EG_alloc((numFace+1)*sizeof(int)); |
853 | ieast = (int *) EG_alloc((numFace+1)*sizeof(int)); |
854 | inorth = (int *) EG_alloc((numFace+1)*sizeof(int)); |
855 | iwest = (int *) EG_alloc((numFace+1)*sizeof(int)); |
856 | |
857 | if (isouth == NULL((void*)0) || |
858 | ieast == NULL((void*)0) || |
859 | inorth == NULL((void*)0) || |
860 | iwest == NULL((void*)0) ) { |
861 | |
862 | status = EGADS_MALLOC-4; |
863 | printf("\tError in fea_bodyToBEM: EG_alloc\n"); |
864 | goto cleanup; |
865 | } |
866 | |
867 | for (i = 1; i <= numFace; i++) { |
868 | isouth[i] = 0; |
869 | ieast [i] = 0; |
870 | inorth[i] = 0; |
871 | iwest [i] = 0; |
872 | |
873 | // nothing to check if quading isn't requested |
874 | if (quadMesh == (int) false0) |
875 | continue; |
876 | |
877 | // check if quading is disabled with .qParams |
878 | status = EG_attributeRet(efaces[i-1], ".qParams", &atype, &alen, &ints, &reals, &string); |
879 | if (status == EGADS_SUCCESS0 && (atype != ATTRREAL2 || (atype == ATTRREAL2 && reals[0] <= 0 ))) { |
880 | printf("\tFace %d quading disabled with attribute .qParams\n", i); |
881 | continue; |
882 | } |
883 | |
884 | // quading only works with one loop |
885 | status = EG_getTopology(efaces[i-1], &eref, &oclass, &mtype, data, &nchild, &echilds, &senses); |
886 | if (status < EGADS_SUCCESS0) goto cleanup; |
887 | |
888 | if (nchild != 1) continue; |
889 | |
890 | // quading only works if the loop has 4 edges |
891 | eloop = echilds[0]; |
892 | status = EG_getTopology(eloop, &eref, &oclass, &mtype, data, &nchild, &echilds, &senses); |
893 | if (status < EGADS_SUCCESS0) goto cleanup; |
894 | |
895 | if (nchild != 4) continue; |
896 | |
897 | // Check to see if two "straight" edges next to each other are parallel - Don't Quad if so |
898 | for (j = 0; j < 4; j++) { |
899 | |
900 | status = EG_getTopology(echilds[j], &eref, &oclass, &mtype, data, &nchild2, &echilds2, &senses); |
901 | if (mtype == DEGENERATE5) { status = EGADS_DEGEN-24; break; } |
902 | if (status < EGADS_SUCCESS0) goto cleanup; |
903 | |
904 | if (j < 3) k = j+1; |
905 | else k = 0; |
906 | |
907 | status = EG_getTopology(echilds[k], &eref, &oclass, &mtype, range, &nchild2, &echilds2, &senses); |
908 | if (mtype == DEGENERATE5) { status = EGADS_DEGEN-24; break; } |
909 | if (status < EGADS_SUCCESS0) goto cleanup; |
910 | |
911 | status = EG_evaluate(echilds[j], data, eval); |
912 | if (status < EGADS_SUCCESS0) goto cleanup; |
913 | |
914 | status = EG_evaluate(echilds[k], range, eval2); |
915 | if (status < EGADS_SUCCESS0) goto cleanup; |
916 | |
917 | scale = dot_DoubleVal(&eval[3], &eval[3]); |
918 | eval[3] /= scale; |
919 | eval[4] /= scale; |
920 | eval[5] /= scale; |
921 | |
922 | scale = dot_DoubleVal(&eval2[3], &eval2[3]); |
923 | eval2[3] /= scale; |
924 | eval2[4] /= scale; |
925 | eval2[5] /= scale; |
926 | |
927 | if (fabs(fabs(dot_DoubleVal(&eval[3], &eval2[3])) - 1) < 1E-6) { |
928 | status = EGADS_OUTSIDE1; |
929 | break; |
930 | } |
931 | } |
932 | |
933 | if (status == EGADS_OUTSIDE1) { |
934 | if (quadMesh == (int)true1) { |
935 | printf("Face %d has parallel edges - not quading\n", i); |
936 | } |
937 | continue; |
938 | } |
939 | |
940 | if (status == EGADS_DEGEN-24) { |
941 | if (quadMesh == (int)true1) { |
942 | printf("Face %d has a degenerate edge - not quading\n", i); |
943 | } |
944 | continue; |
945 | } |
946 | |
947 | isouth[i] = status = EG_indexBodyTopo(ebody, echilds[0]); |
948 | if (status < EGADS_SUCCESS0) goto cleanup; |
949 | |
950 | ieast[i] = status = EG_indexBodyTopo(ebody, echilds[1]); |
951 | if (status < EGADS_SUCCESS0) goto cleanup; |
952 | |
953 | inorth[i] = status = EG_indexBodyTopo(ebody, echilds[2]); |
954 | if (status < EGADS_SUCCESS0) goto cleanup; |
955 | |
956 | iwest[i] = status = EG_indexBodyTopo(ebody, echilds[3]); |
957 | if (status < EGADS_SUCCESS0) goto cleanup; |
958 | } |
959 | |
960 | // make "opposite" sides of four-sided Faces (with only one loop) match |
961 | nchange = 1; |
962 | for (i = 0; i < 20; i++) { |
963 | nchange = 0; |
964 | |
965 | for (face = 1; face <= numFace; face++) { |
966 | if (isouth[face] <= 0 || ieast[face] <= 0 || |
967 | inorth[face] <= 0 || iwest[face] <= 0 ) continue; |
968 | |
969 | if (points[iwest[face]] < points[ieast[face]]) { |
970 | points[iwest[face]] = points[ieast[face]]; |
971 | nchange++; |
972 | |
973 | } else if (points[ieast[face]] < points[iwest[face]]) { |
974 | points[ieast[face]] = points[iwest[face]]; |
975 | nchange++; |
976 | } |
977 | |
978 | if (points[isouth[face]] < points[inorth[face]]) { |
979 | points[isouth[face]] = points[inorth[face]]; |
980 | nchange++; |
981 | } else if (points[inorth[face]] < points[isouth[face]]) { |
982 | points[inorth[face]] = points[isouth[face]]; |
983 | nchange++; |
984 | } |
985 | } |
986 | if (nchange == 0) break; |
987 | } |
988 | if (nchange > 0) { |
989 | printf("Exceeded number of tries making \"opposite\" sides of four-sided Faces (with only one loop) match\n"); |
990 | status = CAPS_MISMATCH-324; |
991 | goto cleanup; |
992 | } |
993 | |
994 | // mark the Edges with points[iedge] evenly-spaced points |
995 | for (edge = 1; edge <= numEdge; edge++) { |
996 | for (i = 1; i < points[edge]-1; i++) { |
997 | rpos[i-1] = (double)(i) / (double)(points[edge]-1); |
998 | } |
999 | |
1000 | if (points[edge] == 2) { |
1001 | i = 0; |
1002 | status = EG_attributeAdd(eedges[edge-1], ".rPos", ATTRINT1, 1, &i, NULL((void*)0), NULL((void*)0)); |
1003 | if (status < EGADS_SUCCESS0) goto cleanup; |
1004 | |
1005 | } else { |
1006 | status = EG_attributeAdd(eedges[edge-1], ".rPos", ATTRREAL2, points[edge]-2, NULL((void*)0), rpos, NULL((void*)0)); |
1007 | if (status < EGADS_SUCCESS0) goto cleanup; |
1008 | } |
1009 | } |
1010 | |
1011 | // Make tessellation |
1012 | status = EG_makeTessBody(ebody, params, &feaMesh->egadsTess); |
1013 | if (status != EGADS_SUCCESS0) { |
1014 | printf("\tError in fea_bodyToBEM: EG_makeTessBody\n"); |
1015 | goto cleanup; |
1016 | } |
1017 | |
1018 | // Make Quads on each four-sided Face |
1019 | params[0] = 0; |
1020 | params[1] = 0; |
1021 | params[2] = 0; |
1022 | |
1023 | // If making quads on faces lets setup an array to keep track of which faces have been quaded. |
1024 | if (quadMesh == (int)true1) { |
1025 | if( numFace > 0) { |
1026 | AIM_ALLOC(qints, numFace, int, aimInfo, status){ if (qints != ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 1026, __func__, 1, "AIM_ALLOC: %s != NULL" , "qints"); goto cleanup; } size_t memorysize = numFace; qints = (int *) EG_alloc(memorysize*sizeof(int)); if (qints == ((void *)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c" , 1026, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "qints" , memorysize, "int"); goto cleanup; } }; |
1027 | } |
1028 | // Set default to 0 |
1029 | for (face = 0; face < numFace; face++) qints[face] = 0; |
1030 | } |
1031 | |
1032 | if (quadMesh == (int)true1) { |
1033 | for (face = 1; face <= numFace; face++) { |
1034 | if (iwest[face] <= 0) continue; |
1035 | |
1036 | status = EG_makeQuads(feaMesh->egadsTess, params, face); |
1037 | if (status < EGADS_SUCCESS0) { |
1038 | printf("Face = %d, failed to make quads\n", face); |
1039 | printf("Edges = %d %d %d %d\n", inorth[face], ieast[face], isouth[face], iwest[face]); |
1040 | continue; |
1041 | //goto cleanup; |
1042 | } |
1043 | } |
1044 | } |
1045 | |
1046 | // Set the mesh type information |
1047 | feaMesh->meshType = SurfaceMesh; |
1048 | feaMesh->analysisType = MeshStructure; |
1049 | |
1050 | // Get number of point in the tessellation |
1051 | status = EG_statusTessBody(feaMesh->egadsTess, &tempBody, &i, &feaMesh->numNode); |
1052 | if (status != EGADS_SUCCESS0) goto cleanup; |
1053 | |
1054 | feaMesh->node = (meshNodeStruct *) EG_alloc(feaMesh->numNode*sizeof(meshNodeStruct)); |
1055 | if (feaMesh->node == NULL((void*)0)) { |
1056 | feaMesh->numNode = 0; |
1057 | status = EGADS_MALLOC-4; |
1058 | goto cleanup; |
1059 | } |
1060 | |
1061 | for (i = 0; i < feaMesh->numNode; i++) { |
1062 | status = initiate_meshNodeStruct(&feaMesh->node[i], feaMesh->analysisType); |
1063 | if (status != CAPS_SUCCESS0) goto cleanup; |
1064 | } |
1065 | |
1066 | // Fill up the Attributes for the nodes |
1067 | for (i = 0; i < feaMesh->numNode; i++) { |
1068 | |
1069 | status = EG_getGlobal(feaMesh->egadsTess, i+1, &pointType, &pointTopoIndex, xyzPoint); |
1070 | if (status != EGADS_SUCCESS0) goto cleanup; |
1071 | |
1072 | feaMesh->node[i].xyz[0] = xyzPoint[0]; |
1073 | feaMesh->node[i].xyz[1] = xyzPoint[1]; |
1074 | feaMesh->node[i].xyz[2] = xyzPoint[2]; |
1075 | |
1076 | feaMesh->node[i].nodeID = i+1; |
1077 | |
1078 | feaData = (feaMeshDataStruct *) feaMesh->node[i].analysisData; |
1079 | |
1080 | status = fea_setFEADataPoint(efaces, eedges, enodes, |
1081 | attrMap, |
1082 | coordSystemMap, |
1083 | constraintMap, |
1084 | loadMap, |
1085 | transferMap, |
1086 | connectMap, |
1087 | responseMap, |
1088 | referenceMap, |
1089 | pointType, pointTopoIndex, |
1090 | feaData); // Set the feaData structure |
1091 | if (status != CAPS_SUCCESS0) goto cleanup; |
1092 | } |
1093 | |
1094 | // Fill element information |
1095 | |
1096 | // If body is just a single node |
1097 | if (isNodeBody == EGADS_SUCCESS0) { |
1098 | |
1099 | if (numNode != 1) { |
1100 | printf("NodeBody found, but more than one node being reported!\n"); |
1101 | status = CAPS_BADVALUE-311; |
1102 | goto cleanup; |
1103 | } |
1104 | |
1105 | numElement = numNode; |
1106 | feaMesh->numElement = numElement; |
1107 | |
1108 | feaMesh->element = (meshElementStruct *) EG_alloc(feaMesh->numElement*sizeof(meshElementStruct)); |
1109 | if (feaMesh->element == NULL((void*)0)) { |
1110 | status = EGADS_MALLOC-4; |
1111 | feaMesh->numElement = 0; |
1112 | goto cleanup; |
1113 | } |
1114 | |
1115 | i = 0; |
1116 | (void) initiate_meshElementStruct(&feaMesh->element[i], feaMesh->analysisType); |
1117 | |
1118 | status = retrieve_CAPSGroupAttr(enodes[i], &attrName); |
1119 | if (status != CAPS_SUCCESS0) { |
1120 | AIM_ERROR(aimInfo, "No capsGroup attribute found for node - %d!!", i+1){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 1120, __func__ , "No capsGroup attribute found for node - %d!!", i+1); }; |
1121 | print_AllAttr(aimInfo, enodes[i]); |
1122 | goto cleanup; |
1123 | } |
1124 | |
1125 | status = get_mapAttrToIndexIndex(attrMap, attrName, &attrIndex); |
1126 | if (status != CAPS_SUCCESS0) { |
1127 | printf("\tError: capsGroup name %s not found in attribute to index map\n", attrName); |
1128 | goto cleanup; |
1129 | } |
1130 | |
1131 | feaMesh->element[i].elementType = Node; |
1132 | |
1133 | feaMesh->element[i].elementID = i+1; |
1134 | |
1135 | status = mesh_allocMeshElementConnectivity(&feaMesh->element[i]); |
1136 | if (status != CAPS_SUCCESS0) goto cleanup; |
1137 | |
1138 | feaMesh->element[i].markerID = attrIndex; |
1139 | |
1140 | feaMesh->element[i].connectivity[0] = i+1; |
1141 | |
1142 | feaData = (feaMeshDataStruct *) feaMesh->element[i].analysisData; |
1143 | |
1144 | feaData->propertyID = attrIndex; |
1145 | |
1146 | feaData->attrIndex = attrIndex; |
1147 | |
1148 | status = get_mapAttrToIndexIndex(coordSystemMap, attrName, &coordSystemIndex); |
1149 | if (status == CAPS_SUCCESS0) { |
1150 | feaData->coordID = coordSystemIndex; |
1151 | } else { |
1152 | feaData->coordID = coordID; |
1153 | } |
1154 | |
1155 | feaMesh->meshQuickRef.numNode += 1; // Add count |
1156 | |
1157 | feaMesh->meshQuickRef.startIndexNode = 0; |
1158 | feaMesh->meshQuickRef.useStartIndex = (int) true1; |
1159 | |
1160 | status = CAPS_SUCCESS0; |
1161 | goto cleanup; |
1162 | |
1163 | } //NODEBODY IF |
1164 | |
1165 | /* Determine of the body type */ |
1166 | status = EG_getTopology(ebody, &eref, &oclass, &bodySubType, data, &nchild, &echilds, &senses); |
1167 | if (status != EGADS_SUCCESS0) goto cleanup; |
1168 | |
1169 | // Can only have "free" edges in wire bodies - Don't want to count the edges of the faces |
1170 | // as "free" edges |
1171 | if (bodySubType == WIREBODY6) { |
1172 | feaMesh->numElement = numEdge; |
1173 | |
1174 | feaMesh->element = (meshElementStruct *) EG_alloc(feaMesh->numElement*sizeof(meshElementStruct)); |
1175 | if (feaMesh->element == NULL((void*)0)) { |
1176 | status = EGADS_MALLOC-4; |
1177 | feaMesh->numElement = 0; |
1178 | goto cleanup; |
1179 | } |
1180 | |
1181 | for (i = 0; i < feaMesh->numElement; i++) { |
1182 | (void) initiate_meshElementStruct(&feaMesh->element[i], feaMesh->analysisType); |
1183 | } |
1184 | |
1185 | for (i = 0; i < numEdge; i++) { |
1186 | |
1187 | status = EG_getInfo(eedges[i], &oclass, &mtype, &topObj, &prev, &next); |
1188 | if (status != CAPS_SUCCESS0) goto cleanup; |
1189 | if (mtype == DEGENERATE5) continue; |
1190 | |
1191 | status = retrieve_CAPSIgnoreAttr(eedges[i], &attrName); |
1192 | if (status == CAPS_SUCCESS0) { |
1193 | printf("\tcapsIgnore attribute found for edge - %d!!\n", i+1); |
1194 | continue; |
1195 | } |
1196 | |
1197 | numElement += 1; |
1198 | |
1199 | status = retrieve_CAPSGroupAttr(eedges[i], &attrName); |
1200 | if (status != CAPS_SUCCESS0) { |
1201 | AIM_ERROR(aimInfo, "No capsGroup attribute found for edge - %d!!", i+1){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 1201, __func__ , "No capsGroup attribute found for edge - %d!!", i+1); }; |
1202 | print_AllAttr(aimInfo, eedges[i] ); |
1203 | goto cleanup; |
1204 | } |
1205 | |
1206 | status = get_mapAttrToIndexIndex(attrMap, attrName, &attrIndex); |
1207 | if (status != CAPS_SUCCESS0) { |
1208 | AIM_ERROR(aimInfo, "capsGroup name %s not found in attribute to index map\n", attrName){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 1208, __func__ , "capsGroup name %s not found in attribute to index map\n", attrName ); }; |
1209 | goto cleanup; |
1210 | } |
1211 | |
1212 | feaMesh->element[numElement-1].elementType = Line; |
1213 | |
1214 | feaMesh->element[numElement-1].elementID = numElement; |
1215 | |
1216 | status = mesh_allocMeshElementConnectivity(&feaMesh->element[numElement-1]); |
1217 | if (status != CAPS_SUCCESS0) goto cleanup; |
1218 | |
1219 | feaMesh->element[numElement-1].markerID = attrIndex; |
1220 | |
1221 | status = EG_getTessEdge(feaMesh->egadsTess, i+1, &numPoint, &xyz, &uv); |
1222 | if (status < EGADS_SUCCESS0) goto cleanup; |
1223 | |
1224 | status = EG_localToGlobal(feaMesh->egadsTess, -(i+1), 1, &gID); |
1225 | if (status != EGADS_SUCCESS0) goto cleanup; |
1226 | |
1227 | feaMesh->element[numElement-1].connectivity[0] = gID; |
1228 | |
1229 | status = EG_localToGlobal(feaMesh->egadsTess, -(i+1), numPoint, &gID); |
1230 | if (status != EGADS_SUCCESS0) goto cleanup; |
1231 | |
1232 | feaMesh->element[numElement-1].connectivity[1] = gID; |
1233 | |
1234 | feaData = (feaMeshDataStruct *) feaMesh->element[numElement-1].analysisData; |
1235 | |
1236 | feaData->propertyID = attrIndex; |
1237 | |
1238 | feaData->attrIndex = attrIndex; |
1239 | |
1240 | status = get_mapAttrToIndexIndex(coordSystemMap, attrName, &coordSystemIndex); |
1241 | if (status == CAPS_SUCCESS0) { |
1242 | feaData->coordID = coordSystemIndex; |
1243 | } else { |
1244 | feaData->coordID = coordID; |
1245 | } |
1246 | |
1247 | feaMesh->meshQuickRef.numLine += 1; // Add count |
1248 | |
1249 | } |
1250 | |
1251 | if (feaMesh->meshQuickRef.numLine != numEdge) { // Resize our array in case we have some ignores |
1252 | |
1253 | tempElement = (meshElementStruct *) EG_reall(feaMesh->element, |
1254 | feaMesh->meshQuickRef.numLine*sizeof(meshElementStruct)); |
1255 | |
1256 | if (tempElement == NULL((void*)0)) { |
1257 | status = EGADS_MALLOC-4; |
1258 | goto cleanup; |
1259 | } |
1260 | |
1261 | feaMesh->element = tempElement; |
1262 | |
1263 | feaMesh->numElement = feaMesh->meshQuickRef.numLine; |
1264 | } |
1265 | |
1266 | feaMesh->meshQuickRef.startIndexLine = 0; |
1267 | feaMesh->meshQuickRef.useStartIndex = (int) true1; |
1268 | |
1269 | status = CAPS_SUCCESS0; |
1270 | goto cleanup; |
1271 | |
1272 | } //WIREBODY IF |
1273 | |
1274 | if (quadMesh == (int) true1 && numFace > 0) { |
1275 | printf("\tGetting quads for BEM!\n"); |
1276 | |
1277 | // Turn off meshQuick guide if you are getting quads |
1278 | feaMesh->meshQuickRef.useStartIndex = (int) false0; |
1279 | } else { |
1280 | feaMesh->meshQuickRef.useStartIndex = (int) true1; |
1281 | feaMesh->meshQuickRef.startIndexTriangle = numElement; |
1282 | } |
1283 | |
1284 | // Get Tris and Quads from faces |
1285 | for (face = 0; face < numFace; face++) { |
1286 | |
1287 | status = retrieve_CAPSIgnoreAttr(efaces[face], &attrName); |
1288 | if (status == CAPS_SUCCESS0) { |
1289 | printf("\tcapsIgnore attribute found for face - %d!!\n", face+1); |
1290 | ignoreFound = (int) true1; |
1291 | continue; |
1292 | } |
1293 | |
1294 | status = retrieve_CAPSGroupAttr(efaces[face], &attrName); |
1295 | if (status != CAPS_SUCCESS0) { |
1296 | AIM_ERROR(aimInfo, "No capsGroup attribute found for face - %d!!", face+1){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 1296, __func__ , "No capsGroup attribute found for face - %d!!", face+1); }; |
1297 | print_AllAttr(aimInfo, efaces[face]); |
1298 | goto cleanup; |
1299 | } |
1300 | |
1301 | status = get_mapAttrToIndexIndex(attrMap, attrName, &attrIndex); |
1302 | if (status != CAPS_SUCCESS0) { |
1303 | AIM_ERROR(aimInfo, "capsGroup name %s not found in attribute to index map", attrName){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 1303, __func__ , "capsGroup name %s not found in attribute to index map", attrName ); }; |
1304 | goto cleanup; |
1305 | } |
1306 | |
1307 | status = get_mapAttrToIndexIndex(coordSystemMap, attrName, &coordSystemIndex); |
1308 | if (status != CAPS_SUCCESS0) coordSystemIndex = 0; |
1309 | |
1310 | |
1311 | loadIndex = CAPSMAGIC1234321; |
1312 | status = retrieve_CAPSLoadAttr(efaces[face], &attrName); |
1313 | if (status == CAPS_SUCCESS0) { |
1314 | |
1315 | status = get_mapAttrToIndexIndex(loadMap, attrName, &loadIndex); |
1316 | |
1317 | if (status != CAPS_SUCCESS0) { |
1318 | printf("Error: capsLoad name %s not found in attribute to index map\n", attrName); |
1319 | goto cleanup; |
1320 | } |
1321 | } |
1322 | |
1323 | if (quadMesh == (int) true1) { |
1324 | status = EG_getQuads(feaMesh->egadsTess, face+1, &numPoint, &xyz, &uv, &ptype, &pindex, &numPatch); |
1325 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 1325 , __func__, 0); goto cleanup; }; |
1326 | |
1327 | } else numPatch = -1; |
1328 | |
1329 | if (numPatch > 0) { |
1330 | |
1331 | if (numPatch != 1) { |
1332 | status = CAPS_NOTIMPLEMENT-334; |
1333 | printf("feaUtils: EG_localToGlobal accidentally only works for a single quad patch! FIXME!\n"); |
1334 | goto cleanup; |
1335 | } |
1336 | |
1337 | qints[face] = 0; |
1338 | for (patch = 1; patch <= numPatch; patch++) { |
1339 | |
1340 | status = EG_getPatch(feaMesh->egadsTess, face+1, patch, &n1, &n2, &pvindex, &pbounds); |
1341 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 1341 , __func__, 0); goto cleanup; }; |
1342 | |
1343 | for (j = 1; j < n2; j++) { |
1344 | for (i = 1; i < n1; i++) { |
1345 | numElement += 1; |
1346 | |
1347 | feaMesh->meshQuickRef.numQuadrilateral += 1; |
1348 | feaMesh->numElement = numElement; |
1349 | |
1350 | tempElement = (meshElementStruct *) EG_reall(feaMesh->element, |
1351 | feaMesh->numElement*sizeof(meshElementStruct)); |
1352 | |
1353 | if (tempElement == NULL((void*)0)) { |
1354 | status = EGADS_MALLOC-4; |
1355 | feaMesh->numElement -= 1; |
1356 | goto cleanup; |
1357 | } |
1358 | |
1359 | feaMesh->element = tempElement; |
1360 | |
1361 | status = initiate_meshElementStruct(&feaMesh->element[numElement-1], feaMesh->analysisType); |
1362 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 1362 , __func__, 0); goto cleanup; }; |
1363 | |
1364 | qints[face] += 1; |
1365 | |
1366 | feaMesh->element[numElement-1].elementType = Quadrilateral; |
1367 | |
1368 | feaMesh->element[numElement-1].elementID = numElement; |
1369 | |
1370 | status = mesh_allocMeshElementConnectivity(&feaMesh->element[numElement-1]); |
1371 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 1371 , __func__, 0); goto cleanup; }; |
1372 | |
1373 | status = EG_localToGlobal(feaMesh->egadsTess, face+1, pvindex[(i-1)+n1*(j-1)], &gID); |
1374 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 1374 , __func__, 0); goto cleanup; }; |
1375 | |
1376 | feaMesh->element[numElement-1].connectivity[0] = gID; |
1377 | |
1378 | status = EG_localToGlobal(feaMesh->egadsTess, face+1, pvindex[(i )+n1*(j-1)], &gID); |
1379 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 1379 , __func__, 0); goto cleanup; }; |
1380 | |
1381 | feaMesh->element[numElement-1].connectivity[1] = gID; |
1382 | |
1383 | status = EG_localToGlobal(feaMesh->egadsTess, face+1, pvindex[(i )+n1*(j )], &gID); |
1384 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 1384 , __func__, 0); goto cleanup; }; |
1385 | |
1386 | feaMesh->element[numElement-1].connectivity[2] = gID; |
1387 | |
1388 | status = EG_localToGlobal(feaMesh->egadsTess, face+1, pvindex[(i-1)+n1*(j )], &gID); |
1389 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 1389 , __func__, 0); goto cleanup; }; |
1390 | |
1391 | feaMesh->element[numElement-1].connectivity[3] = gID; |
1392 | |
1393 | feaMesh->element[numElement-1].markerID = attrIndex; |
1394 | |
1395 | feaData = (feaMeshDataStruct *) feaMesh->element[numElement-1].analysisData; |
1396 | |
1397 | feaData->propertyID = attrIndex; |
1398 | feaData->attrIndex = attrIndex; |
1399 | feaData->coordID = coordSystemIndex; |
1400 | feaData->loadIndex = loadIndex; |
1401 | |
1402 | } |
1403 | } |
1404 | |
1405 | } |
1406 | } else { |
1407 | status = EG_getTessFace(feaMesh->egadsTess, face+1, |
1408 | &numPoint, &xyz, &uv, &ptype, &pindex, |
1409 | &numTri, &triConn, &triNeighbor); |
1410 | if (status < EGADS_SUCCESS0) goto cleanup; |
1411 | |
1412 | for (i= 0; i < numTri; i++) { |
1413 | |
1414 | numElement += 1; |
1415 | |
1416 | feaMesh->meshQuickRef.numTriangle += 1; |
1417 | feaMesh->numElement = numElement; |
1418 | |
1419 | |
1420 | tempElement = (meshElementStruct *) EG_reall(feaMesh->element, |
1421 | feaMesh->numElement*sizeof(meshElementStruct)); |
1422 | |
1423 | if (tempElement == NULL((void*)0)) { |
1424 | status = EGADS_MALLOC-4; |
1425 | feaMesh->numElement -= 1; |
1426 | goto cleanup; |
1427 | } |
1428 | |
1429 | feaMesh->element = tempElement; |
1430 | |
1431 | status = initiate_meshElementStruct(&feaMesh->element[numElement-1], feaMesh->analysisType); |
1432 | if (status != CAPS_SUCCESS0) goto cleanup; |
1433 | |
1434 | feaMesh->element[numElement-1].elementType = Triangle; |
1435 | |
1436 | feaMesh->element[numElement-1].elementID = numElement; |
1437 | |
1438 | status = mesh_allocMeshElementConnectivity(&feaMesh->element[numElement-1]); |
1439 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 1439 , __func__, 0); goto cleanup; }; |
1440 | |
1441 | status = EG_localToGlobal(feaMesh->egadsTess, face+1, triConn[3*i + 0], &gID); |
1442 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 1442 , __func__, 0); goto cleanup; }; |
1443 | |
1444 | feaMesh->element[numElement-1].connectivity[0] = gID; |
1445 | |
1446 | status = EG_localToGlobal(feaMesh->egadsTess, face+1, triConn[3*i + 1], &gID); |
1447 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 1447 , __func__, 0); goto cleanup; }; |
1448 | |
1449 | feaMesh->element[numElement-1].connectivity[1] = gID; |
1450 | |
1451 | status = EG_localToGlobal(feaMesh->egadsTess, face+1, triConn[3*i + 2], &gID); |
1452 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 1452 , __func__, 0); goto cleanup; }; |
1453 | |
1454 | feaMesh->element[numElement-1].connectivity[2] = gID; |
1455 | |
1456 | feaMesh->element[numElement-1].markerID = attrIndex; |
1457 | |
1458 | feaData = (feaMeshDataStruct *) feaMesh->element[numElement-1].analysisData; |
1459 | |
1460 | feaData->propertyID = attrIndex; |
1461 | feaData->attrIndex = attrIndex; |
1462 | feaData->coordID = coordSystemIndex; |
1463 | feaData->loadIndex = loadIndex; |
1464 | |
1465 | } |
1466 | } |
1467 | |
1468 | } |
1469 | |
1470 | if (numPatch > 0) { |
1471 | status = EG_attributeAdd(feaMesh->egadsTess, ".mixed", ATTRINT1, numFace, qints, NULL((void*)0), NULL((void*)0)); |
1472 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 1472 , __func__, 0); goto cleanup; }; |
1473 | } |
1474 | |
1475 | if (ignoreFound == (int) true1) { |
1476 | |
1477 | // Look at the nodeID for each node and check to see if it is being used in the element connectivity; if not it is removed |
1478 | // Note: that the nodeIDs for the nodes and element connectivity isn't changed, as such if using element connectivity to blindly |
1479 | // access a given node this could lead to seg-faults!. mesh_nodeID2Array must be used to access the node array index. |
1480 | status = mesh_removeUnusedNodes(feaMesh); |
1481 | if (status != CAPS_SUCCESS0) goto cleanup; |
1482 | } |
1483 | |
1484 | status = CAPS_SUCCESS0; |
1485 | |
1486 | cleanup: |
1487 | if (status != CAPS_SUCCESS0) printf("\tPremature exit in fea_bodyToBem, status = %d\n", status); |
1488 | |
1489 | AIM_FREE(iwest ){ EG_free(iwest); iwest = ((void*)0); }; |
1490 | AIM_FREE(inorth){ EG_free(inorth); inorth = ((void*)0); }; |
1491 | AIM_FREE(ieast ){ EG_free(ieast); ieast = ((void*)0); }; |
1492 | AIM_FREE(isouth){ EG_free(isouth); isouth = ((void*)0); }; |
1493 | AIM_FREE(rpos ){ EG_free(rpos); rpos = ((void*)0); }; |
1494 | AIM_FREE(points ){ EG_free(points); points = ((void*)0); }; |
1495 | |
1496 | AIM_FREE(enodes){ EG_free(enodes); enodes = ((void*)0); }; |
1497 | AIM_FREE(eedges){ EG_free(eedges); eedges = ((void*)0); }; |
1498 | AIM_FREE(efaces){ EG_free(efaces); efaces = ((void*)0); }; |
1499 | |
1500 | AIM_FREE(qints){ EG_free(qints); qints = ((void*)0); }; |
1501 | |
1502 | enodes = NULL((void*)0); |
1503 | eedges =NULL((void*)0); |
1504 | efaces =NULL((void*)0); |
1505 | |
1506 | return status; |
1507 | } |
1508 | |
1509 | // Set the fea analysis meta data in a mesh |
1510 | int fea_setAnalysisData( void *aimInfo, // (in) AIM structure |
1511 | mapAttrToIndexStruct *attrMap, // (in) map from CAPSGroup names to indexes |
1512 | mapAttrToIndexStruct *coordSystemMap,// (in) map from CoordSystem names to indexes |
1513 | mapAttrToIndexStruct *constraintMap, // (in) map from CAPSConstraint names to indexes |
1514 | mapAttrToIndexStruct *loadMap, // (in) map from CAPSLoad names to indexes |
1515 | mapAttrToIndexStruct *transferMap, // (in) map from CAPSTransfer names to indexes |
1516 | mapAttrToIndexStruct *connectMap, // (in) map from CAPSConnect names to indexes |
1517 | mapAttrToIndexStruct *responseMap, // (in) map from CAPSResponse names to indexes |
1518 | mapAttrToIndexStruct *referenceMap, // (in) map from CAPSReference names to indexes |
1519 | meshStruct *feaMesh) // (in/out) FEA mesh structure |
1520 | { |
1521 | int status = 0; // Function return status |
1522 | |
1523 | int i, face, edge, node, body; // Indexing |
1524 | int dummy; |
1525 | |
1526 | int nodeOffset=0, elementOffset=0; |
1527 | |
1528 | // Body entities |
1529 | int numNode = 0, numEdge = 0, numFace = 0; |
1530 | ego *enodes=NULL((void*)0), *eedges=NULL((void*)0), *efaces=NULL((void*)0); |
1531 | ego ebody; |
1532 | |
1533 | // Meshing |
1534 | int elem; |
1535 | |
1536 | int oclass, nchild, *senses; |
1537 | |
1538 | // Edge point distributions |
1539 | int *points=NULL((void*)0), *isouth=NULL((void*)0), *ieast=NULL((void*)0), *inorth=NULL((void*)0), *iwest=NULL((void*)0); |
1540 | double data[4]; |
1541 | double *rpos=NULL((void*)0); |
1542 | ego eref, *echilds;//, topObj, prev, next; |
1543 | |
1544 | int isNodeBody, bodySubType = 0; // Body classification |
1545 | |
1546 | int pointType, pointTopoIndex; |
1547 | double xyzPoint[3]; |
1548 | |
1549 | // Meshing |
1550 | int numPoint = 0, numTri = 0; |
1551 | const int *triConn = NULL((void*)0), *triNeighbor = NULL((void*)0); // Triangle |
1552 | |
1553 | int gID; // Global id |
1554 | |
1555 | const double *xyz, *uv; |
1556 | double result[18]; |
1557 | |
1558 | const int *ptype = NULL((void*)0), *pindex = NULL((void*)0); |
1559 | |
1560 | // Attributues |
1561 | const char *attrName; |
1562 | int attrIndex, coordSystemIndex, loadIndex; |
1563 | |
1564 | feaMeshDataStruct *feaData = NULL((void*)0); |
1565 | meshGeomDataStruct *geomData; |
1566 | |
1567 | // --------------------------------------------------------------- |
1568 | |
1569 | if (feaMesh->meshType == SurfaceMesh || feaMesh->meshType == Surface2DMesh ) { |
1570 | printf("Setting FEA Data\n"); |
1571 | |
1572 | // Get body from tessellation |
1573 | status = EG_statusTessBody(feaMesh->egadsTess, &ebody, &dummy, &dummy); |
1574 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 1574 , __func__, 0); goto cleanup; }; |
1575 | |
1576 | // Get number of Nodes, Edges, and Faces in ebody |
1577 | status = EG_getBodyTopos(ebody, NULL((void*)0), NODE20, &numNode, &enodes); |
1578 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 1578 , __func__, 0); goto cleanup; }; |
1579 | |
1580 | status = EG_getBodyTopos(ebody, NULL((void*)0), EDGE21, &numEdge, &eedges); |
1581 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 1581 , __func__, 0); goto cleanup; }; |
1582 | |
1583 | status = EG_getBodyTopos(ebody, NULL((void*)0), FACE23, &numFace, &efaces); |
1584 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 1584 , __func__, 0); goto cleanup; }; |
1585 | |
1586 | // What type of BODY do we have? |
1587 | isNodeBody = aim_isNodeBody(ebody, xyzPoint); |
1588 | if (isNodeBody < EGADS_SUCCESS0) goto cleanup; |
1589 | if (isNodeBody == EGADS_SUCCESS0) { |
1590 | // all attributes are on the body rather than the node for a node body |
1591 | enodes[0] = ebody; |
1592 | } |
1593 | |
1594 | // Fill up the Attributes for the nodes |
1595 | for (i = 0; i < feaMesh->numNode; i++) { |
1596 | |
1597 | status = EG_getGlobal(feaMesh->egadsTess, feaMesh->node[i].nodeID, &pointType, &pointTopoIndex, xyzPoint); |
1598 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 1598 , __func__, 0); goto cleanup; }; |
1599 | |
1600 | feaData = (feaMeshDataStruct *) feaMesh->node[i].analysisData; |
1601 | |
1602 | status = fea_setFEADataPoint(efaces, eedges, enodes, |
1603 | attrMap, |
1604 | coordSystemMap, |
1605 | constraintMap, |
1606 | loadMap, |
1607 | transferMap, |
1608 | connectMap, |
1609 | responseMap, |
1610 | referenceMap, |
1611 | pointType, pointTopoIndex, |
1612 | feaData); // Set the feaData structure |
1613 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 1613 , __func__, 0); goto cleanup; }; |
1614 | } |
1615 | |
1616 | // Fill element information |
1617 | |
1618 | // If body is just a single node |
1619 | if (numNode == 1) { |
1620 | |
1621 | if (feaMesh->numNode != 1) { |
1622 | AIM_ERROR(aimInfo, "NodeBody found, but more than one node being reported!\n"){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 1622, __func__ , "NodeBody found, but more than one node being reported!\n") ; }; |
1623 | status = CAPS_BADVALUE-311; |
1624 | goto cleanup; |
1625 | } |
1626 | |
1627 | i = 0; |
1628 | status = retrieve_CAPSGroupAttr(enodes[i], &attrName); |
1629 | if (status != CAPS_SUCCESS0) { |
1630 | AIM_ERROR(aimInfo, "No capsGroup attribute found for node - %d!!", i+1){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 1630, __func__ , "No capsGroup attribute found for node - %d!!", i+1); }; |
1631 | print_AllAttr(aimInfo, enodes[i] ); |
1632 | goto cleanup; |
1633 | } |
1634 | |
1635 | status = get_mapAttrToIndexIndex(attrMap, attrName, &attrIndex); |
1636 | if (status != CAPS_SUCCESS0) { |
1637 | AIM_ERROR(aimInfo, "capsGroup name %s not found in attribute to index map", attrName){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 1637, __func__ , "capsGroup name %s not found in attribute to index map", attrName ); }; |
1638 | goto cleanup; |
1639 | } |
1640 | |
1641 | feaData = (feaMeshDataStruct *) feaMesh->element[i].analysisData; |
1642 | |
1643 | feaData->propertyID = attrIndex; |
1644 | |
1645 | feaData->attrIndex = attrIndex; |
1646 | |
1647 | status = get_mapAttrToIndexIndex(coordSystemMap, attrName, &coordSystemIndex); |
1648 | if (status != CAPS_SUCCESS0) coordSystemIndex = 0; |
1649 | |
1650 | feaData->coordID = coordSystemIndex; |
1651 | |
1652 | status = CAPS_SUCCESS0; |
1653 | goto cleanup; |
1654 | |
1655 | } //NODEBODY IF |
1656 | |
1657 | #if 0 |
1658 | /* Determine the body type */ |
1659 | status = EG_getTopology(ebody, &eref, &oclass, &bodySubType, data, &nchild, &echilds, &senses); |
1660 | if (status != EGADS_SUCCESS0) goto cleanup; |
1661 | |
1662 | // Can only have "free" edges in wire bodies - Don't want to count the edges of the faces |
1663 | // as "free" edges |
1664 | if (bodySubType == WIREBODY6) { |
1665 | |
1666 | for (i = 0; i < feaMesh->meshQuickRef.numLine; i++) { |
1667 | |
1668 | status = EG_getInfo(eedges[i], &oclass, &mtype, &topObj, &prev, &next); |
1669 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 1669 , __func__, 0); goto cleanup; }; |
1670 | if (mtype == DEGENERATE5) continue; |
1671 | |
1672 | if (feaMesh->meshQuickRef.useStartIndex == (int)true1) |
1673 | elem = i + feaMesh->meshQuickRef.startIndexLine; |
1674 | else if (feaMesh->meshQuickRef.useListIndex == (int)true1) |
1675 | elem = feaMesh->meshQuickRef.listIndexLine[i]; |
1676 | else { |
1677 | status = CAPS_BADOBJECT-310; |
1678 | printf("DEVELOPER ERROR: Both useStartIndex and useListIndex are true!\n"); |
1679 | goto cleanup; |
1680 | } |
1681 | |
1682 | attrIndex = feaMesh->element[elem].markerID; |
1683 | |
1684 | // get the capsGroup attribute string value |
1685 | status = get_mapAttrToIndexKeyword(attrMap, attrIndex, &attrName); |
1686 | if (status != CAPS_SUCCESS0) { |
1687 | printf("\tError: capsGroup index '%d' not found in attribute to index map\n", attrIndex); |
1688 | goto cleanup; |
1689 | } |
1690 | |
1691 | feaData = (feaMeshDataStruct *) feaMesh->element[elem].analysisData; |
1692 | |
1693 | status = get_mapAttrToIndexIndex(coordSystemMap, attrName, &coordSystemIndex); |
1694 | if (status != CAPS_SUCCESS0) coordSystemIndex = 0; |
1695 | |
1696 | feaData->propertyID = attrIndex; |
1697 | feaData->coordID = coordSystemIndex; |
1698 | } |
1699 | |
1700 | status = CAPS_SUCCESS0; |
1701 | goto cleanup; |
1702 | |
1703 | } |
1704 | #endif |
1705 | |
1706 | |
1707 | // Set line, tri and quad analysis data |
1708 | for (elem = 0; elem < feaMesh->numElement; elem++) { |
1709 | |
1710 | if (feaMesh->element[elem].elementType != Node && |
1711 | feaMesh->element[elem].elementType != Line && |
1712 | feaMesh->element[elem].elementType != Triangle && |
1713 | feaMesh->element[elem].elementType != Triangle_6 && |
1714 | feaMesh->element[elem].elementType != Quadrilateral && |
1715 | feaMesh->element[elem].elementType != Quadrilateral_8) continue; |
1716 | |
1717 | attrIndex = feaMesh->element[elem].markerID; |
1718 | |
1719 | // get the capsGroup attribute string value |
1720 | status = get_mapAttrToIndexKeyword(attrMap, attrIndex, &attrName); |
1721 | if (status != CAPS_SUCCESS0) { |
1722 | printf("\tError: capsGroup index '%d' not found in attribute to index map\n", attrIndex); |
1723 | goto cleanup; |
1724 | } |
1725 | |
1726 | status = get_mapAttrToIndexIndex(coordSystemMap, attrName, &coordSystemIndex); |
1727 | if (status != CAPS_SUCCESS0) coordSystemIndex = 0; |
1728 | |
1729 | if (feaMesh->element[elem].elementType == Node) { |
1730 | // get the node index |
1731 | node = feaMesh->element[elem].topoIndex; |
1732 | if (node < 1 || node > numNode) { |
1733 | printf("Error: Element '%d': Invalid node topological index: %d, [1-%d]\n", elem, node, numNode); |
1734 | status = CAPS_BADVALUE-311; |
1735 | goto cleanup; |
1736 | } |
1737 | |
1738 | eref = enodes[node-1]; |
1739 | |
1740 | } else if (feaMesh->element[elem].elementType == Line) { |
1741 | // get the edge index |
1742 | edge = feaMesh->element[elem].topoIndex; |
1743 | if (edge < 1 || edge > numEdge) { |
1744 | printf("Error: Element '%d': Invalid edge topological index: %d, [1-%d]\n", elem, edge, numEdge); |
1745 | status = CAPS_BADVALUE-311; |
1746 | goto cleanup; |
1747 | } |
1748 | |
1749 | eref = eedges[edge-1]; |
1750 | |
1751 | } else { |
1752 | |
1753 | // get the face index |
1754 | face = feaMesh->element[elem].topoIndex; |
1755 | if (face < 1 || face > numFace) { |
1756 | printf("Error: Element '%d': Invalid face topological index: %d, [1-%d]\n", elem, face, numFace); |
1757 | status = CAPS_BADVALUE-311; |
1758 | goto cleanup; |
1759 | } |
1760 | |
1761 | eref = efaces[face-1]; |
1762 | |
1763 | // If this is a face in a capsBound, set geomData in nodes |
1764 | status = retrieve_CAPSBoundAttr(eref, &attrName); |
1765 | if (status == CAPS_SUCCESS0) { |
1766 | |
1767 | status = EG_getTessFace(feaMesh->egadsTess, face, |
1768 | &numPoint, &xyz, &uv, &ptype, &pindex, |
1769 | &numTri, &triConn, &triNeighbor); |
1770 | if (status < EGADS_SUCCESS0) goto cleanup; |
1771 | |
1772 | for (i = 0; i < numPoint; i++) { |
1773 | |
1774 | status = EG_localToGlobal(feaMesh->egadsTess, face, i+1, &gID); |
1775 | if (status != EGADS_SUCCESS0) goto cleanup; |
1776 | |
1777 | geomData = feaMesh->node[gID-1].geomData; |
1778 | |
1779 | if (geomData == NULL((void*)0)) { |
1780 | |
1781 | // Get geometry data for node |
1782 | geomData = EG_alloc(sizeof(meshGeomDataStruct)); |
1783 | |
1784 | if (geomData == NULL((void*)0)) { |
1785 | status = EGADS_MALLOC-4; |
1786 | goto cleanup; |
1787 | } |
1788 | |
1789 | status = initiate_meshGeomDataStruct(geomData); |
1790 | if (status != CAPS_SUCCESS0) goto cleanup; |
1791 | |
1792 | geomData->type = ptype[i]; |
1793 | geomData->topoIndex = pindex[i]; |
1794 | |
1795 | // Want the face index to be set for topoIndex |
1796 | if (geomData->topoIndex < 0) geomData->topoIndex = face+1; |
1797 | |
1798 | geomData->uv[0] = uv[2*i + 0]; |
1799 | geomData->uv[1] = uv[2*i + 1]; |
1800 | |
1801 | status = EG_evaluate(eref, geomData->uv, result); |
1802 | if (status != EGADS_SUCCESS0) goto cleanup; |
1803 | |
1804 | // dU |
1805 | geomData->firstDerivative[0] = result[3]; |
1806 | geomData->firstDerivative[1] = result[4]; |
1807 | geomData->firstDerivative[2] = result[5]; |
1808 | |
1809 | // dV |
1810 | geomData->firstDerivative[3] = result[6]; |
1811 | geomData->firstDerivative[4] = result[7]; |
1812 | geomData->firstDerivative[5] = result[8]; |
1813 | |
1814 | feaMesh->node[gID-1].geomData = geomData; |
1815 | } |
1816 | } |
1817 | } |
1818 | } |
1819 | |
1820 | loadIndex = CAPSMAGIC1234321; |
1821 | status = retrieve_CAPSLoadAttr(eref, &attrName); |
1822 | if (status == CAPS_SUCCESS0) { |
1823 | |
1824 | status = get_mapAttrToIndexIndex(loadMap, attrName, &loadIndex); |
1825 | |
1826 | if (status != CAPS_SUCCESS0) { |
1827 | printf("Error: capsLoad name %s not found in attribute to index map\n", attrName); |
1828 | goto cleanup; |
1829 | } |
1830 | } |
1831 | |
1832 | feaData = (feaMeshDataStruct *) feaMesh->element[elem].analysisData; |
1833 | |
1834 | feaData->propertyID = attrIndex; |
1835 | feaData->attrIndex = attrIndex; |
1836 | feaData->coordID = coordSystemIndex; |
1837 | feaData->loadIndex = loadIndex; |
1838 | } |
1839 | |
1840 | } else if (feaMesh->meshType == VolumeMesh) { |
1841 | |
1842 | // Show warning statement |
1843 | printf("Warning - surface nodes are assumed to be packed sequentially in the volume\n"); |
1844 | |
1845 | // Loop through reference meshes |
1846 | for (body = 0; body < feaMesh->numReferenceMesh; body++) { |
1847 | printf("Setting FEA Data from reference mesh %d (of %d)\n", body+1, feaMesh->numReferenceMesh); |
1848 | |
1849 | // Get body from tessellation |
1850 | status = EG_statusTessBody(feaMesh->referenceMesh[body].egadsTess, &ebody, &dummy, &dummy); |
1851 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 1851 , __func__, 0); goto cleanup; }; |
1852 | |
1853 | // Get number of Nodes, Edges, and Faces in ebody |
1854 | status = EG_getBodyTopos(ebody, NULL((void*)0), NODE20, &numNode, &enodes); |
1855 | if (status < EGADS_SUCCESS0) goto cleanup; |
1856 | |
1857 | status = EG_getBodyTopos(ebody, NULL((void*)0), EDGE21, &numEdge, &eedges); |
1858 | if (status != EGADS_SUCCESS0) goto cleanup; |
1859 | |
1860 | status = EG_getBodyTopos(ebody, NULL((void*)0), FACE23, &numFace, &efaces); |
1861 | if (status < EGADS_SUCCESS0) goto cleanup; |
1862 | |
1863 | // What type of BODY do we have? |
1864 | isNodeBody = aim_isNodeBody(ebody, xyzPoint); |
1865 | if (isNodeBody < EGADS_SUCCESS0) goto cleanup; |
1866 | |
1867 | // If body is just a single node |
1868 | if (isNodeBody == EGADS_SUCCESS0) { |
1869 | |
1870 | printf("NodeBody found, not currently supported for VolumeMesh!\n"); |
1871 | status = CAPS_BADVALUE-311; |
1872 | goto cleanup; |
1873 | |
1874 | } //NODEBODY IF |
1875 | |
1876 | // Fill up the Attributes for the nodes |
1877 | for (i = 0; i < feaMesh->referenceMesh[body].numNode; i++) { |
1878 | |
1879 | status = EG_getGlobal(feaMesh->referenceMesh[body].egadsTess, feaMesh->referenceMesh[body].node[i].nodeID, &pointType, &pointTopoIndex, xyzPoint); |
1880 | if (status != EGADS_SUCCESS0) goto cleanup; |
1881 | |
1882 | feaData = (feaMeshDataStruct *) feaMesh->node[i+nodeOffset].analysisData; |
1883 | |
1884 | status = fea_setFEADataPoint(efaces, eedges, enodes, |
1885 | attrMap, |
1886 | coordSystemMap, |
1887 | constraintMap, |
1888 | loadMap, |
1889 | transferMap, |
1890 | connectMap, |
1891 | responseMap, |
1892 | referenceMap, |
1893 | pointType, pointTopoIndex, |
1894 | feaData); // Set the feaData structure |
1895 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 1895 , __func__, 0); goto cleanup; }; |
1896 | } |
1897 | |
1898 | // Fill element information // |
1899 | |
1900 | // Determine the body type |
1901 | status = EG_getTopology(ebody, &eref, &oclass, &bodySubType, data, &nchild, &echilds, &senses); |
1902 | if (status != EGADS_SUCCESS0) goto cleanup; |
1903 | |
1904 | // Can only have "free" edges in wire bodies - Don't want to count the edges of the faces |
1905 | // as "free" edges |
1906 | if (bodySubType == WIREBODY6) { |
1907 | |
1908 | printf("WireBody found, not currently supported for VolumeMesh!\n"); |
1909 | status = CAPS_BADVALUE-311; |
1910 | goto cleanup; |
1911 | |
1912 | } //WIREBODY IF |
1913 | |
1914 | // Set tri and quad analysis data |
1915 | for (elem = 0; elem < feaMesh->referenceMesh[body].numElement; elem++) { |
1916 | |
1917 | if (feaMesh->referenceMesh[body].element[elem].elementType != Triangle && |
1918 | feaMesh->referenceMesh[body].element[elem].elementType != Triangle_6 && |
1919 | feaMesh->referenceMesh[body].element[elem].elementType != Quadrilateral && |
1920 | feaMesh->referenceMesh[body].element[elem].elementType != Quadrilateral_8) continue; |
1921 | |
1922 | // |
1923 | // attrIndex = feaMesh->referenceMesh[body].element[elem].markerID; |
1924 | // |
1925 | // // get the capsGroup attribute string value |
1926 | // status = get_mapAttrToIndexKeyword(attrMap, attrIndex, &attrName); |
1927 | // if (status != CAPS_SUCCESS) { |
1928 | // printf("\tError: capsGroup index '%d' not found in attribute to index map\n", attrIndex); |
1929 | // goto cleanup; |
1930 | // } |
1931 | // |
1932 | // status = get_mapAttrToIndexIndex(coordSystemMap, attrName, &coordSystemIndex); |
1933 | // if (status != CAPS_SUCCESS) coordSystemIndex = 0; |
1934 | |
1935 | // get the face index |
1936 | face = feaMesh->referenceMesh[body].element[elem].topoIndex; |
1937 | if (face < 1 || face > numFace) { |
1938 | printf("Error: Element '%d': Invalid face topological index: %d, [1-%d]\n", elem, face, numFace); |
1939 | status = CAPS_BADVALUE-311; |
1940 | goto cleanup; |
1941 | } |
1942 | |
1943 | loadIndex = CAPSMAGIC1234321; |
1944 | status = retrieve_CAPSLoadAttr(efaces[face-1], &attrName); |
1945 | if (status == CAPS_SUCCESS0) { |
1946 | |
1947 | status = get_mapAttrToIndexIndex(loadMap, attrName, &loadIndex); |
1948 | |
1949 | if (status != CAPS_SUCCESS0) { |
1950 | printf("Error: capsLoad name %s not found in attribute to index map\n", attrName); |
1951 | goto cleanup; |
1952 | } |
1953 | } |
1954 | |
1955 | feaData = (feaMeshDataStruct *) feaMesh->element[elem+elementOffset].analysisData; |
1956 | |
1957 | //feaData->propertyID = attrIndex; DONT THINK WE WANT TO CHANGE THE PROPERTY TYPE |
1958 | // feaData->coordID = coordSystemIndex; DONT THINK WE WANT TO CHANGE THE Coordinate TYPE |
1959 | feaData->loadIndex = loadIndex; |
1960 | } |
1961 | |
1962 | nodeOffset += feaMesh->referenceMesh[body].numNode; |
1963 | elementOffset += feaMesh->referenceMesh[body].numElement; |
1964 | } |
1965 | |
1966 | } else { |
1967 | printf("Unknown meshType!\n"); |
1968 | status = CAPS_BADTYPE-306; |
1969 | goto cleanup; |
1970 | } |
1971 | |
1972 | status = CAPS_SUCCESS0; |
1973 | |
1974 | cleanup: |
1975 | if (status != CAPS_SUCCESS0) printf("\tPremature exit in fea_setAnalysisData, status = %d\n", status); |
1976 | |
1977 | EG_free(iwest ); |
1978 | EG_free(inorth); |
1979 | EG_free(ieast ); |
1980 | EG_free(isouth); |
1981 | EG_free(rpos ); |
1982 | EG_free(points ); |
1983 | |
1984 | EG_free(enodes); |
1985 | EG_free(eedges); |
1986 | EG_free(efaces); |
1987 | |
1988 | enodes = NULL((void*)0); |
1989 | eedges = NULL((void*)0); |
1990 | efaces = NULL((void*)0); |
1991 | |
1992 | return status; |
1993 | } |
1994 | |
1995 | // Set feaData for a given point index and topology index. Ego faces, edges, and nodes must be provided along with attribute maps |
1996 | int fea_setFEADataPoint(ego *faces, ego *edges, ego *nodes, |
1997 | mapAttrToIndexStruct *attrMap, |
1998 | /*@unused@*/ mapAttrToIndexStruct *coordSystemMap, |
1999 | mapAttrToIndexStruct *constraintMap, |
2000 | mapAttrToIndexStruct *loadMap, |
2001 | mapAttrToIndexStruct *transferMap, |
2002 | mapAttrToIndexStruct *connectMap, |
2003 | mapAttrToIndexStruct *responseMap, |
2004 | mapAttrToIndexStruct *referenceMap, |
2005 | int pointType, int pointTopoIndex, |
2006 | feaMeshDataStruct *feaData) { // Set the feaData structure |
2007 | |
2008 | int status; |
2009 | |
2010 | int coordID = 0; // Default coordinate id for mesh |
2011 | |
2012 | // Attributes |
2013 | const char *attrName; |
2014 | int constraintIndex=-1, loadIndex=-1, transferIndex=-1, connectIndex=-1; |
2015 | int connectLinkIndex=-1, attrIndex=-1, responseIndex=-1, referenceIndex=-1; //coordSystemIndex |
2016 | |
2017 | ego object; |
2018 | |
2019 | feaData->coordID = coordID; |
2020 | |
2021 | // Get attribute index on entity |
2022 | constraintIndex = CAPSMAGIC1234321; |
2023 | loadIndex = CAPSMAGIC1234321; |
2024 | transferIndex = CAPSMAGIC1234321; |
2025 | connectIndex = CAPSMAGIC1234321; |
2026 | connectLinkIndex = CAPSMAGIC1234321; |
2027 | responseIndex = CAPSMAGIC1234321; |
2028 | referenceIndex = CAPSMAGIC1234321; |
2029 | |
2030 | if (pointType == 0) { // Node |
2031 | |
2032 | object = nodes[pointTopoIndex-1]; |
2033 | |
2034 | } else if (pointType > 0 ) { // Edge |
2035 | |
2036 | object = edges[pointTopoIndex-1]; |
2037 | |
2038 | } else { // Face |
2039 | |
2040 | object = faces[pointTopoIndex-1]; |
2041 | |
2042 | } |
2043 | |
2044 | status = retrieve_CAPSGroupAttr(object, &attrName); |
2045 | if (status == CAPS_SUCCESS0) { |
2046 | status = get_mapAttrToIndexIndex(attrMap, attrName, &attrIndex); |
2047 | if (status != CAPS_SUCCESS0 && status != CAPS_NOTFOUND-303 && status != CAPS_NULLVALUE-307) goto cleanup; |
2048 | } |
2049 | |
2050 | status = retrieve_CAPSConstraintAttr(object, &attrName); |
2051 | if (status == CAPS_SUCCESS0) { |
2052 | status = get_mapAttrToIndexIndex(constraintMap, attrName, &constraintIndex); |
2053 | if (status != CAPS_SUCCESS0 && status != CAPS_NOTFOUND-303 && status != CAPS_NULLVALUE-307) goto cleanup; |
2054 | } |
2055 | |
2056 | status = retrieve_CAPSLoadAttr(object, &attrName); |
2057 | if (status == CAPS_SUCCESS0) { |
2058 | status = get_mapAttrToIndexIndex(loadMap, attrName, &loadIndex); |
2059 | if (status != CAPS_SUCCESS0 && status != CAPS_NOTFOUND-303 && status != CAPS_NULLVALUE-307) goto cleanup; |
2060 | } |
2061 | |
2062 | status = retrieve_CAPSBoundAttr(object, &attrName); |
2063 | if (status == CAPS_SUCCESS0) { |
2064 | status = get_mapAttrToIndexIndex(transferMap, attrName, &transferIndex); |
2065 | if (status != CAPS_SUCCESS0 && status != CAPS_NOTFOUND-303 && status != CAPS_NULLVALUE-307) goto cleanup; |
2066 | } |
2067 | |
2068 | status = retrieve_CAPSConnectAttr(object, &attrName); |
2069 | if (status == CAPS_SUCCESS0) { |
2070 | status = get_mapAttrToIndexIndex(connectMap, attrName, &connectIndex); |
2071 | if (status != CAPS_SUCCESS0 && status != CAPS_NOTFOUND-303 && status != CAPS_NULLVALUE-307) goto cleanup; |
2072 | } |
2073 | |
2074 | status = retrieve_CAPSConnectLinkAttr(object, &attrName); |
2075 | if (status == CAPS_SUCCESS0) { |
2076 | status = get_mapAttrToIndexIndex(connectMap, attrName, &connectLinkIndex); |
2077 | if (status != CAPS_SUCCESS0 && status != CAPS_NOTFOUND-303 && status != CAPS_NULLVALUE-307) goto cleanup; |
2078 | } |
2079 | |
2080 | status = retrieve_CAPSResponseAttr(object, &attrName); |
2081 | if (status == CAPS_SUCCESS0) { |
2082 | status = get_mapAttrToIndexIndex(responseMap, attrName, &responseIndex); |
2083 | if (status != CAPS_SUCCESS0 && status != CAPS_NOTFOUND-303 && status != CAPS_NULLVALUE-307) goto cleanup; |
2084 | } |
2085 | |
2086 | status = retrieve_CAPSReferenceAttr(object, &attrName); |
2087 | if (status == CAPS_SUCCESS0) { |
2088 | status = get_mapAttrToIndexIndex(referenceMap, attrName, &referenceIndex); |
2089 | if (status != CAPS_SUCCESS0 && status != CAPS_NOTFOUND-303 && status != CAPS_NULLVALUE-307) goto cleanup; |
2090 | } |
2091 | |
2092 | feaData->attrIndex = attrIndex; |
2093 | |
2094 | feaData->constraintIndex = constraintIndex; |
2095 | feaData->loadIndex = loadIndex; |
2096 | feaData->transferIndex = transferIndex; |
2097 | feaData->connectIndex = connectIndex; |
2098 | feaData->connectLinkIndex = connectLinkIndex; |
2099 | feaData->responseIndex = responseIndex; |
2100 | feaData->referenceIndex = referenceIndex; |
2101 | |
2102 | status = CAPS_SUCCESS0; |
2103 | goto cleanup; |
2104 | |
2105 | cleanup: |
2106 | |
2107 | if (status != CAPS_SUCCESS0) printf("Error: Premature exit in fea_setFEADataPoint, status %d\n", status); |
2108 | |
2109 | return status; |
2110 | } |
2111 | |
2112 | // Initiate (0 out all values and NULL all pointers) of feaProperty in the feaPropertyStruct structure format |
2113 | int initiate_feaPropertyStruct(feaPropertyStruct *feaProperty) { |
2114 | int i; |
2115 | |
2116 | feaProperty->name = NULL((void*)0); |
2117 | |
2118 | feaProperty->propertyType = UnknownProperty; |
2119 | |
2120 | feaProperty->propertyID = 0; // ID number of property |
2121 | |
2122 | feaProperty->materialID = 0; // ID number of material |
2123 | feaProperty->materialName = NULL((void*)0); // Name of material associated with material ID |
2124 | |
2125 | // Rods |
2126 | feaProperty->crossSecArea = 0.0; // Bar cross-sectional area |
2127 | feaProperty->torsionalConst = 0.0; // Torsional constant |
2128 | feaProperty->torsionalStressReCoeff = 0.0; // Torsional stress recovery coefficient |
2129 | feaProperty->massPerLength = 0.0; // Mass per unit length |
2130 | |
2131 | // Bar - see rod for additional variables |
2132 | feaProperty->zAxisInertia = 0.0; // Section moment of inertia about the z axis |
2133 | feaProperty->yAxisInertia = 0.0; // Section moment of inertia about the y axis |
2134 | |
2135 | feaProperty->yCoords[0] = 0.0; // Element y, z coordinates, in the bar cross-section, of |
2136 | feaProperty->yCoords[1] = 0.0; // of four points at which to recover stresses |
2137 | feaProperty->yCoords[2] = 0.0; |
2138 | feaProperty->yCoords[3] = 0.0; |
2139 | |
2140 | feaProperty->zCoords[0] = 0.0; |
2141 | feaProperty->zCoords[1] = 0.0; |
2142 | feaProperty->zCoords[2] = 0.0; |
2143 | feaProperty->zCoords[3] = 0.0; |
2144 | |
2145 | feaProperty->areaShearFactors[0] = 0.0; // Area factors for shear |
2146 | feaProperty->areaShearFactors[1] = 0.0; |
2147 | |
2148 | feaProperty->crossProductInertia = 0.0; // Section cross-product of inertia |
2149 | |
2150 | feaProperty->crossSecType = NULL((void*)0); // Type of cross sections |
2151 | for (i = 0; i < 10; i++) feaProperty->crossSecDimension[i] = 0.0; // Dimensions |
2152 | |
2153 | feaProperty->orientationVec[0] = 0.0; // Orientation vector |
2154 | feaProperty->orientationVec[1] = 0.0; |
2155 | feaProperty->orientationVec[2] = 0.0; |
2156 | |
2157 | // Shear |
2158 | |
2159 | // Shell |
2160 | feaProperty->membraneThickness = 0.0; // Membrane thickness |
2161 | feaProperty->materialBendingID = 0; /// ID number of material for bending - if not specified and bendingInertiaRatio > 0 this value defaults to materialID |
2162 | feaProperty->bendingInertiaRatio = 1.0; // Ratio of actual bending moment inertia (I) to bending inertia of a solid |
2163 | // plate of thickness TM Real - default 1.0 |
2164 | feaProperty->materialShearID = 0; // ID number of material for shear - if not specified and shearMembraneRatio > 0 this value defaults to materialID |
2165 | feaProperty->shearMembraneRatio = 5.0/6.0; // Ratio of shear to membrane thickness - default 5/6 |
2166 | feaProperty->massPerArea = 0.0; // Mass per unit area |
2167 | //feaProperty->neutralPlaneDist[0] = 0; // Distances from the neutral plane of the plate to locations where |
2168 | //feaProperty->neutralPlaneDist[1] = 0; // stress is calculate |
2169 | |
2170 | feaProperty->zOffsetRel = 0.0; // Offset from the surface of grid points to the element reference plane |
2171 | |
2172 | feaProperty->compositeShearBondAllowable = 0.0; // Shear stress limit for bonding between plies |
2173 | feaProperty->compositeFailureTheory = NULL((void*)0); // HILL, HOFF, TSAI, STRN |
2174 | feaProperty->compositeSymmetricLaminate = (int) false0; // 1- SYM only half the plies are specified, for odd number plies 1/2 thickness of center ply is specified |
2175 | // the first ply is the bottom ply in the stack, default (0) all plies specified |
2176 | feaProperty->numPly = 0; |
2177 | feaProperty->compositeMaterialID = NULL((void*)0); // Vector of material ID's from bottom to top for all plies |
2178 | feaProperty->compositeThickness = NULL((void*)0); // Vector of thicknesses from bottom to top for all plies |
2179 | feaProperty->compositeOrientation = NULL((void*)0); // Vector of orientations from bottom to top for all plies |
2180 | |
2181 | // Solid |
2182 | |
2183 | // Concentrated Mass |
2184 | feaProperty->mass = 0.0; // Mass value |
2185 | feaProperty->massOffset[0] = 0.0; // Offset distance from the grid point to the center of gravity |
2186 | feaProperty->massOffset[1] = 0.0; |
2187 | feaProperty->massOffset[2] = 0.0; |
2188 | feaProperty->massInertia[0] = 0.0; // Mass moment of inertia measured at the mass center of gravity |
2189 | feaProperty->massInertia[1] = 0.0; |
2190 | feaProperty->massInertia[2] = 0.0; |
2191 | feaProperty->massInertia[3] = 0.0; |
2192 | feaProperty->massInertia[4] = 0.0; |
2193 | feaProperty->massInertia[5] = 0.0; |
2194 | |
2195 | return CAPS_SUCCESS0; |
2196 | } |
2197 | |
2198 | // Destroy (0 out all values and NULL all pointers) of feaProperty in the feaPropertyStruct structure format |
2199 | int destroy_feaPropertyStruct(feaPropertyStruct *feaProperty) { |
2200 | |
2201 | int i; |
2202 | |
2203 | if (feaProperty->name != NULL((void*)0)) EG_free(feaProperty->name); |
2204 | |
2205 | feaProperty->propertyType = UnknownProperty; |
2206 | |
2207 | feaProperty->propertyID = 0; // ID number of property |
2208 | |
2209 | feaProperty->materialID = 0; // ID number of material |
2210 | |
2211 | if (feaProperty->materialName != NULL((void*)0)) EG_free(feaProperty->materialName); // Name of material associated with material ID |
2212 | feaProperty->materialName = NULL((void*)0); |
2213 | |
2214 | // Rods |
2215 | feaProperty->crossSecArea = 0; // Bar cross-sectional area |
2216 | feaProperty->torsionalConst = 0; // Torsional constant |
2217 | feaProperty->torsionalStressReCoeff = 0; // Torsional stress recovery coefficient |
2218 | feaProperty->massPerLength = 0; // Mass per unit length |
2219 | |
2220 | // Bar - see rod for additional variables |
2221 | feaProperty->zAxisInertia = 0; // Section moment of inertia about the z axis |
2222 | feaProperty->yAxisInertia = 0; // Section moment of inertia about the y axis |
2223 | |
2224 | feaProperty->yCoords[0] = 0; // Element y, z coordinates, in the bar cross-section, of |
2225 | feaProperty->yCoords[1] = 0; // of four points at which to recover stresses |
2226 | feaProperty->yCoords[2] = 0; |
2227 | feaProperty->yCoords[3] = 0; |
2228 | |
2229 | feaProperty->zCoords[0] = 0; |
2230 | feaProperty->zCoords[1] = 0; |
2231 | feaProperty->zCoords[2] = 0; |
2232 | feaProperty->zCoords[3] = 0; |
2233 | |
2234 | feaProperty->areaShearFactors[0] = 0; // Area factors for shear |
2235 | feaProperty->areaShearFactors[1] = 0; |
2236 | |
2237 | feaProperty->crossProductInertia = 0; // Section cross-product of inertia |
2238 | |
2239 | if (feaProperty->crossSecType != NULL((void*)0)) EG_free(feaProperty->crossSecType); |
2240 | feaProperty->crossSecType = NULL((void*)0); // Type of cross sections |
2241 | for (i = 0; i < 10; i++) feaProperty->crossSecDimension[i] = 0.0; // Dimensions |
2242 | |
2243 | feaProperty->orientationVec[0] = 0.0; // Orientation vector |
2244 | feaProperty->orientationVec[1] = 0.0; |
2245 | feaProperty->orientationVec[2] = 0.0; |
2246 | |
2247 | // Shear |
2248 | |
2249 | // Shell |
2250 | feaProperty->membraneThickness = 0; // Membrane thickness |
2251 | feaProperty->materialBendingID = 0; // ID number of material for bending |
2252 | feaProperty->bendingInertiaRatio = 1.0; // Ratio of actual bending moment inertia (I) to bending inertia of a solid |
2253 | // plate of thickness TM Real - default 1.0 |
2254 | feaProperty->materialShearID = 0; // ID number of material for shear |
2255 | feaProperty->shearMembraneRatio = 5.0/6.0; // Ratio of shear to membrane thickness - default 5/6 |
2256 | feaProperty->massPerArea = 0; // Mass per unit area |
2257 | //feaProperty->neutralPlaneDist[0] = 0; // Distances from the neutral plane of the plate to locations where |
2258 | //feaProperty->neutralPlaneDist[1] = 0; // stress is calculate |
2259 | |
2260 | feaProperty->zOffsetRel = 0.0; // Offset from the surface of grid points to the element reference plane |
2261 | |
2262 | feaProperty->numPly = 0; |
2263 | feaProperty->compositeShearBondAllowable = 0.0; // Shear stress limit for bonding between plies |
2264 | if (feaProperty->compositeFailureTheory != NULL((void*)0)) EG_free(feaProperty->compositeFailureTheory); // HILL, HOFF, TSAI, STRN |
2265 | feaProperty->compositeFailureTheory = NULL((void*)0); |
2266 | feaProperty->compositeSymmetricLaminate = (int) false0; // 1- SYM only half the plies are specified, for odd number plies 1/2 thickness of center ply is specified |
2267 | // the first ply is the bottom ply in the stack, default (0) all plies specified |
2268 | if (feaProperty->compositeMaterialID != NULL((void*)0)) EG_free(feaProperty->compositeMaterialID); |
2269 | if (feaProperty->compositeThickness != NULL((void*)0)) EG_free(feaProperty->compositeThickness); |
2270 | if (feaProperty->compositeOrientation != NULL((void*)0)) EG_free(feaProperty->compositeOrientation); |
2271 | |
2272 | feaProperty->compositeMaterialID = NULL((void*)0); |
2273 | feaProperty->compositeThickness = NULL((void*)0); |
2274 | feaProperty->compositeOrientation = NULL((void*)0); |
2275 | |
2276 | // Solid |
2277 | |
2278 | // Concentrated Mass |
2279 | feaProperty->mass = 0.0; // Mass value |
2280 | feaProperty->massOffset[0] = 0.0; // Offset distance from the grid point to the center of gravity |
2281 | feaProperty->massOffset[1] = 0.0; |
2282 | feaProperty->massOffset[2] = 0.0; |
2283 | feaProperty->massInertia[0] = 0.0; // Mass moment of inertia measured at the mass center of gravity |
2284 | feaProperty->massInertia[1] = 0.0; |
2285 | feaProperty->massInertia[2] = 0.0; |
2286 | feaProperty->massInertia[3] = 0.0; |
2287 | feaProperty->massInertia[4] = 0.0; |
2288 | feaProperty->massInertia[5] = 0.0; |
2289 | |
2290 | return CAPS_SUCCESS0; |
2291 | } |
2292 | |
2293 | // Initiate (0 out all values and NULL all pointers) of feaMaterial in the feaMaterialStruct structure format |
2294 | int initiate_feaMaterialStruct(feaMaterialStruct *feaMaterial) { |
2295 | |
2296 | feaMaterial->name = NULL((void*)0); // Material name |
2297 | |
2298 | feaMaterial->materialType = UnknownMaterial; // Set |
2299 | |
2300 | feaMaterial->materialID = 0; // ID number of material |
2301 | |
2302 | feaMaterial->youngModulus = 0.0; // E - Young's Modulus |
2303 | feaMaterial->shearModulus = 0.0; // G - Shear Modulus |
2304 | feaMaterial->poissonRatio = 0.0; // Poisson's Ratio |
2305 | feaMaterial->density = 0.0; // Rho - material mass density |
2306 | feaMaterial->thermalExpCoeff = 0.0; //Coefficient of thermal expansion |
2307 | feaMaterial->temperatureRef = 0.0; // Reference temperature |
2308 | feaMaterial->dampingCoeff = 0.0; // Damping coefficient |
2309 | feaMaterial->tensionAllow = 0.0; // Tension allowable for the material |
2310 | feaMaterial->compressAllow = 0.0; // Compression allowable for the material |
2311 | feaMaterial->shearAllow = 0.0; // Shear allowable for the material |
2312 | |
2313 | feaMaterial->youngModulusLateral = 0.0; // Young's Modulus in the lateral direction |
2314 | feaMaterial->shearModulusTrans1Z = 0.0; // Transverse shear modulus in the 1-Z plane |
2315 | feaMaterial->shearModulusTrans2Z = 0.0; // Transverse shear modulus in the 2-Z plane |
2316 | feaMaterial->tensionAllowLateral = 0.0; // Tension allowable for the material |
2317 | feaMaterial->compressAllowLateral = 0.0; // Compression allowable for the material |
2318 | feaMaterial->thermalExpCoeffLateral = 0.0; //Coefficient of thermal expansion |
2319 | feaMaterial->allowType = 0; |
2320 | |
2321 | feaMaterial->specificHeat = 0; |
2322 | feaMaterial->kappa = 0; |
2323 | |
2324 | return CAPS_SUCCESS0; |
2325 | } |
2326 | |
2327 | // Destroy (0 out all values and NULL all pointers) of feaMaterial in the feaMaterialStruct structure format |
2328 | int destroy_feaMaterialStruct(feaMaterialStruct *feaMaterial) { |
2329 | |
2330 | if (feaMaterial->name != NULL((void*)0)) EG_free(feaMaterial->name); |
2331 | feaMaterial->name = NULL((void*)0); // Material name |
2332 | |
2333 | feaMaterial->materialType = UnknownMaterial; // Material type |
2334 | |
2335 | feaMaterial->materialID = 0; // ID number of material |
2336 | |
2337 | feaMaterial->youngModulus = 0.0; // E - Young's Modulus |
2338 | feaMaterial->shearModulus = 0.0; // G - Shear Modulus |
2339 | feaMaterial->poissonRatio = 0.0; // Poisson's Ratio |
2340 | feaMaterial->density = 0.0; // Rho - material mass density |
2341 | feaMaterial->thermalExpCoeff = 0.0; //Coefficient of thermal expansion |
2342 | feaMaterial->temperatureRef = 0.0; // Reference temperature |
2343 | feaMaterial->dampingCoeff = 0.0; // Damping coefficient |
2344 | feaMaterial->tensionAllow = 0.0; // Tension allowable for the material |
2345 | feaMaterial->compressAllow = 0.0; // Compression allowable for the material |
2346 | feaMaterial->shearAllow = 0.0; // Shear allowable for the material |
2347 | |
2348 | feaMaterial->youngModulusLateral = 0.0; // Young's Modulus in the lateral direction |
2349 | feaMaterial->shearModulusTrans1Z = 0.0; // Transverse shear modulus in the 1-Z plane |
2350 | feaMaterial->shearModulusTrans2Z = 0.0; // Transverse shear modulus in the 2-Z plane |
2351 | feaMaterial->tensionAllowLateral = 0.0; // Tension allowable for the material |
2352 | feaMaterial->compressAllowLateral = 0.0; // Compression allowable for the material |
2353 | feaMaterial->thermalExpCoeffLateral = 0.0; //Coefficient of thermal expansion |
2354 | feaMaterial->allowType = 0; |
2355 | |
2356 | feaMaterial->specificHeat = 0; |
2357 | feaMaterial->kappa = 0; |
2358 | |
2359 | return CAPS_SUCCESS0; |
2360 | } |
2361 | |
2362 | // Initiate (0 out all values and NULL all pointers) of feaUnits in the feaUnitsStruct structure format |
2363 | int initiate_feaUnitsStruct(feaUnitsStruct *feaUnits) { |
2364 | |
2365 | feaUnits->densityVol = NULL((void*)0); |
2366 | feaUnits->densityArea = NULL((void*)0); |
2367 | feaUnits->mass = NULL((void*)0); |
2368 | feaUnits->length = NULL((void*)0); |
2369 | feaUnits->pressure = NULL((void*)0); |
2370 | feaUnits->temperature = NULL((void*)0); |
2371 | feaUnits->momentOfInertia = NULL((void*)0); |
2372 | |
2373 | return CAPS_SUCCESS0; |
2374 | } |
2375 | |
2376 | // Destroy (0 out all values and NULL all pointers) of feaUnits in the feaUnitsStruct structure format |
2377 | int destroy_feaUnitsStruct(feaUnitsStruct *feaUnits) { |
2378 | |
2379 | AIM_FREE(feaUnits->densityVol){ EG_free(feaUnits->densityVol); feaUnits->densityVol = ((void*)0); }; |
2380 | AIM_FREE(feaUnits->densityArea){ EG_free(feaUnits->densityArea); feaUnits->densityArea = ((void*)0); }; |
2381 | AIM_FREE(feaUnits->mass){ EG_free(feaUnits->mass); feaUnits->mass = ((void*)0); }; |
2382 | AIM_FREE(feaUnits->length){ EG_free(feaUnits->length); feaUnits->length = ((void* )0); }; |
2383 | AIM_FREE(feaUnits->pressure){ EG_free(feaUnits->pressure); feaUnits->pressure = ((void *)0); }; |
2384 | AIM_FREE(feaUnits->temperature){ EG_free(feaUnits->temperature); feaUnits->temperature = ((void*)0); }; |
2385 | AIM_FREE(feaUnits->momentOfInertia){ EG_free(feaUnits->momentOfInertia); feaUnits->momentOfInertia = ((void*)0); }; |
2386 | |
2387 | return CAPS_SUCCESS0; |
2388 | } |
2389 | |
2390 | // Initiate (0 out all values and NULL all pointers) of feaConstraint in the feaConstraintStruct structure format |
2391 | int initiate_feaConstraintStruct(feaConstraintStruct *feaConstraint) { |
2392 | |
2393 | feaConstraint->name = NULL((void*)0); // Constraint name |
2394 | |
2395 | feaConstraint->constraintType = UnknownConstraint; // Constraint type |
2396 | |
2397 | feaConstraint->constraintID = 0; // ID number of constraint |
2398 | |
2399 | feaConstraint->numGridID = 0; // Component number of grid |
2400 | feaConstraint->gridIDSet = NULL((void*)0); // List of component number of grids to apply constraint to |
2401 | |
2402 | feaConstraint->dofConstraint = 0; // Number to indicate DOF constraints |
2403 | feaConstraint->gridDisplacement = 0; |
2404 | |
2405 | return CAPS_SUCCESS0; |
2406 | } |
2407 | |
2408 | // Destroy (0 out all values and NULL all pointers) of feaConstraint in the feaConstraintStruct structure format |
2409 | int destroy_feaConstraintStruct(feaConstraintStruct *feaConstraint) { |
2410 | |
2411 | if (feaConstraint->name != NULL((void*)0)) EG_free(feaConstraint->name); |
2412 | feaConstraint->name = NULL((void*)0); // Constraint name |
2413 | |
2414 | feaConstraint->constraintType = UnknownConstraint; // Constraint type |
2415 | |
2416 | feaConstraint->constraintID = 0; // ID number of constraint |
2417 | |
2418 | feaConstraint->numGridID = 0; // Number of grid IDs in grid ID set |
2419 | |
2420 | if (feaConstraint->gridIDSet != NULL((void*)0)) EG_free(feaConstraint->gridIDSet); // List of component number of grids to apply constraint to |
2421 | |
2422 | feaConstraint->dofConstraint = 0; // Number to indicate DOF constraints |
2423 | feaConstraint->gridDisplacement = 0; // The value for the displacement |
2424 | |
2425 | return CAPS_SUCCESS0; |
2426 | } |
2427 | |
2428 | // Initiate (0 out all values and NULL all pointers) of feaSupport in the feaSupportStruct structure format |
2429 | int initiate_feaSupportStruct(feaSupportStruct *feaSupport) { |
2430 | |
2431 | feaSupport->name = NULL((void*)0); // Support name |
2432 | |
2433 | feaSupport->supportID = 0; // ID number of support |
2434 | |
2435 | feaSupport->numGridID = 0; // Component number of grid |
2436 | feaSupport->gridIDSet = NULL((void*)0); // List of component number of grids to apply support to |
2437 | |
2438 | feaSupport->dofSupport = 0; // Number to indicate DOF supports |
2439 | |
2440 | return CAPS_SUCCESS0; |
2441 | } |
2442 | |
2443 | // Destroy (0 out all values and NULL all pointers) of feaSupport in the feaSupportStruct structure format |
2444 | int destroy_feaSupportStruct(feaSupportStruct *feaSupport) { |
2445 | |
2446 | if (feaSupport->name != NULL((void*)0)) EG_free(feaSupport->name); |
2447 | feaSupport->name = NULL((void*)0); // Support name |
2448 | |
2449 | feaSupport->supportID = 0; // ID number of support |
2450 | |
2451 | feaSupport->numGridID = 0; // Number of grid IDs in grid ID set |
2452 | |
2453 | if (feaSupport->gridIDSet != NULL((void*)0)) EG_free(feaSupport->gridIDSet); // List of component number of grids to apply support to |
2454 | |
2455 | feaSupport->dofSupport = 0; // Number to indicate DOF supports |
2456 | |
2457 | return CAPS_SUCCESS0; |
2458 | } |
2459 | |
2460 | // Initiate (0 out all values and NULL all pointers) of feaAnalysis in the feaAnalysisStruct structure format |
2461 | int initiate_feaAnalysisStruct(feaAnalysisStruct *feaAnalysis) { |
2462 | |
2463 | feaAnalysis->name = NULL((void*)0); // Analysis name |
2464 | |
2465 | feaAnalysis->analysisType = UnknownAnalysis; // Type of analysis |
2466 | |
2467 | feaAnalysis->analysisID = 0; // ID number of analysis |
2468 | |
2469 | // Loads for the analysis |
2470 | feaAnalysis->numLoad = 0; // Number of loads in the analysis |
2471 | feaAnalysis->loadSetID = NULL((void*)0); // List of the load IDSs |
2472 | |
2473 | // Constraints for the analysis |
2474 | feaAnalysis->numConstraint = 0; // Number of constraints in the analysis |
2475 | feaAnalysis->constraintSetID = NULL((void*)0); // List of constraint IDs |
2476 | |
2477 | // Supports for the analysis |
2478 | feaAnalysis->numSupport = 0; // Number of supports in the analysis |
2479 | feaAnalysis->supportSetID = NULL((void*)0); // List of support IDs |
2480 | |
2481 | // Optimization constraints |
2482 | feaAnalysis->numDesignConstraint = 0; // Number of design constraints |
2483 | feaAnalysis->designConstraintSetID = NULL((void*)0); // List of design constraint IDs |
2484 | |
2485 | // Optimization responses |
2486 | feaAnalysis->numDesignResponse = 0; // Number of design responses |
2487 | feaAnalysis->designResponseSetID = NULL((void*)0); // List of design response IDs |
2488 | |
2489 | // Eigenvalue |
2490 | feaAnalysis->extractionMethod = NULL((void*)0); |
2491 | |
2492 | feaAnalysis->frequencyRange[0] = 0; |
2493 | feaAnalysis->frequencyRange[1] = 0; |
2494 | |
2495 | feaAnalysis->numEstEigenvalue = 0; |
2496 | feaAnalysis->numDesiredEigenvalue = 0; |
2497 | feaAnalysis->eigenNormaliztion = NULL((void*)0); |
2498 | |
2499 | feaAnalysis->gridNormaliztion = 0; |
2500 | feaAnalysis->componentNormaliztion = 0; |
2501 | |
2502 | feaAnalysis->lanczosMode = 2; //Lanczos mode for calculating eigenvalues |
2503 | feaAnalysis->lanczosType = NULL((void*)0); //Lanczos matrix type (DPB, DGB) |
2504 | |
2505 | // Trim |
2506 | feaAnalysis->numMachNumber = 0; |
2507 | feaAnalysis->machNumber = NULL((void*)0); // Mach number |
2508 | feaAnalysis->dynamicPressure = 0.0; // Dynamic pressure |
2509 | feaAnalysis->density = 0.0; // Density |
2510 | feaAnalysis->aeroSymmetryXY = NULL((void*)0); |
2511 | feaAnalysis->aeroSymmetryXZ = NULL((void*)0); |
2512 | |
2513 | feaAnalysis->numRigidVariable = 0; // Number of rigid trim variables |
2514 | feaAnalysis->rigidVariable = NULL((void*)0); // List of character labels identifying rigid trim variables, size=[numRigidVariables] |
2515 | |
2516 | feaAnalysis->numRigidConstraint = 0; // Number of rigid trim constrained variables |
2517 | feaAnalysis->rigidConstraint = NULL((void*)0); // List of character labels identifying rigid constrained trim variables, size=[numRigidConstraint] |
2518 | feaAnalysis->magRigidConstraint = NULL((void*)0); // Magnitude of rigid constrained trim variables, size=[numRigidConstraint] |
2519 | |
2520 | feaAnalysis->numControlConstraint = 0; // Number of control surface constrained variables |
2521 | feaAnalysis->controlConstraint = NULL((void*)0); // List of character labels identifying control surfaces to be constrained trim variables, size=[numControlConstraint] |
2522 | feaAnalysis->magControlConstraint = NULL((void*)0); // Magnitude of control surface constrained variables, size=[numControlConstraint] |
2523 | |
2524 | // Flutter |
2525 | feaAnalysis->numReducedFreq = 0; |
2526 | feaAnalysis->reducedFreq = NULL((void*)0); |
2527 | |
2528 | feaAnalysis->numFlutterVel = 0; |
2529 | feaAnalysis->flutterVel = NULL((void*)0); |
2530 | |
2531 | feaAnalysis->flutterConvergenceParam = 0.0; |
2532 | |
2533 | feaAnalysis->visualFlutter = (int) false0; |
2534 | |
2535 | return CAPS_SUCCESS0; |
2536 | } |
2537 | |
2538 | // Destroy (0 out all values and NULL all pointers) of feaAnalysis in the feaAnalysisStruct structure format |
2539 | int destroy_feaAnalysisStruct(feaAnalysisStruct *feaAnalysis) { |
2540 | int status; // Function return status |
2541 | |
2542 | if (feaAnalysis->name != NULL((void*)0)) EG_free(feaAnalysis->name); |
2543 | feaAnalysis->name = NULL((void*)0); // Analysis name |
2544 | |
2545 | feaAnalysis->analysisType = UnknownAnalysis; // Type of analysis |
2546 | |
2547 | feaAnalysis->analysisID = 0; // ID number of analysis |
2548 | |
2549 | // Loads for the analysis |
2550 | feaAnalysis->numLoad = 0; // Number of loads in the analysis |
2551 | if(feaAnalysis->loadSetID != NULL((void*)0)) EG_free(feaAnalysis->loadSetID); |
2552 | feaAnalysis->loadSetID = NULL((void*)0); // List of the load IDSs |
2553 | |
2554 | // Constraints for the analysis |
2555 | feaAnalysis->numConstraint = 0; // Number of constraints in the analysis |
2556 | if (feaAnalysis->constraintSetID != NULL((void*)0)) EG_free(feaAnalysis->constraintSetID); |
2557 | feaAnalysis->constraintSetID = NULL((void*)0); // List of constraint IDs |
2558 | |
2559 | // Supports for the analysis |
2560 | feaAnalysis->numSupport = 0; // Number of supports in the analysis |
2561 | if (feaAnalysis->supportSetID != NULL((void*)0)) EG_free(feaAnalysis->supportSetID); |
2562 | feaAnalysis->supportSetID = NULL((void*)0); // List of support IDs |
2563 | |
2564 | // Optimization constraints |
2565 | feaAnalysis->numDesignConstraint = 0; // Number of design constraints |
2566 | if (feaAnalysis->designConstraintSetID != NULL((void*)0)) EG_free(feaAnalysis->designConstraintSetID); |
2567 | feaAnalysis->designConstraintSetID = NULL((void*)0); // List of design constraint IDs |
2568 | |
2569 | // Optimization responses |
2570 | feaAnalysis->numDesignResponse = 0; // Number of design responses |
2571 | if (feaAnalysis->designResponseSetID != NULL((void*)0)) EG_free(feaAnalysis->designResponseSetID); |
2572 | feaAnalysis->designResponseSetID = NULL((void*)0); // List of design response IDs |
2573 | |
2574 | // Eigenvalue |
2575 | if (feaAnalysis->extractionMethod != NULL((void*)0)) EG_free(feaAnalysis->extractionMethod); |
2576 | feaAnalysis->extractionMethod = NULL((void*)0); |
2577 | |
2578 | feaAnalysis->frequencyRange[0] = 0; |
2579 | feaAnalysis->frequencyRange[1] = 0; |
2580 | |
2581 | feaAnalysis->numEstEigenvalue = 0; |
2582 | feaAnalysis->numDesiredEigenvalue = 0; |
2583 | |
2584 | if (feaAnalysis->eigenNormaliztion != NULL((void*)0)) EG_free(feaAnalysis->eigenNormaliztion); |
2585 | feaAnalysis->eigenNormaliztion = NULL((void*)0); |
2586 | |
2587 | feaAnalysis->gridNormaliztion = 0; |
2588 | feaAnalysis->componentNormaliztion = 0; |
2589 | |
2590 | feaAnalysis->lanczosMode = 2; //Lanczos mode for calculating eigenvalues |
2591 | |
2592 | if (feaAnalysis->lanczosType != NULL((void*)0)) EG_free(feaAnalysis->lanczosType); |
2593 | feaAnalysis->lanczosType = NULL((void*)0); //Lanczos matrix type (DPB, DGB) |
2594 | |
2595 | // Trim |
2596 | feaAnalysis->numMachNumber = 0; |
2597 | |
2598 | if (feaAnalysis->machNumber != NULL((void*)0)) EG_free(feaAnalysis->machNumber); |
2599 | feaAnalysis->machNumber = NULL((void*)0); // Mach number |
2600 | |
2601 | //feaAnalysis->machNumber = 0.0; // Mach number |
2602 | feaAnalysis->dynamicPressure = 0.0; // Dynamic pressure |
2603 | feaAnalysis->density = 0.0; // Density |
2604 | if (feaAnalysis->aeroSymmetryXY != NULL((void*)0)) EG_free(feaAnalysis->aeroSymmetryXY); |
2605 | if (feaAnalysis->aeroSymmetryXZ != NULL((void*)0)) EG_free(feaAnalysis->aeroSymmetryXZ); |
2606 | |
2607 | if (feaAnalysis->rigidVariable != NULL((void*)0)) { |
2608 | status = string_freeArray(feaAnalysis->numRigidVariable, &feaAnalysis->rigidVariable); |
2609 | if (status != CAPS_SUCCESS0) printf("Status %d during string_freeArray\n", status); |
2610 | } |
2611 | |
2612 | feaAnalysis->numRigidVariable = 0; // Number of trim rigid trim variables |
2613 | feaAnalysis->rigidVariable = NULL((void*)0); // List of character labels identifying rigid trim variables, size=[numRigidVariables] |
2614 | |
2615 | if (feaAnalysis->rigidConstraint != NULL((void*)0)) { |
2616 | status = string_freeArray(feaAnalysis->numRigidConstraint, &feaAnalysis->rigidConstraint); |
2617 | if (status != CAPS_SUCCESS0) printf("Status %d during string_freeArray\n", status); |
2618 | } |
2619 | |
2620 | feaAnalysis->numRigidConstraint = 0; // Number of rigid trim constrained variables |
2621 | feaAnalysis->rigidConstraint = NULL((void*)0); // List of character labels identifying rigid constrained trim variables, size=[numRigidConstraint] |
2622 | |
2623 | if (feaAnalysis->magRigidConstraint != NULL((void*)0)) EG_free(feaAnalysis->magRigidConstraint); |
2624 | feaAnalysis->magRigidConstraint = NULL((void*)0); // Magnitude of rigid constrained trim variables, size=[numRigidConstraint] |
2625 | |
2626 | if (feaAnalysis->controlConstraint != NULL((void*)0)) { |
2627 | status = string_freeArray(feaAnalysis->numControlConstraint, &feaAnalysis->controlConstraint); |
2628 | if (status != CAPS_SUCCESS0) printf("Status %d during string_freeArray\n", status); |
2629 | } |
2630 | |
2631 | feaAnalysis->numControlConstraint = 0; // Number of control surface constrained variables |
2632 | feaAnalysis->controlConstraint = NULL((void*)0); // List of character labels identifying control surfaces to be constrained trim variables, size=[numControlConstraint] |
2633 | |
2634 | EG_free(feaAnalysis->magControlConstraint); |
2635 | feaAnalysis->magControlConstraint = NULL((void*)0); // Magnitude of control surface constrained variables, size=[numControlConstraint] |
2636 | |
2637 | // Flutter |
2638 | feaAnalysis->numReducedFreq = 0; |
2639 | EG_free(feaAnalysis->reducedFreq); |
2640 | feaAnalysis->reducedFreq = NULL((void*)0); |
2641 | |
2642 | feaAnalysis->numFlutterVel = 0; |
2643 | EG_free(feaAnalysis->flutterVel); |
2644 | feaAnalysis->flutterVel = NULL((void*)0); |
2645 | |
2646 | feaAnalysis->flutterConvergenceParam = 0.0; |
2647 | |
2648 | feaAnalysis->visualFlutter = (int) false0; |
2649 | |
2650 | return CAPS_SUCCESS0; |
2651 | } |
2652 | |
2653 | // Initiate (0 out all values and NULL all pointers) of feaLoad in the feaLoadStruct structure format |
2654 | int initiate_feaLoadStruct(feaLoadStruct *feaLoad) { |
2655 | |
2656 | feaLoad->name = NULL((void*)0); // Load name |
2657 | |
2658 | feaLoad->loadType = UnknownLoad; // Load type |
2659 | |
2660 | feaLoad->loadID = 0; // ID number of load |
2661 | |
2662 | feaLoad->loadScaleFactor = 1; // Scale factor for when combining loads |
2663 | |
2664 | // Concentrated force at a grid point |
2665 | feaLoad->numGridID = 0; // Number of grid IDs in grid ID set |
2666 | feaLoad->gridIDSet = NULL((void*)0); // List of grid IDs to apply the constraint to. size = [numGridID] |
2667 | feaLoad->coordSystemID= 0; // Component number of coordinate system in which force vector is specified |
2668 | |
2669 | feaLoad->forceScaleFactor= 0.0; // Overall scale factor for the force |
2670 | feaLoad->directionVector[0] = 0.0; // [0]-x, [1]-y, [2]-z components of the force vector |
2671 | feaLoad->directionVector[1] = 0.0; |
2672 | feaLoad->directionVector[2] = 0.0; |
2673 | |
2674 | // Concentrated moment at a grid point (also uses coordSystemID and directionVector) |
2675 | feaLoad->momentScaleFactor= 0.0; // Overall scale factor for the moment |
2676 | |
2677 | // Gravitational load (also uses coordSystemID and directionVector) |
2678 | feaLoad->gravityAcceleration= 0.0; // Gravitational acceleration |
2679 | |
2680 | // Pressure load |
2681 | feaLoad->pressureForce= 0.0; // Pressure value |
2682 | feaLoad->pressureDistributeForce[0] = 0.0; // Pressure load at a specified grid location in the element |
2683 | feaLoad->pressureDistributeForce[1] = 0.0; |
2684 | feaLoad->pressureDistributeForce[2] = 0.0; |
2685 | feaLoad->pressureDistributeForce[3] = 0.0; |
2686 | |
2687 | feaLoad->pressureMultiDistributeForce = NULL((void*)0); // Unique pressure load at a specified grid location for |
2688 | // each element in elementIDSet size = [numElementID][4] - used in type PressureExternal |
2689 | // where the pressure force is being provided by an external source (i.e. data transfer) |
2690 | |
2691 | feaLoad->numElementID = 0; // Number of elements IDs in element ID set |
2692 | feaLoad->elementIDSet = NULL((void*)0); // List element IDs in which to apply the load. size = [numElementID] |
2693 | |
2694 | // Rotational velocity (also uses coordSystemID and directionVector) |
2695 | feaLoad->angularVelScaleFactor = 0.0; // Overall scale factor for the angular velocity |
2696 | feaLoad->angularAccScaleFactor = 0.0; // Overall scale factor for the angular acceleration |
2697 | |
2698 | // Thermal load - the temperature at a grid point - use gridIDSet |
2699 | feaLoad->temperature = 0.0; // Temperature value |
2700 | feaLoad->temperatureDefault = 0.0; // Default temperature of grid point explicitly not used |
2701 | |
2702 | feaLoad->temperatureMultiDistribute = NULL((void*)0); |
2703 | |
2704 | return CAPS_SUCCESS0; |
2705 | } |
2706 | |
2707 | // Copy feaLoad in the feaLoadStruct structure format |
2708 | // assumes that copy has been initialized with initiate_feaLoadStruct |
2709 | int copy_feaLoadStruct(void *aimInfo, feaLoadStruct *feaLoad, feaLoadStruct *copy) { |
2710 | |
2711 | int status = CAPS_SUCCESS0; |
2712 | int i; |
2713 | |
2714 | if (feaLoad->name != NULL((void*)0)) { |
2715 | AIM_STRDUP(copy->name, feaLoad->name, aimInfo, status){ if (copy->name != ((void*)0)) { status = -4; aim_status( aimInfo, status, "feaUtils.c", 2715, __func__, 1, "AIM_STRDUP: %s != NULL!" , "copy->name"); goto cleanup; } copy->name = EG_strdup (feaLoad->name); if (copy->name == ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 2715, __func__ , 2, "AIM_STRDUP: %s %s", "copy->name", feaLoad->name); goto cleanup; } }; // Load name |
2716 | } |
2717 | |
2718 | copy->loadType = feaLoad->loadType; // Load type |
2719 | |
2720 | copy->loadID = feaLoad->loadID; // ID number of load |
2721 | |
2722 | copy->loadScaleFactor = feaLoad->loadScaleFactor; // Scale factor for when combining loads |
2723 | |
2724 | // Concentrated force at a grid point |
2725 | copy->numGridID = feaLoad->numGridID; // Number of grid IDs in grid ID set |
2726 | // List of grid IDs to apply the constraint to |
2727 | AIM_ALLOC(copy->gridIDSet, feaLoad->numGridID, int, aimInfo, status){ if (copy->gridIDSet != ((void*)0)) { status = -4; aim_status (aimInfo, status, "feaUtils.c", 2727, __func__, 1, "AIM_ALLOC: %s != NULL" , "copy->gridIDSet"); goto cleanup; } size_t memorysize = feaLoad ->numGridID; copy->gridIDSet = (int *) EG_alloc(memorysize *sizeof(int)); if (copy->gridIDSet == ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 2727, __func__ , 3, "AIM_ALLOC: %s size %zu type %s", "copy->gridIDSet", memorysize , "int"); goto cleanup; } }; |
2728 | for (i = 0; i < feaLoad->numGridID; i++) |
2729 | copy->gridIDSet[i] = feaLoad->gridIDSet[i]; |
2730 | |
2731 | copy->coordSystemID = feaLoad->coordSystemID; // Component number of coordinate system in which force vector is specified |
2732 | copy->forceScaleFactor = feaLoad->forceScaleFactor; // Overall scale factor for the force |
2733 | copy->directionVector[0] = feaLoad->directionVector[0]; // [0]-x, [1]-y, [2]-z components of the force vector |
2734 | copy->directionVector[1] = feaLoad->directionVector[1]; |
2735 | copy->directionVector[2] = feaLoad->directionVector[2]; |
2736 | |
2737 | // Concentrated moment at a grid pofeaLoad->(also uses coordSystemID and directionVector) |
2738 | copy->momentScaleFactor = feaLoad->momentScaleFactor; // Overall scale factor for the moment |
2739 | |
2740 | // Gravitational load (also uses coordSystemID and directionVector) |
2741 | copy->gravityAcceleration = feaLoad->gravityAcceleration; // Gravitational acceleration |
2742 | |
2743 | // Pressure load |
2744 | copy->pressureForce = feaLoad->pressureForce; // Pressure value |
2745 | |
2746 | copy->pressureDistributeForce[0] = feaLoad->pressureDistributeForce[0]; // Pressure load at a specified grid location in the element |
2747 | copy->pressureDistributeForce[1] = feaLoad->pressureDistributeForce[1]; |
2748 | copy->pressureDistributeForce[2] = feaLoad->pressureDistributeForce[2]; |
2749 | copy->pressureDistributeForce[3] = feaLoad->pressureDistributeForce[3]; |
2750 | |
2751 | // Unique pressure load at a specified grid location for |
2752 | //each element in elementIDSet size = [4*numElementID]- used in type PressureExternal |
2753 | if (feaLoad->pressureMultiDistributeForce != NULL((void*)0)) { |
2754 | AIM_ALLOC(copy->pressureMultiDistributeForce, feaLoad->numElementID, double, aimInfo, status){ if (copy->pressureMultiDistributeForce != ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 2754, __func__ , 1, "AIM_ALLOC: %s != NULL", "copy->pressureMultiDistributeForce" ); goto cleanup; } size_t memorysize = feaLoad->numElementID ; copy->pressureMultiDistributeForce = (double *) EG_alloc (memorysize*sizeof(double)); if (copy->pressureMultiDistributeForce == ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c" , 2754, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "copy->pressureMultiDistributeForce" , memorysize, "double"); goto cleanup; } }; |
2755 | for (i = 0; i < 4*feaLoad->numElementID; i++) |
2756 | copy->pressureMultiDistributeForce[i] = feaLoad->pressureMultiDistributeForce[i]; |
2757 | } else { |
2758 | copy->pressureMultiDistributeForce = NULL((void*)0); |
2759 | } |
2760 | |
2761 | copy->numElementID = feaLoad->numElementID; // Number of elements IDs in element ID set |
2762 | AIM_ALLOC(copy->elementIDSet, feaLoad->numElementID, int, aimInfo, status){ if (copy->elementIDSet != ((void*)0)) { status = -4; aim_status (aimInfo, status, "feaUtils.c", 2762, __func__, 1, "AIM_ALLOC: %s != NULL" , "copy->elementIDSet"); goto cleanup; } size_t memorysize = feaLoad->numElementID; copy->elementIDSet = (int *) EG_alloc (memorysize*sizeof(int)); if (copy->elementIDSet == ((void *)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c" , 2762, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "copy->elementIDSet" , memorysize, "int"); goto cleanup; } }; // List element IDs in which to apply the load |
2763 | for (i = 0; i < feaLoad->numElementID; i++) |
2764 | copy->elementIDSet[i] = feaLoad->elementIDSet[i]; |
2765 | |
2766 | // Rotational velocity (also uses coordSystemID and directionVector) |
2767 | copy->angularVelScaleFactor = feaLoad->angularVelScaleFactor; // Overall scale factor for the angular velocity |
2768 | copy->angularAccScaleFactor = feaLoad->angularAccScaleFactor; // Overall scale factor for the angular acceleration |
2769 | |
2770 | // Thermal load - the temperature at a grid point - use gridIDSet |
2771 | copy->temperature = feaLoad->temperature; // Temperature value |
2772 | copy->temperatureDefault = feaLoad->temperatureDefault; // Default temperature of grid point explicitly not used |
2773 | |
2774 | if (feaLoad->temperatureMultiDistribute != NULL((void*)0)) { |
2775 | AIM_ALLOC(copy->temperatureMultiDistribute, feaLoad->numGridID, double, aimInfo, status){ if (copy->temperatureMultiDistribute != ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 2775, __func__ , 1, "AIM_ALLOC: %s != NULL", "copy->temperatureMultiDistribute" ); goto cleanup; } size_t memorysize = feaLoad->numGridID; copy->temperatureMultiDistribute = (double *) EG_alloc(memorysize *sizeof(double)); if (copy->temperatureMultiDistribute == ( (void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c" , 2775, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "copy->temperatureMultiDistribute" , memorysize, "double"); goto cleanup; } }; |
2776 | for (i = 0; i < feaLoad->numGridID; i++) |
2777 | copy->temperatureMultiDistribute[i] = feaLoad->temperatureMultiDistribute[i]; |
2778 | } else { |
2779 | copy->temperatureMultiDistribute = NULL((void*)0); |
2780 | } |
2781 | |
2782 | cleanup: |
2783 | return status; |
2784 | } |
2785 | |
2786 | // Destroy (0 out all values and NULL all pointers) of feaLoad in the feaLoadStruct structure format |
2787 | int destroy_feaLoadStruct(feaLoadStruct *feaLoad) { |
2788 | |
2789 | AIM_FREE(feaLoad->name){ EG_free(feaLoad->name); feaLoad->name = ((void*)0); }; // Load name |
2790 | |
2791 | feaLoad->loadType = UnknownLoad; // Load type |
2792 | |
2793 | feaLoad->loadID = 0; // ID number of load |
2794 | |
2795 | feaLoad->loadScaleFactor = 1; // Scale factor for when combining loads |
2796 | |
2797 | // Concentrated force at a grid point |
2798 | feaLoad->numGridID = 0; // Number of grid IDs in grid ID set |
2799 | AIM_FREE(feaLoad->gridIDSet){ EG_free(feaLoad->gridIDSet); feaLoad->gridIDSet = ((void *)0); }; // List of grid IDs to apply the constraint to |
2800 | |
2801 | feaLoad->coordSystemID= 0; // Component number of coordinate system in which force vector is specified |
2802 | feaLoad->forceScaleFactor= 0; // Overall scale factor for the force |
2803 | feaLoad->directionVector[0] = 0; // [0]-x, [1]-y, [2]-z components of the force vector |
2804 | feaLoad->directionVector[1] = 0; |
2805 | feaLoad->directionVector[2] = 0; |
2806 | |
2807 | // Concentrated moment at a grid pofeaLoad->(also uses coordSystemID and directionVector) |
2808 | feaLoad->momentScaleFactor= 0; // Overall scale factor for the moment |
2809 | |
2810 | // Gravitational load (also uses coordSystemID and directionVector) |
2811 | feaLoad->gravityAcceleration= 0; // Gravitational acceleration |
2812 | |
2813 | // Pressure load |
2814 | feaLoad->pressureForce= 0; // Pressure value |
2815 | |
2816 | feaLoad->pressureDistributeForce[0] = 0; // Pressure load at a specified grid location in the element |
2817 | feaLoad->pressureDistributeForce[1] = 0; |
2818 | feaLoad->pressureDistributeForce[2] = 0; |
2819 | feaLoad->pressureDistributeForce[3] = 0; |
2820 | |
2821 | // Unique pressure load at a specified grid location for |
2822 | //each element in elementIDSet size = [4*numElementID]- used in type PressureExternal |
2823 | AIM_FREE(feaLoad->pressureMultiDistributeForce){ EG_free(feaLoad->pressureMultiDistributeForce); feaLoad-> pressureMultiDistributeForce = ((void*)0); }; |
2824 | |
2825 | |
2826 | feaLoad->numElementID = 0; // Number of elements IDs in element ID set |
2827 | AIM_FREE(feaLoad->elementIDSet){ EG_free(feaLoad->elementIDSet); feaLoad->elementIDSet = ((void*)0); }; // List element IDs in which to apply the load |
2828 | |
2829 | // Rotational velocity (also uses coordSystemID and directionVector) |
2830 | feaLoad->angularVelScaleFactor = 0.0; // Overall scale factor for the angular velocity |
2831 | feaLoad->angularAccScaleFactor = 0.0; // Overall scale factor for the angular acceleration |
2832 | |
2833 | // Thermal load - the temperature at a grid point - use gridIDSet |
2834 | feaLoad->temperature = 0.0; // Temperature value |
2835 | feaLoad->temperatureDefault = 0.0; // Default temperature of grid point explicitly not used |
2836 | |
2837 | AIM_FREE(feaLoad->temperatureMultiDistribute){ EG_free(feaLoad->temperatureMultiDistribute); feaLoad-> temperatureMultiDistribute = ((void*)0); }; |
2838 | |
2839 | return CAPS_SUCCESS0; |
2840 | } |
2841 | |
2842 | // Initiate (0 out all values and NULL all pointers) of feaDesignVariable in the feaDesignVariableStruct structure format |
2843 | int initiate_feaDesignVariableStruct(feaDesignVariableStruct *feaDesignVariable) { |
2844 | |
2845 | feaDesignVariable->name = NULL((void*)0); |
2846 | |
2847 | feaDesignVariable->designVariableID = 0; // ID number of design variable |
2848 | |
2849 | |
2850 | feaDesignVariable->initialValue = 0.0; // Initial value of design variable |
2851 | feaDesignVariable->lowerBound = 0.0; // Lower bounds of variable |
2852 | feaDesignVariable->upperBound = 0.0; // Upper bounds of variable |
2853 | feaDesignVariable->maxDelta= 0.0; // Move limit for design variable |
2854 | |
2855 | feaDesignVariable->numDiscreteValue = 0; // Number of discrete values that a design variable can assume |
2856 | |
2857 | feaDesignVariable->discreteValue = NULL((void*)0); // List of discrete values that a design variable can assume; |
2858 | |
2859 | feaDesignVariable->numIndependVariable = 0; // Number of independent variables this variables depends on |
2860 | feaDesignVariable->independVariable = NULL((void*)0); // List of independent variable names, size[numIndependVariable] |
2861 | feaDesignVariable->independVariableID = NULL((void*)0);// List of independent variable designVariableIDs, size[numIndependVariable] |
2862 | feaDesignVariable->independVariableWeight = NULL((void*)0); // List of independent variable weights, size[numIndependVariable] |
2863 | |
2864 | feaDesignVariable->variableWeight[0] = 0.0; // Weight to apply to if variable is dependent |
2865 | feaDesignVariable->variableWeight[1] = 0.0; |
2866 | |
2867 | feaDesignVariable->numRelation = 0; |
2868 | feaDesignVariable->relationSet = NULL((void*)0); |
2869 | |
2870 | return CAPS_SUCCESS0; |
2871 | } |
2872 | |
2873 | // Initiate (0 out all values and NULL all pointers) of feaDesignVariable in the feaDesignVariableStruct structure format |
2874 | int destroy_feaDesignVariableStruct(feaDesignVariableStruct *feaDesignVariable) { |
2875 | |
2876 | if (feaDesignVariable->name != NULL((void*)0)) EG_free(feaDesignVariable->name); |
2877 | feaDesignVariable->name = NULL((void*)0); |
2878 | |
2879 | feaDesignVariable->designVariableID = 0; // ID number of design variable |
2880 | |
2881 | feaDesignVariable->initialValue = 0.0; // Initial value of design variable |
2882 | feaDesignVariable->lowerBound = 0.0; // Lower bounds of variable |
2883 | feaDesignVariable->upperBound = 0.0; // Upper bounds of variable |
2884 | feaDesignVariable->maxDelta= 0.0; // Move limit for design variable |
2885 | |
2886 | feaDesignVariable->numDiscreteValue = 0; // Number of discrete values that a design variable can assume; |
2887 | if (feaDesignVariable->discreteValue != NULL((void*)0)) EG_free(feaDesignVariable->discreteValue); |
2888 | feaDesignVariable->discreteValue = NULL((void*)0); // List of discrete values that a design variable can assume; |
2889 | |
2890 | (void) string_freeArray(feaDesignVariable->numIndependVariable, &feaDesignVariable->independVariable); |
2891 | feaDesignVariable->independVariable = NULL((void*)0); // List of independent variable names, size[numIndependVariable] |
2892 | |
2893 | feaDesignVariable->numIndependVariable = 0; // Number of independent variables this variables depends on |
2894 | |
2895 | if (feaDesignVariable->independVariableID != NULL((void*)0)) EG_free(feaDesignVariable->independVariableID); |
2896 | feaDesignVariable->independVariableID = NULL((void*)0);// List of independent variable designVariableIDs |
2897 | |
2898 | if (feaDesignVariable->independVariableWeight != NULL((void*)0)) EG_free(feaDesignVariable->independVariableWeight); |
2899 | feaDesignVariable->independVariableWeight = NULL((void*)0); // List of independent variable weights, size[numIndependVariable] |
2900 | |
2901 | feaDesignVariable->variableWeight[0] = 0.0; // Weight to apply to if variable is dependent |
2902 | feaDesignVariable->variableWeight[1] = 0.0; |
2903 | |
2904 | feaDesignVariable->numRelation = 0; |
2905 | if (feaDesignVariable->relationSet != NULL((void*)0)) EG_free(feaDesignVariable->relationSet); |
2906 | |
2907 | return CAPS_SUCCESS0; |
2908 | |
2909 | } |
2910 | |
2911 | // Initiate (0 out all values and NULL all pointers) of feaDesignConstraint in the feaDesignConstraintStruct structure format |
2912 | int initiate_feaDesignConstraintStruct(feaDesignConstraintStruct *feaDesignConstraint) { |
2913 | |
2914 | feaDesignConstraint->name = NULL((void*)0); |
2915 | |
2916 | feaDesignConstraint->designConstraintID = 0; // ID number of design constraint |
2917 | |
2918 | feaDesignConstraint->designConstraintType = UnknownDesignCon; |
2919 | |
2920 | feaDesignConstraint->responseType = NULL((void*)0); // Response type options for DRESP1 Entry |
2921 | |
2922 | feaDesignConstraint->lowerBound = 0.0; // Lower bounds of design response |
2923 | feaDesignConstraint->upperBound = 0.0; // Upper bounds of design response |
2924 | |
2925 | feaDesignConstraint->numPropertyID = 0; // Number of property ID to apply the design variable to |
2926 | feaDesignConstraint->propertySetID = NULL((void*)0); // List of property IDs |
2927 | feaDesignConstraint->propertySetType = NULL((void*)0); // List of property types corresponding to the propertySetID |
2928 | |
2929 | feaDesignConstraint->fieldPosition = 0; // Position in card to apply design variable to |
2930 | feaDesignConstraint->fieldName = NULL((void*)0); // Name of property/material to apply design variable to |
2931 | |
2932 | feaDesignConstraint->velocityType = NULL((void*)0); |
2933 | feaDesignConstraint->scalingFactor = 0.0; |
2934 | |
2935 | feaDesignConstraint->numVelocity = 0; |
2936 | feaDesignConstraint->velocity = NULL((void*)0); |
2937 | |
2938 | feaDesignConstraint->numDamping = 0; |
2939 | feaDesignConstraint->damping = NULL((void*)0); |
2940 | |
2941 | return CAPS_SUCCESS0; |
2942 | } |
2943 | |
2944 | // Destroy (0 out all values and NULL all pointers) of feaDesignConstraint in the feaDesignConstraintStruct structure format |
2945 | int destroy_feaDesignConstraintStruct(feaDesignConstraintStruct *feaDesignConstraint) { |
2946 | |
2947 | if (feaDesignConstraint->name != NULL((void*)0)) EG_free(feaDesignConstraint->name); |
2948 | feaDesignConstraint->name = NULL((void*)0); |
2949 | |
2950 | feaDesignConstraint->designConstraintID = 0; // ID number of design constraint |
2951 | |
2952 | feaDesignConstraint->designConstraintType = UnknownDesignCon; |
2953 | |
2954 | if (feaDesignConstraint->responseType != NULL((void*)0)) EG_free(feaDesignConstraint->responseType); |
2955 | feaDesignConstraint->responseType = NULL((void*)0); // Response type options for DRESP1 Entry |
2956 | |
2957 | feaDesignConstraint->lowerBound = 0.0; // Lower bounds of design response |
2958 | feaDesignConstraint->upperBound = 0.0; // Upper bounds of design response |
2959 | |
2960 | feaDesignConstraint->numPropertyID = 0; // Number of property ID to apply the design variable to |
2961 | |
2962 | if (feaDesignConstraint->propertySetID != NULL((void*)0)) EG_free(feaDesignConstraint->propertySetID); |
2963 | feaDesignConstraint->propertySetID = NULL((void*)0); // List of property IDs |
2964 | |
2965 | if (feaDesignConstraint->propertySetType != NULL((void*)0)) EG_free(feaDesignConstraint->propertySetType); |
2966 | feaDesignConstraint->propertySetType = NULL((void*)0); // List of property types corresponding to the propertySetID |
2967 | |
2968 | feaDesignConstraint->fieldPosition = 0; // Position in card to apply design variable to |
2969 | if (feaDesignConstraint->fieldName != NULL((void*)0)) EG_free(feaDesignConstraint->fieldName); |
2970 | feaDesignConstraint->fieldName = NULL((void*)0); // Name of property/material to apply design variable to |
2971 | |
2972 | if (feaDesignConstraint->velocityType != NULL((void*)0)) EG_free(feaDesignConstraint->velocityType); |
2973 | feaDesignConstraint->velocityType = NULL((void*)0); |
2974 | feaDesignConstraint->scalingFactor = 0.0; |
2975 | |
2976 | if (feaDesignConstraint->velocity != NULL((void*)0)) EG_free(feaDesignConstraint->velocity); |
2977 | feaDesignConstraint->numVelocity = 0; |
2978 | feaDesignConstraint->velocity = NULL((void*)0); |
2979 | |
2980 | if (feaDesignConstraint->damping != NULL((void*)0)) EG_free(feaDesignConstraint->damping); |
2981 | feaDesignConstraint->numDamping = 0; |
2982 | feaDesignConstraint->damping = NULL((void*)0); |
2983 | |
2984 | return CAPS_SUCCESS0; |
2985 | |
2986 | } |
2987 | |
2988 | // Initiate (0 out all values and NULL all pointers) of feaOptimizationControl in the feaOptimizationControlStruct structure format |
2989 | int initiate_feaOptimizationControlStruct(feaOptimizationControlStruct *feaOptimizationControl) { |
2990 | |
2991 | feaOptimizationControl->fullyStressedDesign = 0; // ASTROS specific - fully stressed design number of iterations |
2992 | feaOptimizationControl->mathProgramming = 0; // Math programming number of iteratinons |
2993 | feaOptimizationControl->maxIter = 0; // Maximum number of optimization iterations |
2994 | feaOptimizationControl->constraintRetention = 0.0; // Constraint retention factor |
2995 | feaOptimizationControl->eps = 0.0; // A different constraint retention factor? |
2996 | feaOptimizationControl->moveLimit = 0.0; // Move limit |
2997 | |
2998 | return CAPS_SUCCESS0; |
2999 | } |
3000 | |
3001 | // Destroy (0 out all values and NULL all pointers) of feaOptimizationControl in the feaOptimizationControlStruct structure format |
3002 | int destroy_feaOptimzationControlStruct(feaOptimizationControlStruct *feaOptimizationControl) { |
3003 | |
3004 | feaOptimizationControl->fullyStressedDesign = 0; // ASTROS specific - fully stressed design number of iterations |
3005 | feaOptimizationControl->mathProgramming = 0; // Math programming number of iteratinons |
3006 | feaOptimizationControl->maxIter = 0; // Maximum number of optimization iterations |
3007 | feaOptimizationControl->constraintRetention = 0.0; // Constraint retention factor |
3008 | feaOptimizationControl->eps = 0.0; // A different constraint retention factor? |
3009 | feaOptimizationControl->moveLimit = 0.0; // Move limit |
3010 | |
3011 | return CAPS_SUCCESS0; |
3012 | } |
3013 | |
3014 | // Initiate (0 out all values and NULL all pointers) of feaCoordSystem in the feaCoordSystemStruct structure format |
3015 | int initiate_feaCoordSystemStruct(feaCoordSystemStruct *feaCoordSystem) { |
3016 | |
3017 | int i; // Indexing |
3018 | |
3019 | feaCoordSystem->name = NULL((void*)0); // Coordinate system name |
3020 | |
3021 | feaCoordSystem->coordSystemType = UnknownCoordSystem; // Coordinate system type |
3022 | |
3023 | feaCoordSystem->coordSystemID = 0; // ID number of coordinate system |
3024 | feaCoordSystem->refCoordSystemID = 0; // ID of reference coordinate system |
3025 | |
3026 | for (i = 0; i < 3; i++) { |
3027 | feaCoordSystem->origin[i] = 0; // x, y, and z coordinates for the origin |
3028 | |
3029 | feaCoordSystem->normal1[i] = 0; // First normal direction |
3030 | feaCoordSystem->normal2[i] = 0; // Second normal direction |
3031 | feaCoordSystem->normal3[i] = 0; // Third normal direction - found from normal1 x normal2 |
3032 | } |
3033 | |
3034 | return CAPS_SUCCESS0; |
3035 | } |
3036 | |
3037 | // Destroy (0 out all values and NULL all pointers) of feaCoordSystem in the feaCoordSystemStruct structure format |
3038 | int destroy_feaCoordSystemStruct(feaCoordSystemStruct *feaCoordSystem) { |
3039 | |
3040 | int i; // Indexing |
3041 | |
3042 | if (feaCoordSystem->name != NULL((void*)0)) EG_free(feaCoordSystem->name); |
3043 | feaCoordSystem->name = NULL((void*)0); // Coordinate system name |
3044 | |
3045 | feaCoordSystem->coordSystemType = UnknownCoordSystem; // Coordinate system type |
3046 | |
3047 | feaCoordSystem->coordSystemID = 0; // ID number of coordinate system |
3048 | feaCoordSystem->refCoordSystemID = 0; // ID of reference coordinate system |
3049 | |
3050 | for (i = 0; i < 3; i++) { |
3051 | feaCoordSystem->origin[i] = 0; // x, y, and z coordinates for the origin |
3052 | |
3053 | feaCoordSystem->normal1[i] = 0; // First normal direction |
3054 | feaCoordSystem->normal2[i] = 0; // Second normal direction |
3055 | feaCoordSystem->normal3[i] = 0; // Third normal direction - found from normal1 x normal2 |
3056 | } |
3057 | |
3058 | return CAPS_SUCCESS0; |
3059 | } |
3060 | |
3061 | // Initiate (0 out all values and NULL all pointers) of feaAero in the feaAeroStruct structure format |
3062 | int initiate_feaAeroStruct(feaAeroStruct *feaAero) { |
3063 | |
3064 | int status; // Function return status |
3065 | |
3066 | feaAero->name = NULL((void*)0); // Coordinate system name |
3067 | |
3068 | feaAero->surfaceID = 0; // Surface ID |
3069 | feaAero->coordSystemID = 0; // Coordinate system ID |
3070 | |
3071 | feaAero->numGridID = 0; // Number of grid IDs in grid ID set for the spline |
3072 | feaAero->gridIDSet = NULL((void*)0); // List of grid IDs to apply spline to. size = [numGridID] |
3073 | |
3074 | status = initiate_vlmSurfaceStruct(&feaAero->vlmSurface); |
3075 | if (status != CAPS_SUCCESS0) printf("Status %d during initiate_vlmSurfaceStruct\n", status); |
3076 | |
3077 | return CAPS_SUCCESS0; |
3078 | } |
3079 | |
3080 | // Destroy (0 out all values and NULL all pointers) of feaAero in the feaAeroStruct structure format |
3081 | int destroy_feaAeroStruct(feaAeroStruct *feaAero) { |
3082 | |
3083 | int status; // Function return status |
3084 | |
3085 | if (feaAero->name != NULL((void*)0)) EG_free(feaAero->name); |
3086 | feaAero->name = NULL((void*)0); // Coordinate system name |
3087 | |
3088 | feaAero->surfaceID = 0; // Surface ID |
3089 | feaAero->coordSystemID = 0; // Coordinate system ID |
3090 | |
3091 | feaAero->numGridID = 0; // Number of grid IDs in grid ID set for the spline |
3092 | |
3093 | if (feaAero->gridIDSet != NULL((void*)0)) EG_free(feaAero->gridIDSet); |
3094 | feaAero->gridIDSet = NULL((void*)0); // List of grid IDs to apply spline to. size = [numGridID] |
3095 | |
3096 | status = destroy_vlmSurfaceStruct(&feaAero->vlmSurface); |
3097 | if (status != CAPS_SUCCESS0) printf("Status %d during destroy_vlmSurfaceStruct\n", status); |
3098 | |
3099 | return CAPS_SUCCESS0; |
3100 | } |
3101 | |
3102 | // Initiate (0 out all values and NULL all pointers) of feaAeroRef in the feaAeroRefStruct structure format |
3103 | int initiate_feaAeroRefStruct(feaAeroRefStruct *feaAeroRef) { |
3104 | |
3105 | feaAeroRef->coordSystemID = 0; // Aerodynamic coordinate sytem id |
3106 | feaAeroRef->rigidMotionCoordSystemID = 0; // Reference coordinate system identification for rigid body motions. |
3107 | |
3108 | feaAeroRef->refChord = 1.0; // Reference chord length. Reference span. (Real > 0.0) |
3109 | feaAeroRef->refSpan = 1.0; // Reference span |
3110 | feaAeroRef->refArea = 1.0; // Reference area |
3111 | feaAeroRef->refGridID = 0; |
3112 | |
3113 | feaAeroRef->symmetryXZ = 0; // Symmetry key for the aero coordinate x-z plane. (Integer = +1 for symmetry, 0 for no symmetry, |
3114 | // and -1 for antisymmetry; Default = 0) |
3115 | feaAeroRef->symmetryXY = 0; // The symmetry key for the aero coordinate x-y plane can be used to simulate ground effects. |
3116 | // (Integer = +1 for antisymmetry, 0 for no symmetry, and -1 for symmetry; Default = 0) |
3117 | return CAPS_SUCCESS0; |
3118 | } |
3119 | |
3120 | // Destroy (0 out all values and NULL all pointers) of feaAeroRef in the feaAeroRefStruct structure format |
3121 | int destroy_feaAeroRefStruct(feaAeroRefStruct *feaAeroRef) { |
3122 | |
3123 | feaAeroRef->coordSystemID = 0; // Aerodynamic coordinate sytem id |
3124 | feaAeroRef->rigidMotionCoordSystemID = 0; // Reference coordinate system identification for rigid body motions. |
3125 | |
3126 | feaAeroRef->refChord = 0; // Reference chord length. Reference span. (Real > 0.0) |
3127 | feaAeroRef->refSpan = 0; // Reference span |
3128 | feaAeroRef->refArea = 0; // Reference area |
3129 | feaAeroRef->refGridID = 0; |
3130 | |
3131 | feaAeroRef->symmetryXZ = 0; // Symmetry key for the aero coordinate x-z plane. (Integer = +1 for symmetry, 0 for no symmetry, |
3132 | // and -1 for antisymmetry; Default = 0) |
3133 | feaAeroRef->symmetryXY = 0; // The symmetry key for the aero coordinate x-y plane can be used to simulate ground effects. |
3134 | // (Integer = +1 for antisymmetry, 0 for no symmetry, and -1 for symmetry; Default = 0) |
3135 | return CAPS_SUCCESS0; |
3136 | } |
3137 | |
3138 | // Initiate (0 out all values and NULL all pointers) of feaConnect in the feaConnectionStruct structure format |
3139 | int initiate_feaConnectionStruct(feaConnectionStruct *feaConnect) { |
3140 | |
3141 | feaConnect->name = NULL((void*)0); // Connection name |
3142 | |
3143 | feaConnect->connectionID =0; // Connection ID |
3144 | |
3145 | feaConnect->connectionType = UnknownConnection; // Connection type |
3146 | |
3147 | feaConnect->elementID = 0; |
3148 | |
3149 | // RBE2 - dependent degrees of freedom |
3150 | feaConnect->connectivity[0] = 0; // Grid IDs - 0 index = Independent grid ID, 1 index = Dependent grid ID |
3151 | feaConnect->connectivity[1] = 0; |
3152 | feaConnect->dofDependent = 0; |
3153 | |
3154 | // Spring |
3155 | feaConnect->stiffnessConst = 0.0; |
3156 | feaConnect->componentNumberStart = 0; |
3157 | feaConnect->componentNumberEnd = 0; |
3158 | feaConnect->dampingConst = 0.0; |
3159 | feaConnect->stressCoeff = 0.0; |
3160 | |
3161 | // Damper - see spring for additional entries |
3162 | |
3163 | // Mass (scalar) - see spring for additional entries |
3164 | feaConnect->mass = 0.0; |
3165 | |
3166 | // RBE3 - master/slave |
3167 | feaConnect->numMaster = 0; |
3168 | feaConnect->masterIDSet = NULL((void*)0); // Independent |
3169 | feaConnect->masterWeighting = NULL((void*)0); |
3170 | feaConnect->masterComponent = NULL((void*)0); |
3171 | |
3172 | return CAPS_SUCCESS0; |
3173 | } |
3174 | |
3175 | // Destroy (0 out all values and NULL all pointers) of feaConnect in the feaConnectionStruct structure format |
3176 | int destroy_feaConnectionStruct(feaConnectionStruct *feaConnect) { |
3177 | |
3178 | if (feaConnect->name != NULL((void*)0)) EG_free(feaConnect->name); |
3179 | feaConnect->name = NULL((void*)0); // Connection name |
3180 | |
3181 | feaConnect->connectionID =0; // Connection ID |
3182 | |
3183 | feaConnect->connectionType = UnknownConnection; // Connection type |
3184 | |
3185 | feaConnect->elementID = 0; |
3186 | |
3187 | // RBE2 - dependent degrees of freedom |
3188 | feaConnect->connectivity[0] = 0; // Grid IDs - 0 index = Independent grid ID, 1 index = Dependent grid ID |
3189 | feaConnect->connectivity[1] = 0; |
3190 | feaConnect->dofDependent = 0; |
3191 | |
3192 | // Spring |
3193 | feaConnect->stiffnessConst = 0.0; |
3194 | feaConnect->componentNumberStart = 0; |
3195 | feaConnect->componentNumberEnd = 0; |
3196 | feaConnect->dampingConst = 0.0; |
3197 | feaConnect->stressCoeff = 0.0; |
3198 | |
3199 | // Damper - see spring for additional entries |
3200 | |
3201 | // Mass (scalar) - see spring for additional entries |
3202 | feaConnect->mass = 0.0; |
3203 | |
3204 | // RBE3 - master/slave |
3205 | feaConnect->numMaster = 0; |
3206 | if (feaConnect->masterIDSet != NULL((void*)0)) EG_free(feaConnect->masterIDSet); |
3207 | feaConnect->masterIDSet = NULL((void*)0); // Independent |
3208 | if (feaConnect->masterWeighting != NULL((void*)0)) EG_free(feaConnect->masterWeighting); |
3209 | feaConnect->masterWeighting = NULL((void*)0); |
3210 | if (feaConnect->masterComponent != NULL((void*)0)) EG_free(feaConnect->masterComponent); |
3211 | feaConnect->masterComponent = NULL((void*)0); |
3212 | |
3213 | return CAPS_SUCCESS0; |
3214 | } |
3215 | |
3216 | int initiate_feaDesignEquationStruct(feaDesignEquationStruct *equation) { |
3217 | |
3218 | if (equation == NULL((void*)0)) return CAPS_NULLVALUE-307; |
3219 | |
3220 | equation->equationID = 0; |
3221 | equation->name = NULL((void*)0); |
3222 | equation->equationArraySize = 0; |
3223 | equation->equationArray = NULL((void*)0); |
3224 | |
3225 | return CAPS_SUCCESS0; |
3226 | } |
3227 | |
3228 | int destroy_feaDesignEquationStruct(feaDesignEquationStruct *equation) { |
3229 | |
3230 | int i; |
3231 | |
3232 | if (equation == NULL((void*)0)) return CAPS_NULLVALUE-307; |
3233 | |
3234 | if (equation->name != NULL((void*)0)) EG_free(equation->name); |
3235 | |
3236 | if (equation->equationArray != NULL((void*)0)) { |
3237 | for (i = 0; i < equation->equationArraySize; i++) { |
3238 | if (equation->equationArray[i] != NULL((void*)0)) { |
3239 | EG_free(equation->equationArray[i]); |
3240 | } |
3241 | } |
3242 | EG_free(equation->equationArray); |
3243 | } |
3244 | |
3245 | return initiate_feaDesignEquationStruct(equation); |
3246 | } |
3247 | |
3248 | int initiate_feaDesignResponseStruct(feaDesignResponseStruct *response) { |
3249 | |
3250 | if (response == NULL((void*)0)) return CAPS_NULLVALUE-307; |
3251 | |
3252 | response->responseID = 0; |
3253 | |
3254 | response->name = NULL((void*)0); |
3255 | |
3256 | response->responseType = NULL((void*)0); |
3257 | response->propertyType = NULL((void*)0); |
3258 | |
3259 | response->region = 0; |
3260 | |
3261 | response->component = 0; // Component number |
3262 | response->itemCode = 0; // Item code |
3263 | response->modeNumber = 0; // Mode number |
3264 | |
3265 | response->lamina = 0; // Lamina number |
3266 | response->frequency = 0.0; // Frequency value |
3267 | response->time = 0.0; // Time value |
3268 | response->restraintFlag = 0; // Restraint flag |
3269 | |
3270 | response->gridID = 0; // Grid ID |
3271 | response->propertyID = 0; // Property entry ID |
3272 | |
3273 | return CAPS_SUCCESS0; |
3274 | } |
3275 | |
3276 | int destroy_feaDesignResponseStruct(feaDesignResponseStruct *response) { |
3277 | |
3278 | if (response == NULL((void*)0)) return CAPS_NULLVALUE-307; |
3279 | |
3280 | if (response->name != NULL((void*)0)) EG_free(response->name); |
3281 | |
3282 | if (response->responseType != NULL((void*)0)) EG_free(response->responseType); |
3283 | if (response->propertyType != NULL((void*)0)) EG_free(response->propertyType); |
3284 | |
3285 | return initiate_feaDesignResponseStruct(response); |
3286 | } |
3287 | |
3288 | int initiate_feaDesignEquationResponseStruct(feaDesignEquationResponseStruct* equationResponse) { |
3289 | |
3290 | if (equationResponse == NULL((void*)0)) return CAPS_NULLVALUE-307; |
3291 | |
3292 | equationResponse->equationResponseID = 0; |
3293 | |
3294 | equationResponse->name = NULL((void*)0); // Name of the equation |
3295 | |
3296 | equationResponse->equationName = NULL((void*)0); |
3297 | |
3298 | equationResponse->region = 0; // Region identifier for constant screening |
3299 | |
3300 | equationResponse->numDesignVariable = 0; |
3301 | equationResponse->designVariableNameSet = NULL((void*)0); // Design variable names, size = [numDesignVariable] |
3302 | |
3303 | equationResponse->numConstant = 0; |
3304 | equationResponse->constantLabelSet = NULL((void*)0); // Labels of the table constants, size = [numConstant] |
3305 | |
3306 | equationResponse->numResponse = 0; |
3307 | equationResponse->responseNameSet = NULL((void*)0); // Names of design sensitivity response quantities, size = [numResponse] |
3308 | |
3309 | equationResponse->numGrid = 0; |
3310 | equationResponse->gridIDSet = NULL((void*)0); // Grid IDs, size = [numGrid] |
3311 | equationResponse->dofNumberSet = NULL((void*)0); // Degree of freedom numbers, size = [numGrid] |
3312 | |
3313 | equationResponse->numEquationResponse = 0; |
3314 | equationResponse->equationResponseNameSet = NULL((void*)0); // Names of design sensitivity equation response quantities, size = [numEquationResponse] |
3315 | |
3316 | return CAPS_SUCCESS0; |
3317 | } |
3318 | |
3319 | int destroy_feaDesignEquationResponseStruct(feaDesignEquationResponseStruct* equationResponse) { |
3320 | |
3321 | if (equationResponse == NULL((void*)0)) return CAPS_NULLVALUE-307; |
3322 | |
3323 | if (equationResponse->name != NULL((void*)0)) EG_free(equationResponse->name); |
3324 | |
3325 | if (equationResponse->equationName != NULL((void*)0)) EG_free(equationResponse->equationName); |
3326 | |
3327 | if (equationResponse->designVariableNameSet != NULL((void*)0)) { |
3328 | string_freeArray(equationResponse->numDesignVariable, &equationResponse->designVariableNameSet); |
3329 | } |
3330 | |
3331 | if (equationResponse->constantLabelSet != NULL((void*)0)) { |
3332 | string_freeArray(equationResponse->numConstant, &equationResponse->constantLabelSet); |
3333 | } |
3334 | |
3335 | if (equationResponse->responseNameSet != NULL((void*)0)) { |
3336 | string_freeArray(equationResponse->numResponse, &equationResponse->responseNameSet); |
3337 | } |
3338 | |
3339 | if (equationResponse->gridIDSet != NULL((void*)0)) EG_free(equationResponse->gridIDSet); |
3340 | if (equationResponse->dofNumberSet != NULL((void*)0)) EG_free(equationResponse->dofNumberSet); |
3341 | |
3342 | if (equationResponse->equationResponseNameSet != NULL((void*)0)) { |
3343 | string_freeArray(equationResponse->numEquationResponse, &equationResponse->equationResponseNameSet); |
3344 | } |
3345 | |
3346 | return initiate_feaDesignEquationResponseStruct(equationResponse); |
3347 | } |
3348 | |
3349 | int initiate_feaDesignTableStruct(feaDesignTableStruct *table) { |
3350 | |
3351 | if (table == NULL((void*)0)) return CAPS_NULLVALUE-307; |
3352 | |
3353 | table->numConstant = 0; |
3354 | table->constantLabel = NULL((void*)0); |
3355 | table->constantValue = NULL((void*)0); |
3356 | |
3357 | return CAPS_SUCCESS0; |
3358 | } |
3359 | |
3360 | int destroy_feaDesignTableStruct(feaDesignTableStruct *table) { |
3361 | |
3362 | if (table == NULL((void*)0)) return CAPS_NULLVALUE-307; |
3363 | |
3364 | if (table->constantLabel != NULL((void*)0)) string_freeArray(table->numConstant, &table->constantLabel); |
3365 | if (table->constantValue != NULL((void*)0)) EG_free(table->constantValue); |
3366 | |
3367 | return initiate_feaDesignTableStruct(table); |
3368 | } |
3369 | |
3370 | |
3371 | int initiate_feaDesignOptParamStruct(feaDesignOptParamStruct *table) { |
3372 | |
3373 | if (table == NULL((void*)0)) return CAPS_NULLVALUE-307; |
3374 | |
3375 | table->numParam = 0; |
3376 | table->paramLabel = NULL((void*)0); |
3377 | table->paramValue = NULL((void*)0); |
3378 | table->paramType = NULL((void*)0); |
3379 | |
3380 | return CAPS_SUCCESS0; |
3381 | } |
3382 | |
3383 | int destroy_feaDesignOptParamStruct(feaDesignOptParamStruct *table) { |
3384 | |
3385 | int i; |
3386 | |
3387 | if (table == NULL((void*)0)) return CAPS_NULLVALUE-307; |
3388 | |
3389 | if (table->paramLabel != NULL((void*)0)) string_freeArray(table->numParam, &table->paramLabel); |
3390 | |
3391 | if (table->paramValue != NULL((void*)0)) { |
3392 | for (i = 0; i < table->numParam; i++) { |
3393 | if (table->paramValue[i] != NULL((void*)0)) { |
3394 | EG_free(table->paramValue[i]); |
3395 | } |
3396 | } |
3397 | EG_free(table->paramValue); |
3398 | } |
3399 | |
3400 | if (table->paramType != NULL((void*)0)) EG_free(table->paramType); |
3401 | |
3402 | return initiate_feaDesignOptParamStruct(table); |
3403 | } |
3404 | |
3405 | int initiate_feaDesignVariableRelationStruct(feaDesignVariableRelationStruct *relation) { |
3406 | |
3407 | if (relation == NULL((void*)0)) return CAPS_NULLVALUE-307; |
3408 | |
3409 | relation->name = NULL((void*)0); |
3410 | |
3411 | relation->componentType = 0; |
3412 | |
3413 | relation->relationID = 0; |
3414 | |
3415 | relation->numDesignVariable = 0; |
3416 | relation->designVariableNameSet = NULL((void*)0); |
3417 | relation->designVariableSet = NULL((void*)0); |
3418 | |
3419 | relation->fieldPosition = 0; |
3420 | relation->fieldName = NULL((void*)0); |
3421 | |
3422 | relation->constantRelationCoeff = 0.0; |
3423 | relation->linearRelationCoeff = NULL((void*)0); |
3424 | |
3425 | relation->numMaterialID = 0; // Number of materials to apply the design variable to |
3426 | relation->materialSetID = NULL((void*)0); // List of materials IDs |
3427 | relation->materialSetType = NULL((void*)0); // List of materials types corresponding to the materialSetID |
3428 | |
3429 | relation->numPropertyID = 0; // Number of property ID to apply the design variable to |
3430 | relation->propertySetID = NULL((void*)0); // List of property IDs |
3431 | relation->propertySetType = NULL((void*)0); // List of property types corresponding to the propertySetID |
3432 | |
3433 | relation->numElementID = 0; // Number of element ID to apply the design variable to |
3434 | relation->elementSetID = NULL((void*)0); // List of element IDs |
3435 | relation->elementSetType = NULL((void*)0); // List of element types corresponding to the elementSetID |
3436 | relation->elementSetSubType = NULL((void*)0); // List of element subtypes correspoding to the elementSetID |
3437 | |
3438 | return CAPS_SUCCESS0; |
3439 | } |
3440 | |
3441 | int destroy_feaDesignVariableRelationStruct(feaDesignVariableRelationStruct *relation) { |
3442 | |
3443 | if (relation == NULL((void*)0)) return CAPS_NULLVALUE-307; |
3444 | |
3445 | if (relation->designVariableNameSet != NULL((void*)0)) string_freeArray(relation->numDesignVariable, &relation->designVariableNameSet); |
3446 | if (relation->name != NULL((void*)0)) EG_free(relation->name); |
3447 | if (relation->designVariableSet != NULL((void*)0)) EG_free(relation->designVariableSet); |
3448 | |
3449 | if (relation->fieldName != NULL((void*)0)) EG_free(relation->fieldName); |
3450 | |
3451 | if (relation->linearRelationCoeff != NULL((void*)0)) EG_free(relation->linearRelationCoeff); |
3452 | |
3453 | relation->numMaterialID = 0; // Number of materials to apply the design variable to |
3454 | if (relation->materialSetID != NULL((void*)0)) EG_free(relation->materialSetID); |
3455 | relation->materialSetID = NULL((void*)0); // List of materials IDs |
3456 | |
3457 | if (relation->materialSetType != NULL((void*)0)) EG_free(relation->materialSetType); |
3458 | relation->materialSetType = NULL((void*)0); // List of materials types corresponding to the materialSetID |
3459 | |
3460 | relation->numPropertyID = 0; // Number of property ID to apply the design variable to |
3461 | if (relation->propertySetID != NULL((void*)0)) EG_free(relation->propertySetID); |
3462 | relation->propertySetID = NULL((void*)0); // List of property IDs |
3463 | |
3464 | if (relation->propertySetType != NULL((void*)0)) EG_free(relation->propertySetType); |
3465 | relation->propertySetType = NULL((void*)0); // List of property types corresponding to the propertySetID |
3466 | |
3467 | relation->numElementID = 0; // Number of element ID to apply the design variable to |
3468 | if (relation->elementSetID != NULL((void*)0)) EG_free(relation->elementSetID); |
3469 | relation->elementSetID = NULL((void*)0); // List of element IDs |
3470 | |
3471 | if (relation->elementSetType != NULL((void*)0)) EG_free(relation->elementSetType); |
3472 | relation->elementSetType = NULL((void*)0); // List of element types corresponding to the elementSetID |
3473 | |
3474 | if (relation->elementSetSubType != NULL((void*)0)) EG_free(relation->elementSetSubType); |
3475 | relation->elementSetSubType = NULL((void*)0); // List of element subtypes correspoding to the elementSetID |
3476 | |
3477 | return initiate_feaDesignVariableRelationStruct(relation); |
3478 | } |
3479 | |
3480 | // Get the material properties from a capsTuple |
3481 | int fea_getMaterial(void *aimInfo, |
3482 | int numMaterialTuple, |
3483 | capsTuple materialTuple[], |
3484 | feaUnitsStruct *feaUnits, |
3485 | int *numMaterial, |
3486 | feaMaterialStruct *feaMaterial[]) { |
3487 | |
3488 | /*! \page feaMaterial FEA Material |
3489 | * Structure for the material tuple = ("Material Name", "Value"). |
3490 | * "Material Name" defines the reference name for the material being specified. |
3491 | * The "Value" can either be a JSON String dictionary (see Section \ref jsonStringMaterial) or a single string keyword |
3492 | * (see Section \ref keyStringMaterial). |
3493 | */ |
3494 | |
3495 | int status; //Function return |
3496 | |
3497 | int i; // Indexing |
3498 | |
3499 | char *keyValue = NULL((void*)0); |
3500 | char *keyWord = NULL((void*)0); |
3501 | |
3502 | // Destroy our material structures coming in if aren't 0 and NULL already |
3503 | if (*feaMaterial != NULL((void*)0)) { |
3504 | for (i = 0; i < *numMaterial; i++) { |
3505 | status = destroy_feaMaterialStruct(&(*feaMaterial)[i]); |
3506 | if (status != CAPS_SUCCESS0) return status; |
3507 | } |
3508 | } |
3509 | if (*feaMaterial != NULL((void*)0)) EG_free(*feaMaterial); |
3510 | *feaMaterial = NULL((void*)0); |
3511 | *numMaterial = 0; |
3512 | |
3513 | printf("\nGetting FEA materials.......\n"); |
3514 | |
3515 | *numMaterial = numMaterialTuple; |
3516 | printf("\tNumber of materials - %d\n", *numMaterial); |
3517 | |
3518 | if (*numMaterial > 0) { |
3519 | *feaMaterial = (feaMaterialStruct *) EG_alloc(*numMaterial * sizeof(feaMaterialStruct)); |
3520 | if (*feaMaterial == NULL((void*)0)) return EGADS_MALLOC-4; |
3521 | |
3522 | } else { |
3523 | printf("\tNumber of material values in input tuple is 0\n"); |
3524 | return CAPS_NOTFOUND-303; |
3525 | } |
3526 | |
3527 | for (i = 0; i < *numMaterial; i++) { |
3528 | status = initiate_feaMaterialStruct(&(*feaMaterial)[i]); |
3529 | if (status != CAPS_SUCCESS0) return status; |
3530 | } |
3531 | |
3532 | for (i = 0; i < *numMaterial; i++) { |
3533 | |
3534 | printf("\tMaterial name - %s\n", materialTuple[i].name); |
3535 | |
3536 | (*feaMaterial)[i].name = (char *) EG_alloc(((strlen(materialTuple[i].name)) + 1)*sizeof(char)); |
3537 | if ((*feaMaterial)[i].name == NULL((void*)0)) return EGADS_MALLOC-4; |
3538 | |
3539 | memcpy((*feaMaterial)[i].name, materialTuple[i].name, strlen(materialTuple[i].name)*sizeof(char)); |
3540 | (*feaMaterial)[i].name[strlen(materialTuple[i].name)] = '\0'; |
3541 | |
3542 | (*feaMaterial)[i].materialID = i + 1; |
3543 | |
3544 | // Do we have a json string? |
3545 | if (strncmp(materialTuple[i].value, "{", 1) == 0) { |
3546 | //printf("JSON String - %s\n", materialTuple[i].value); |
3547 | |
3548 | |
3549 | /*! \page feaMaterial |
3550 | * \section jsonStringMaterial JSON String Dictionary |
3551 | * |
3552 | * If "Value" is JSON string dictionary |
3553 | * \if (MYSTRAN || NASTRAN || ASTROS || HSM || ABAQUS || MASSTRAN) |
3554 | * (e.g. "Value" = {"density": 7850, "youngModulus": 120000.0, "poissonRatio": 0.5, "materialType": "isotropic"}) |
3555 | * \endif |
3556 | * the following keywords ( = default values) may be used: |
3557 | * |
3558 | * <ul> |
3559 | * <li> <B>materialType = "Isotropic"</B> </li> <br> |
3560 | * \if (MYSTRAN || NASTRAN || ASTROS || HSM || ABAQUS) |
3561 | * Material property type. Options: Isotropic, Anisothotropic, Orthotropic, or Anisotropic. |
3562 | * \elseif MASSTRAN |
3563 | * Material property type. Options: Isotropic. |
3564 | * \endif |
3565 | * </ul> |
3566 | */ |
3567 | |
3568 | // Get material Type |
3569 | keyWord = "materialType"; |
3570 | status = search_jsonDictionary( materialTuple[i].value, keyWord, &keyValue); |
3571 | if (status == CAPS_SUCCESS0) { |
3572 | |
3573 | //{UnknownMaterial, Isotropic, Anisothotropic, Orthotropic, Anisotropic} |
3574 | if (strcasecmp(keyValue, "\"Isotropic\"") == 0) (*feaMaterial)[i].materialType = Isotropic; |
3575 | else if (strcasecmp(keyValue, "\"Anisothotropic\"") == 0) (*feaMaterial)[i].materialType = Anisothotropic; |
3576 | else if (strcasecmp(keyValue, "\"Orthotropic\"") == 0) (*feaMaterial)[i].materialType = Orthotropic; |
3577 | else if (strcasecmp(keyValue, "\"Anisotropic\"") == 0) (*feaMaterial)[i].materialType = Anisotropic; |
3578 | else { |
3579 | |
3580 | printf("\tUnrecognized \"%s\" specified (%s) for Material tuple %s, defaulting to \"Isotropic\"\n", keyWord, |
3581 | keyValue, |
3582 | materialTuple[i].name); |
3583 | (*feaMaterial)[i].materialType = Isotropic; |
3584 | } |
3585 | |
3586 | } else { |
3587 | |
3588 | printf("\tNo \"%s\" specified for Material tuple %s, defaulting to \"Isotropic\"\n", keyWord, |
3589 | materialTuple[i].name); |
3590 | (*feaMaterial)[i].materialType = Isotropic; |
3591 | } |
3592 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
3593 | |
3594 | //Fill up material properties |
3595 | |
3596 | /*! \page feaMaterial |
3597 | * |
3598 | * \if (MYSTRAN || NASTRAN || HSM || ASTROS || ABAQUS) |
3599 | * <ul> |
3600 | * <li> <B>youngModulus = 0.0</B> </li> <br> |
3601 | * Also known as the elastic modulus, defines the relationship between stress and strain. |
3602 | * Default if `shearModulus' and `poissonRatio' != 0, youngModulus = 2*(1+poissonRatio)*shearModulus |
3603 | * </ul> |
3604 | * \endif |
3605 | * |
3606 | */ |
3607 | keyWord = "youngModulus"; |
3608 | status = search_jsonDictionary( materialTuple[i].value, keyWord, &keyValue); |
3609 | if (status == CAPS_SUCCESS0) { |
3610 | if ( feaUnits->pressure != NULL((void*)0) ) { |
3611 | status = string_toDoubleUnits(aimInfo, keyValue, feaUnits->pressure, &(*feaMaterial)[i].youngModulus); |
3612 | } else { |
3613 | status = string_toDouble(keyValue, &(*feaMaterial)[i].youngModulus); |
3614 | } |
3615 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 3615 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
3616 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
3617 | } |
3618 | |
3619 | /*! \page feaMaterial |
3620 | * |
3621 | * \if (MYSTRAN || NASTRAN || HSM || ASTROS || ABAQUS) |
3622 | * <ul> |
3623 | * <li> <B>shearModulus = 0.0</B> </li> <br> |
3624 | * Also known as the modulus of rigidity, is defined as the ratio of shear stress to the shear strain. |
3625 | * Default if `youngModulus' and `poissonRatio' != 0, shearModulus = youngModulus/(2*(1+poissonRatio)) |
3626 | * </ul> |
3627 | * \endif |
3628 | */ |
3629 | keyWord = "shearModulus"; |
3630 | status = search_jsonDictionary( materialTuple[i].value, keyWord, &keyValue); |
3631 | if (status == CAPS_SUCCESS0) { |
3632 | |
3633 | status = string_toDouble(keyValue, &(*feaMaterial)[i].shearModulus); |
3634 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 3634 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
3635 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
3636 | } |
3637 | |
3638 | /*! \page feaMaterial |
3639 | * |
3640 | * |
3641 | * \if (MYSTRAN || NASTRAN || HSM || ASTROS || ABAQUS) |
3642 | * <ul> |
3643 | * <li> <B>poissonRatio = 0.0</B> </li> <br> |
3644 | * The fraction of expansion divided by the fraction of compression. |
3645 | * Default if `youngModulus' and `shearModulus' != 0, poissonRatio = (2*youngModulus/shearModulus) - 1 |
3646 | * </ul> |
3647 | * \endif |
3648 | */ |
3649 | keyWord = "poissonRatio"; |
3650 | status = search_jsonDictionary( materialTuple[i].value, keyWord, &keyValue); |
3651 | if (status == CAPS_SUCCESS0) { |
3652 | |
3653 | status = string_toDouble(keyValue, &(*feaMaterial)[i].poissonRatio); |
3654 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 3654 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
3655 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
3656 | } |
3657 | |
3658 | // Check Young's modulus, shear modulus, and Poisson's ratio |
3659 | if ( ((*feaMaterial)[i].youngModulus == 0 && (*feaMaterial)[i].poissonRatio == 0) || |
3660 | ((*feaMaterial)[i].shearModulus == 0 && (*feaMaterial)[i].poissonRatio == 0) || |
3661 | ((*feaMaterial)[i].youngModulus == 0 && (*feaMaterial)[i].shearModulus == 0) ) { |
3662 | // Do nothing |
3663 | |
3664 | } else if ((*feaMaterial)[i].youngModulus == 0) { |
3665 | (*feaMaterial)[i].youngModulus = 2*(1+(*feaMaterial)[i].poissonRatio)*(*feaMaterial)[i].shearModulus; |
3666 | } else if ((*feaMaterial)[i].shearModulus == 0) { |
3667 | (*feaMaterial)[i].shearModulus = (*feaMaterial)[i].youngModulus/(2*(1+(*feaMaterial)[i].poissonRatio)); |
3668 | } else if ((*feaMaterial)[i].poissonRatio == 0) { |
3669 | (*feaMaterial)[i].poissonRatio = (*feaMaterial)[i].youngModulus/(2*(*feaMaterial)[i].shearModulus) -1; |
3670 | } |
3671 | |
3672 | /*! \page feaMaterial |
3673 | * |
3674 | * |
3675 | * \if (MYSTRAN || NASTRAN || HSM || ASTROS || ABAQUS || MASSTRAN) |
3676 | * <ul> |
3677 | * <li> <B>density = 0.0</B> </li> <br> |
3678 | * Density of the material. |
3679 | * </ul> |
3680 | * \endif |
3681 | */ |
3682 | keyWord = "density"; |
3683 | status = search_jsonDictionary( materialTuple[i].value, keyWord, &keyValue); |
3684 | if (status == CAPS_SUCCESS0) { |
3685 | if ( feaUnits->densityVol != NULL((void*)0) ) { |
3686 | status = string_toDoubleUnits(aimInfo, keyValue, feaUnits->densityVol, &(*feaMaterial)[i].density); |
3687 | } else { |
3688 | status = string_toDouble(keyValue, &(*feaMaterial)[i].density); |
3689 | } |
3690 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 3690 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
3691 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
3692 | } |
3693 | |
3694 | /*! \page feaMaterial |
3695 | * |
3696 | * \if (MYSTRAN || NASTRAN || ASTROS) |
3697 | * <ul> |
3698 | * <li> <B>thermalExpCoeff = 0.0</B> </li> <br> |
3699 | * Thermal expansion coefficient of the material. |
3700 | * </ul> |
3701 | * \endif |
3702 | */ |
3703 | keyWord = "thermalExpCoeff"; |
3704 | status = search_jsonDictionary( materialTuple[i].value, keyWord, &keyValue); |
3705 | if (status == CAPS_SUCCESS0) { |
3706 | |
3707 | status = string_toDouble(keyValue, &(*feaMaterial)[i].thermalExpCoeff); |
3708 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 3708 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
3709 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
3710 | } |
3711 | |
3712 | /*! \page feaMaterial |
3713 | * |
3714 | * \if (MYSTRAN || NASTRAN || ASTROS) |
3715 | * <ul> |
3716 | * <li> <B>thermalExpCoeffLateral = 0.0</B> </li> <br> |
3717 | * Thermal expansion coefficient of the material. |
3718 | * </ul> |
3719 | * \endif |
3720 | */ |
3721 | keyWord = "thermalExpCoeffLateral"; |
3722 | status = search_jsonDictionary( materialTuple[i].value, keyWord, &keyValue); |
3723 | if (status == CAPS_SUCCESS0) { |
3724 | |
3725 | status = string_toDouble(keyValue, &(*feaMaterial)[i].thermalExpCoeffLateral); |
3726 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 3726 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
3727 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
3728 | } |
3729 | |
3730 | /*! \page feaMaterial |
3731 | * |
3732 | * |
3733 | * \if (MYSTRAN || NASTRAN || ASTROS) |
3734 | * <ul> |
3735 | * <li> <B>temperatureRef = 0.0</B> </li> <br> |
3736 | * Reference temperature for material properties. |
3737 | * </ul> |
3738 | * \endif |
3739 | */ |
3740 | keyWord = "temperatureRef"; |
3741 | status = search_jsonDictionary( materialTuple[i].value, keyWord, &keyValue); |
3742 | if (status == CAPS_SUCCESS0) { |
3743 | |
3744 | status = string_toDouble(keyValue, &(*feaMaterial)[i].temperatureRef); |
3745 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 3745 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
3746 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
3747 | } |
3748 | |
3749 | /*! \page feaMaterial |
3750 | * |
3751 | * \if (MYSTRAN || NASTRAN || ASTROS) |
3752 | * <ul> |
3753 | * <li> <B>dampingCoeff = 0.0</B> </li> <br> |
3754 | * Damping coefficient for the material. |
3755 | * </ul> |
3756 | * \endif |
3757 | */ |
3758 | keyWord = "dampingCoeff"; |
3759 | status = search_jsonDictionary( materialTuple[i].value, keyWord, &keyValue); |
3760 | if (status == CAPS_SUCCESS0) { |
3761 | |
3762 | status = string_toDouble(keyValue, &(*feaMaterial)[i].dampingCoeff); |
3763 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 3763 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
3764 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
3765 | } |
3766 | |
3767 | /*! \page feaMaterial |
3768 | * |
3769 | * |
3770 | * \if NASTRAN |
3771 | * <ul> |
3772 | * <li> <B>yieldAllow = 0.0</B> </li> <br> |
3773 | * Yield strength/allowable for the material. |
3774 | * </ul> |
3775 | * \endif |
3776 | */ |
3777 | keyWord = "yieldAllow"; |
3778 | status = search_jsonDictionary( materialTuple[i].value, keyWord, &keyValue); |
3779 | if (status == CAPS_SUCCESS0) { |
3780 | |
3781 | status = string_toDouble(keyValue, &(*feaMaterial)[i].yieldAllow); |
3782 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 3782 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
3783 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
3784 | } |
3785 | |
3786 | /*! \page feaMaterial |
3787 | * |
3788 | * |
3789 | * \if NASTRAN |
3790 | * <ul> |
3791 | * <li> <B>tensionAllow = 0.0</B> </li> <br> |
3792 | * Tension allowable for the material. |
3793 | * </ul> |
3794 | * \endif |
3795 | */ |
3796 | keyWord = "tensionAllow"; |
3797 | status = search_jsonDictionary( materialTuple[i].value, keyWord, &keyValue); |
3798 | if (status == CAPS_SUCCESS0) { |
3799 | |
3800 | status = string_toDouble(keyValue, &(*feaMaterial)[i].tensionAllow); |
3801 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 3801 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
3802 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
3803 | } |
3804 | |
3805 | /*! \page feaMaterial |
3806 | * |
3807 | * |
3808 | * \if NASTRAN |
3809 | * <ul> |
3810 | * <li> <B>tensionAllowLateral = 0.0</B> </li> <br> |
3811 | * Lateral tension allowable for the material. |
3812 | * </ul> |
3813 | * \endif |
3814 | */ |
3815 | keyWord = "tensionAllowLateral"; |
3816 | status = search_jsonDictionary( materialTuple[i].value, keyWord, &keyValue); |
3817 | if (status == CAPS_SUCCESS0) { |
3818 | |
3819 | status = string_toDouble(keyValue, &(*feaMaterial)[i].tensionAllowLateral); |
3820 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 3820 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
3821 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
3822 | } |
3823 | |
3824 | /*! \page feaMaterial |
3825 | * |
3826 | * \if NASTRAN |
3827 | * <ul> |
3828 | * <li> <B>compressAllow = 0.0</B> </li> <br> |
3829 | * Compression allowable for the material. |
3830 | * </ul> |
3831 | * \endif |
3832 | */ |
3833 | keyWord = "compressAllow"; |
3834 | status = search_jsonDictionary( materialTuple[i].value, keyWord, &keyValue); |
3835 | if (status == CAPS_SUCCESS0) { |
3836 | |
3837 | status = string_toDouble(keyValue, &(*feaMaterial)[i].compressAllow); |
3838 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 3838 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
3839 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
3840 | } |
3841 | |
3842 | /*! \page feaMaterial |
3843 | * |
3844 | * \if NASTRAN |
3845 | * <ul> |
3846 | * <li> <B>compressAllowLateral = 0.0</B> </li> <br> |
3847 | * Lateral compression allowable for the material. |
3848 | * </ul> |
3849 | * \endif |
3850 | */ |
3851 | keyWord = "compressAllowLateral"; |
3852 | status = search_jsonDictionary( materialTuple[i].value, keyWord, &keyValue); |
3853 | if (status == CAPS_SUCCESS0) { |
3854 | |
3855 | status = string_toDouble(keyValue, &(*feaMaterial)[i].compressAllowLateral); |
3856 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 3856 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
3857 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
3858 | } |
3859 | |
3860 | /*! \page feaMaterial |
3861 | * |
3862 | * \if NASTRAN |
3863 | * <ul> |
3864 | * <li> <B>shearAllow = 0.0</B> </li> <br> |
3865 | * Shear allowable for the material. |
3866 | * </ul> |
3867 | * \endif |
3868 | */ |
3869 | keyWord = "shearAllow"; |
3870 | status = search_jsonDictionary( materialTuple[i].value, keyWord, &keyValue); |
3871 | if (status == CAPS_SUCCESS0) { |
3872 | |
3873 | status = string_toDouble(keyValue, &(*feaMaterial)[i].shearAllow); |
3874 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 3874 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
3875 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
3876 | } |
3877 | |
3878 | /*! \page feaMaterial |
3879 | * |
3880 | * \if (NASTRAN) |
3881 | * <ul> |
3882 | * <li> <B>allowType = 0 </B> </li> <br> |
3883 | * This flag defines if the above allowables <c>compressAllow</c> etc. are defined in terms of stress (0) or strain (1). The default is stress (0). |
3884 | * </ul> |
3885 | * \endif |
3886 | */ |
3887 | keyWord = "allowType"; |
3888 | status = search_jsonDictionary( materialTuple[i].value, keyWord, &keyValue); |
3889 | if (status == CAPS_SUCCESS0) { |
3890 | status = string_toInteger(keyValue, &(*feaMaterial)[i].allowType); |
3891 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 3891 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
3892 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
3893 | } |
3894 | |
3895 | /*! \page feaMaterial |
3896 | * |
3897 | * \if (MYSTRAN || NASTRAN || ABAQUS) |
3898 | * <ul> |
3899 | * <li> <B>youngModulusLateral = 0.0</B> </li> <br> |
3900 | * Elastic modulus in lateral direction for an orthotropic material |
3901 | * </ul> |
3902 | * \endif |
3903 | */ |
3904 | keyWord = "youngModulusLateral"; |
3905 | status = search_jsonDictionary( materialTuple[i].value, keyWord, &keyValue); |
3906 | if (status == CAPS_SUCCESS0) { |
3907 | |
3908 | status = string_toDouble(keyValue, &(*feaMaterial)[i].youngModulusLateral); |
3909 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 3909 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
3910 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
3911 | } |
3912 | |
3913 | /*! \page feaMaterial |
3914 | * |
3915 | * \if (MYSTRAN || NASTRAN || ABAQUS) |
3916 | * <ul> |
3917 | * <li> <B>shearModulusTrans1Z = 0.0</B> </li> <br> |
3918 | * Transverse shear modulus in the 1-Z plane for an orthotropic material |
3919 | * </ul> |
3920 | * \endif |
3921 | */ |
3922 | keyWord = "shearModulusTrans1Z"; |
3923 | status = search_jsonDictionary( materialTuple[i].value, keyWord, &keyValue); |
3924 | if (status == CAPS_SUCCESS0) { |
3925 | |
3926 | status = string_toDouble(keyValue, &(*feaMaterial)[i].shearModulusTrans1Z); |
3927 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 3927 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
3928 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
3929 | } |
3930 | |
3931 | /*! \page feaMaterial |
3932 | * |
3933 | * \if (MYSTRAN || NASTRAN || ABAQUS) |
3934 | * <ul> |
3935 | * <li> <B>shearModulusTrans2Z = 0.0</B> </li> <br> |
3936 | * Transverse shear modulus in the 2-Z plane for an orthotropic material |
3937 | * </ul> |
3938 | * \endif |
3939 | */ |
3940 | keyWord = "shearModulusTrans2Z"; |
3941 | status = search_jsonDictionary( materialTuple[i].value, keyWord, &keyValue); |
3942 | if (status == CAPS_SUCCESS0) { |
3943 | |
3944 | status = string_toDouble(keyValue, &(*feaMaterial)[i].shearModulusTrans2Z); |
3945 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 3945 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
3946 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
3947 | } |
3948 | |
3949 | /*! \page feaMaterial |
3950 | * |
3951 | * \if (TACS || NASTRAN || ABAQUS) |
3952 | * <ul> |
3953 | * <li> <B>kappa = 0.0</B> </li> <br> |
3954 | * Thermal conductivity for an isotropic solid |
3955 | * </ul> |
3956 | * \endif |
3957 | */ |
3958 | keyWord = "kappa"; |
3959 | status = search_jsonDictionary( materialTuple[i].value, keyWord, &keyValue); |
3960 | if (status == CAPS_SUCCESS0) { |
3961 | |
3962 | status = string_toDouble(keyValue, &(*feaMaterial)[i].kappa); |
3963 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 3963 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
3964 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
3965 | } |
3966 | |
3967 | /*! \page feaMaterial |
3968 | * |
3969 | * \if (TACS || NASTRAN || ABAQUS) |
3970 | * <ul> |
3971 | * <li> <B>specificHeat = 0.0</B> </li> <br> |
3972 | * Specific heat constant pressure (per unit mass) for an isotropic solid |
3973 | * </ul> |
3974 | * \endif |
3975 | */ |
3976 | keyWord = "specificHeat"; |
3977 | status = search_jsonDictionary( materialTuple[i].value, keyWord, &keyValue); |
3978 | if (status == CAPS_SUCCESS0) { |
3979 | |
3980 | status = string_toDouble(keyValue, &(*feaMaterial)[i].specificHeat); |
3981 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 3981 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
3982 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
3983 | } |
3984 | |
3985 | } else { |
3986 | |
3987 | /*! \page feaMaterial |
3988 | * \section keyStringMaterial Single Value String |
3989 | * |
3990 | * If "Value" is a string, the string value may correspond to an entry in a predefined material lookup |
3991 | * table. NOT YET IMPLEMENTED!!!! |
3992 | * |
3993 | */ |
3994 | // CALL material look up |
3995 | AIM_ERROR(aimInfo, "Material tuple value ('%s') is expected to be a JSON string", materialTuple[i].value){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 3995, __func__ , "Material tuple value ('%s') is expected to be a JSON string" , materialTuple[i].value); }; |
3996 | status = CAPS_BADVALUE-311; |
3997 | goto cleanup; |
3998 | } |
3999 | } |
4000 | |
4001 | printf("\tDone getting FEA materials\n"); |
4002 | status = CAPS_SUCCESS0; |
4003 | |
4004 | cleanup: |
4005 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4006 | |
4007 | return status; |
4008 | } |
4009 | |
4010 | // Get the property properties from a capsTuple |
4011 | int fea_getProperty(void *aimInfo, |
4012 | int numPropertyTuple, |
4013 | capsTuple propertyTuple[], |
4014 | mapAttrToIndexStruct *attrMap, |
4015 | feaUnitsStruct *feaUnits, |
4016 | feaProblemStruct *feaProblem) { |
4017 | |
4018 | /*! \page feaProperty FEA Property |
4019 | * Structure for the property tuple = ("Property Name", "Value"). |
4020 | * "Property Name" defines the reference <c>capsGroup</c> for the property being specified. |
4021 | * The "Value" can either be a JSON String dictionary (see Section \ref jsonStringProperty) or a single string keyword |
4022 | * (see Section \ref keyStringProperty). |
4023 | */ |
4024 | |
4025 | int status; //Function return |
4026 | |
4027 | int i, j, matIndex; // Indexing |
4028 | int found; // Bool test function |
4029 | |
4030 | int pidIndex; // Property identification index found in attribute map |
4031 | |
4032 | int tempInteger; |
4033 | |
4034 | char *keyValue = NULL((void*)0); |
4035 | char *keyWord = NULL((void*)0); |
4036 | char *tempString = NULL((void*)0); |
4037 | char **tempStringArray = NULL((void*)0); |
4038 | |
4039 | // double tempDouble; |
4040 | |
4041 | // Destroy our property structures coming in if aren't 0 and NULL already |
4042 | if (feaProblem->feaProperty != NULL((void*)0)) { |
4043 | for (i = 0; i < feaProblem->numProperty; i++) { |
4044 | status = destroy_feaPropertyStruct(&feaProblem->feaProperty[i]); |
4045 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4045 , __func__, 0); goto cleanup; }; |
4046 | } |
4047 | } |
4048 | AIM_FREE(feaProblem->feaProperty){ EG_free(feaProblem->feaProperty); feaProblem->feaProperty = ((void*)0); }; |
4049 | feaProblem->numProperty = 0; |
4050 | |
4051 | printf("\nGetting FEA properties.......\n"); |
4052 | |
4053 | feaProblem->numProperty = numPropertyTuple; |
4054 | printf("\tNumber of properties - %d\n", feaProblem->numProperty); |
4055 | |
4056 | if (feaProblem->numProperty > 0) { |
4057 | |
4058 | feaProblem->feaProperty = (feaPropertyStruct *) EG_alloc(feaProblem->numProperty * sizeof(feaPropertyStruct)); |
4059 | if (feaProblem->feaProperty == NULL((void*)0)) return EGADS_MALLOC-4; |
4060 | |
4061 | } else { |
4062 | AIM_ERROR(aimInfo, "Number of property values in input tuple is 0\n"){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 4062, __func__ , "Number of property values in input tuple is 0\n"); }; |
4063 | status = CAPS_NOTFOUND-303; |
4064 | goto cleanup; |
4065 | } |
4066 | |
4067 | for (i = 0; i < feaProblem->numProperty; i++) { |
4068 | status = initiate_feaPropertyStruct(&feaProblem->feaProperty[i]); |
4069 | AIM_STATUS(aimInfo, status, "Unable to initiate feaProperty structure (number = %d)", i)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4069 , __func__, 2, "Unable to initiate feaProperty structure (number = %d)" , i); goto cleanup; }; |
4070 | } |
4071 | |
4072 | for (i = 0; i < feaProblem->numProperty; i++) { |
4073 | |
4074 | printf("\tProperty name - %s\n", propertyTuple[i].name); |
4075 | |
4076 | // Set property name from tuple name |
4077 | AIM_STRDUP(feaProblem->feaProperty[i].name, propertyTuple[i].name, aimInfo, status){ if (feaProblem->feaProperty[i].name != ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 4077, __func__ , 1, "AIM_STRDUP: %s != NULL!", "feaProblem->feaProperty[i].name" ); goto cleanup; } feaProblem->feaProperty[i].name = EG_strdup (propertyTuple[i].name); if (feaProblem->feaProperty[i].name == ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c" , 4077, __func__, 2, "AIM_STRDUP: %s %s", "feaProblem->feaProperty[i].name" , propertyTuple[i].name); goto cleanup; } }; |
4078 | |
4079 | // Get to property ID number from the attribute map |
4080 | status = get_mapAttrToIndexIndex(attrMap, feaProblem->feaProperty[i].name, &pidIndex); |
4081 | if (status != CAPS_SUCCESS0) { |
4082 | AIM_ERROR(aimInfo, "Tuple name '%s' not found in attribute map of PIDS!!!!\n", feaProblem->feaProperty[i].name){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 4082, __func__ , "Tuple name '%s' not found in attribute map of PIDS!!!!\n", feaProblem->feaProperty[i].name); }; |
4083 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4084 | goto cleanup; |
4085 | } else { |
4086 | feaProblem->feaProperty[i].propertyID = pidIndex; |
4087 | } |
4088 | |
4089 | // Do we have a json string? |
4090 | if (strncmp(propertyTuple[i].value, "{", 1) == 0) { |
4091 | //printf("JSON String - %s\n",propertyTuple[i].value); |
4092 | |
4093 | /*! \page feaProperty |
4094 | * \section jsonStringProperty JSON String Dictionary |
4095 | * |
4096 | * If "Value" is JSON string dictionary |
4097 | * \if (MYSTRAN || NASTRAN) |
4098 | * (e.g. "Value" = {"shearMembraneRatio": 0.83, "bendingInertiaRatio": 1.0, "membraneThickness": 0.2, "propertyType": "Shell"}) |
4099 | * \endif |
4100 | * the following keywords ( = default values) may be used: |
4101 | * |
4102 | * |
4103 | * \if (MYSTRAN || NASTRAN) |
4104 | * <ul> |
4105 | * <li> <B>propertyType = No Default value</B> </li> <br> |
4106 | * Type of property to apply to a given capsGroup <c>Name</c>. Options: ConcentratedMass, Rod, |
4107 | * Bar, Shear, Shell, Composite, and Solid |
4108 | * </ul> |
4109 | * \elseif (MASSTRAN) |
4110 | * <ul> |
4111 | * <li> <B>propertyType = No Default value</B> </li> <br> |
4112 | * Type of property to apply to a given capsGroup <c>Name</c>. Options: ConcentratedMass, Shell |
4113 | * </ul> |
4114 | * \elseif ABAQUS |
4115 | * |
4116 | * Something else .... |
4117 | * |
4118 | * \elseif ASTROS |
4119 | * <ul> |
4120 | * <li> <B>propertyType = No Default value</B> </li> <br> |
4121 | * Type of property to apply to a give capsGroup <c>Name</c>. Options: ConcentratedMass, Rod, |
4122 | * Bar, Shear, Shell, Membrane, Composite, and Solid |
4123 | * </ul> |
4124 | * \endif |
4125 | * |
4126 | */ |
4127 | |
4128 | // Get property Type |
4129 | keyWord = "propertyType"; |
4130 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4131 | if (status == CAPS_SUCCESS0) { |
4132 | |
4133 | //{UnknownProperty, ConcentratedMass Rod, Bar, Shear, Shell, Composite, Solid} |
4134 | if (strcasecmp(keyValue, "\"ConcentratedMass\"") == 0) feaProblem->feaProperty[i].propertyType = ConcentratedMass; |
4135 | else if (strcasecmp(keyValue, "\"Rod\"") == 0) feaProblem->feaProperty[i].propertyType = Rod; |
4136 | else if (strcasecmp(keyValue, "\"Bar\"") == 0) feaProblem->feaProperty[i].propertyType = Bar; |
4137 | else if (strcasecmp(keyValue, "\"Shear\"") == 0) feaProblem->feaProperty[i].propertyType = Shear; |
4138 | else if (strcasecmp(keyValue, "\"Shell\"") == 0) feaProblem->feaProperty[i].propertyType = Shell; |
4139 | else if (strcasecmp(keyValue, "\"Membrane\"") == 0) feaProblem->feaProperty[i].propertyType = Membrane; |
4140 | else if (strcasecmp(keyValue, "\"Composite\"") == 0) feaProblem->feaProperty[i].propertyType = Composite; |
4141 | else if (strcasecmp(keyValue, "\"Solid\"") == 0) feaProblem->feaProperty[i].propertyType = Solid; |
4142 | else { |
4143 | AIM_ERROR(aimInfo, "Unrecognized \"%s\" specified (%s) for Property tuple %s, current options are "{ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 4146, __func__ , "Unrecognized \"%s\" specified (%s) for Property tuple %s, current options are " "\"Rod, Bar, Shear, Shell, Composite, and Solid\"\n", keyWord , keyValue, propertyTuple[i].name); } |
4144 | "\"Rod, Bar, Shear, Shell, Composite, and Solid\"\n", keyWord,{ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 4146, __func__ , "Unrecognized \"%s\" specified (%s) for Property tuple %s, current options are " "\"Rod, Bar, Shear, Shell, Composite, and Solid\"\n", keyWord , keyValue, propertyTuple[i].name); } |
4145 | keyValue,{ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 4146, __func__ , "Unrecognized \"%s\" specified (%s) for Property tuple %s, current options are " "\"Rod, Bar, Shear, Shell, Composite, and Solid\"\n", keyWord , keyValue, propertyTuple[i].name); } |
4146 | propertyTuple[i].name){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 4146, __func__ , "Unrecognized \"%s\" specified (%s) for Property tuple %s, current options are " "\"Rod, Bar, Shear, Shell, Composite, and Solid\"\n", keyWord , keyValue, propertyTuple[i].name); }; |
4147 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4148 | |
4149 | status = CAPS_NOTFOUND-303; |
4150 | goto cleanup; |
4151 | } |
4152 | |
4153 | } else { |
4154 | AIM_ERROR(aimInfo, "\tNo \"%s\" specified for Property tuple %s, this mandatory! Current options are "{ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 4156, __func__ , "\tNo \"%s\" specified for Property tuple %s, this mandatory! Current options are " "\"ConcentratedMass, Rod, Bar, Shear, Shell, Composite, and Solid\"\n" , keyWord, propertyTuple[i].name); } |
4155 | "\"ConcentratedMass, Rod, Bar, Shear, Shell, Composite, and Solid\"\n", keyWord,{ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 4156, __func__ , "\tNo \"%s\" specified for Property tuple %s, this mandatory! Current options are " "\"ConcentratedMass, Rod, Bar, Shear, Shell, Composite, and Solid\"\n" , keyWord, propertyTuple[i].name); } |
4156 | propertyTuple[i].name){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 4156, __func__ , "\tNo \"%s\" specified for Property tuple %s, this mandatory! Current options are " "\"ConcentratedMass, Rod, Bar, Shear, Shell, Composite, and Solid\"\n" , keyWord, propertyTuple[i].name); }; |
4157 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4158 | |
4159 | status = CAPS_NOTFOUND-303; |
4160 | goto cleanup; |
4161 | } |
4162 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4163 | |
4164 | /*! \page feaProperty |
4165 | * |
4166 | * \if (MYSTRAN || NASTRAN) |
4167 | * <ul> |
4168 | * <li> <B>material = "Material Name" (\ref feaMaterial) </B> </li> <br> |
4169 | * "Material Name" from \ref feaMaterial to use for property. If no material is set the first material |
4170 | * created will be used |
4171 | * </ul> |
4172 | * \elseif ABAQUS |
4173 | * |
4174 | * Something else .... |
4175 | * |
4176 | * \elseif ASTROS |
4177 | * <ul> |
4178 | * <li> <B>material = `Material Name' (\ref feaMaterial) </B> </li> <br> |
4179 | * `Material Name' from \ref feaMaterial to use for property. If no material is set the first material |
4180 | * created will be used |
4181 | * </ul> |
4182 | * \endif |
4183 | */ |
4184 | keyWord = "material"; |
4185 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4186 | if (status == CAPS_SUCCESS0) { |
4187 | |
4188 | found = (int) false0; |
4189 | for (matIndex = 0; matIndex < feaProblem->numMaterial; matIndex++ ) { |
4190 | |
4191 | AIM_FREE(tempString){ EG_free(tempString); tempString = ((void*)0); }; |
4192 | tempString = string_removeQuotation(keyValue); |
4193 | |
4194 | if (strcasecmp(feaProblem->feaMaterial[matIndex].name, tempString) == 0) { |
4195 | feaProblem->feaProperty[i].materialID = feaProblem->feaMaterial[matIndex].materialID; |
4196 | |
4197 | AIM_STRDUP(feaProblem->feaProperty[i].materialName, feaProblem->feaMaterial[matIndex].name, aimInfo, status){ if (feaProblem->feaProperty[i].materialName != ((void*)0 )) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 4197 , __func__, 1, "AIM_STRDUP: %s != NULL!", "feaProblem->feaProperty[i].materialName" ); goto cleanup; } feaProblem->feaProperty[i].materialName = EG_strdup(feaProblem->feaMaterial[matIndex].name); if ( feaProblem->feaProperty[i].materialName == ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 4197, __func__ , 2, "AIM_STRDUP: %s %s", "feaProblem->feaProperty[i].materialName" , feaProblem->feaMaterial[matIndex].name); goto cleanup; } }; |
4198 | feaProblem->feaProperty[i].materialName[strlen(feaProblem->feaMaterial[matIndex].name)] = '\0'; |
4199 | |
4200 | found = (int) true1; |
4201 | break; |
4202 | } |
4203 | } |
4204 | |
4205 | AIM_FREE(tempString){ EG_free(tempString); tempString = ((void*)0); }; |
4206 | |
4207 | if (found == (int) false0) { |
4208 | AIM_ERROR(aimInfo, "Unrecognized \"%s\" specified (%s) for Property tuple %s. No match in Material tuple\n", keyWord,{ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 4210, __func__ , "Unrecognized \"%s\" specified (%s) for Property tuple %s. No match in Material tuple\n" , keyWord, keyValue, propertyTuple[i].name); } |
4209 | keyValue,{ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 4210, __func__ , "Unrecognized \"%s\" specified (%s) for Property tuple %s. No match in Material tuple\n" , keyWord, keyValue, propertyTuple[i].name); } |
4210 | propertyTuple[i].name){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 4210, __func__ , "Unrecognized \"%s\" specified (%s) for Property tuple %s. No match in Material tuple\n" , keyWord, keyValue, propertyTuple[i].name); }; |
4211 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4212 | status = CAPS_NOTFOUND-303; |
4213 | goto cleanup; |
4214 | } |
4215 | |
4216 | } else { |
4217 | |
4218 | if (feaProblem->feaProperty[i].propertyType != ConcentratedMass && |
4219 | feaProblem->feaProperty[i].propertyType != Composite) { |
4220 | printf("\tNo \"%s\" specified for Property tuple %s, defaulting to an index of 1\n", keyWord, |
4221 | propertyTuple[i].name); |
4222 | } |
4223 | |
4224 | feaProblem->feaProperty[i].materialID = 1; |
4225 | if (feaProblem->numMaterial > 0) { |
4226 | AIM_STRDUP(feaProblem->feaProperty[i].materialName, feaProblem->feaMaterial[0].name, aimInfo, status){ if (feaProblem->feaProperty[i].materialName != ((void*)0 )) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 4226 , __func__, 1, "AIM_STRDUP: %s != NULL!", "feaProblem->feaProperty[i].materialName" ); goto cleanup; } feaProblem->feaProperty[i].materialName = EG_strdup(feaProblem->feaMaterial[0].name); if (feaProblem ->feaProperty[i].materialName == ((void*)0)) { status = -4 ; aim_status(aimInfo, status, "feaUtils.c", 4226, __func__, 2 , "AIM_STRDUP: %s %s", "feaProblem->feaProperty[i].materialName" , feaProblem->feaMaterial[0].name); goto cleanup; } }; |
4227 | } |
4228 | } |
4229 | |
4230 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4231 | |
4232 | // Fill up properties /// |
4233 | |
4234 | // Rods |
4235 | /*! \page feaProperty |
4236 | * |
4237 | * \if (MYSTRAN || NASTRAN) |
4238 | * <ul> |
4239 | * <li> <B>crossSecArea = 0.0</B> </li> <br> |
4240 | * Cross sectional area. |
4241 | * </ul> |
4242 | * \elseif ABAQUS |
4243 | * |
4244 | * Something else .... |
4245 | * |
4246 | * \elseif ASTROS |
4247 | * <ul> |
4248 | * <li> <B>crossSecArea = 0.0</B> </li> <br> |
4249 | * Cross sectional area. |
4250 | * </ul> |
4251 | * \endif |
4252 | */ |
4253 | keyWord = "crossSecArea"; |
4254 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4255 | if (status == CAPS_SUCCESS0) { |
4256 | |
4257 | status = string_toDouble(keyValue, &feaProblem->feaProperty[i].crossSecArea); |
4258 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4258 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
4259 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4260 | } |
4261 | |
4262 | /*! \page feaProperty |
4263 | * |
4264 | * \if (MYSTRAN || NASTRAN) |
4265 | * <ul> |
4266 | * <li> <B>torsionalConst = 0.0</B> </li> <br> |
4267 | * Torsional constant. |
4268 | * </ul> |
4269 | * \elseif ABAQUS |
4270 | * |
4271 | * Something else .... |
4272 | * |
4273 | * \elseif ASTROS |
4274 | * <ul> |
4275 | * <li> <B>torsionalConst = 0.0</B> </li> <br> |
4276 | * Torsional constant. |
4277 | * </ul> |
4278 | * \endif |
4279 | */ |
4280 | keyWord = "torsionalConst"; |
4281 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4282 | if (status == CAPS_SUCCESS0) { |
4283 | |
4284 | status = string_toDouble(keyValue, &feaProblem->feaProperty[i].torsionalConst); |
4285 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4285 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
4286 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4287 | } |
4288 | |
4289 | /*! \page feaProperty |
4290 | * |
4291 | * \if (MYSTRAN || NASTRAN) |
4292 | * <ul> |
4293 | * <li> <B>torsionalStressReCoeff = 0.0</B> </li> <br> |
4294 | * Torsional stress recovery coefficient. |
4295 | * </ul> |
4296 | * \elseif ABAQUS |
4297 | * |
4298 | * Something else .... |
4299 | * |
4300 | * \elseif ASTROS |
4301 | * <ul> |
4302 | * <li> <B>torsionalStressReCoeff = 0.0</B> </li> <br> |
4303 | * Torsional stress recovery coefficient. |
4304 | * </ul> |
4305 | * \endif |
4306 | */ |
4307 | keyWord = "torsionalStressReCoeff"; |
4308 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4309 | if (status == CAPS_SUCCESS0) { |
4310 | |
4311 | status = string_toDouble(keyValue, &feaProblem->feaProperty[i].torsionalStressReCoeff); |
4312 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4312 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
4313 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4314 | } |
4315 | |
4316 | /*! \page feaProperty |
4317 | * |
4318 | * \if (HSM) |
4319 | * <ul> |
4320 | * <li> <B>massPerLength = 0.0</B> </li> <br> |
4321 | * Mass per unit length. |
4322 | * </ul> |
4323 | * |
4324 | * \elseif ( MYSTRAN || NASTRAN || ASTROS || ABAQUS) |
4325 | * <ul> |
4326 | * <li> <B>massPerLength = 0.0</B> </li> <br> |
4327 | * Non-structural mass per unit length. |
4328 | * </ul> |
4329 | * |
4330 | * \endif |
4331 | */ |
4332 | keyWord = "massPerLength"; |
4333 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4334 | if (status == CAPS_SUCCESS0) { |
4335 | |
4336 | status = string_toDouble(keyValue, &feaProblem->feaProperty[i].massPerLength); |
4337 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4337 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
4338 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4339 | } |
4340 | |
4341 | // Bar - see rod for additional variables |
4342 | |
4343 | /*! \page feaProperty |
4344 | * |
4345 | * \if (MYSTRAN || NASTRAN) |
4346 | * <ul> |
4347 | * <li> <B>zAxisInertia = 0.0</B> </li> <br> |
4348 | * Section moment of inertia about the element z-axis. |
4349 | * </ul> |
4350 | * \elseif ABAQUS |
4351 | * |
4352 | * Something else .... |
4353 | * |
4354 | * \elseif ASTROS |
4355 | * <ul> |
4356 | * <li> <B>zAxisInertia = 0.0</B> </li> <br> |
4357 | * Section moment of inertia about the element z-axis. |
4358 | * </ul> |
4359 | * \endif |
4360 | */ |
4361 | keyWord = "zAxisInertia"; |
4362 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4363 | if (status == CAPS_SUCCESS0) { |
4364 | |
4365 | status = string_toDouble(keyValue, &feaProblem->feaProperty[i].zAxisInertia); |
4366 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4366 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
4367 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4368 | } |
4369 | |
4370 | /*! \page feaProperty |
4371 | * |
4372 | * \if (MYSTRAN || NASTRAN) |
4373 | * <ul> |
4374 | * <li> <B>yAxisInertia = 0.0</B> </li> <br> |
4375 | * Section moment of inertia about the element y-axis. |
4376 | * </ul> |
4377 | * \elseif ABAQUS |
4378 | * |
4379 | * Something else .... |
4380 | * |
4381 | * \elseif ASTROS |
4382 | * <ul> |
4383 | * <li> <B>yAxisInertia = 0.0</B> </li> <br> |
4384 | * Section moment of inertia about the element y-axis. |
4385 | * </ul> |
4386 | * \endif |
4387 | */ |
4388 | keyWord = "yAxisInertia"; |
4389 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4390 | if (status == CAPS_SUCCESS0) { |
4391 | |
4392 | status = string_toDouble(keyValue, &feaProblem->feaProperty[i].yAxisInertia); |
4393 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4393 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
4394 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4395 | } |
4396 | |
4397 | /*! \page feaProperty |
4398 | * |
4399 | * \if (MYSTRAN || NASTRAN) |
4400 | * <ul> |
4401 | * <li> <B>yCoords[4] = [0.0, 0.0, 0.0, 0.0]</B> </li> <br> |
4402 | * Element y-coordinates, in the bar cross-section, of four points at which to recover stresses |
4403 | * </ul> |
4404 | * \elseif ABAQUS |
4405 | * |
4406 | * Something else .... |
4407 | * |
4408 | * \elseif ASTROS |
4409 | * <ul> |
4410 | * <li> <B>yCoords[4] = [0.0, 0.0, 0.0, 0.0]</B> </li> <br> |
4411 | * Element y-coordinates, in the bar cross-section, of four points at which to recover stresses |
4412 | * </ul> |
4413 | * \endif |
4414 | */ |
4415 | keyWord = "yCoords"; |
4416 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4417 | if (status == CAPS_SUCCESS0) { |
4418 | status = string_toDoubleArray(keyValue, |
4419 | (int) sizeof(feaProblem->feaProperty[i].yCoords)/sizeof(double), |
4420 | feaProblem->feaProperty[i].yCoords); |
4421 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4421 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
4422 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4423 | } |
4424 | |
4425 | /*! \page feaProperty |
4426 | * |
4427 | * \if (MYSTRAN || NASTRAN) |
4428 | * <ul> |
4429 | * <li> <B>zCoords[4] = [0.0, 0.0, 0.0, 0.0]</B> </li> <br> |
4430 | * Element z-coordinates, in the bar cross-section, of four points at which to recover stresses |
4431 | * </ul> |
4432 | * \elseif ABAQUS |
4433 | * |
4434 | * Something else .... |
4435 | * |
4436 | * \elseif ASTROS |
4437 | * <ul> |
4438 | * <li> <B>zCoords[4] = [0.0, 0.0, 0.0, 0.0]</B> </li> <br> |
4439 | * Element z-coordinates, in the bar cross-section, of four points at which to recover stresses |
4440 | * </ul> |
4441 | * \endif |
4442 | */ |
4443 | keyWord = "zCoords"; |
4444 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4445 | if (status == CAPS_SUCCESS0) { |
4446 | status = string_toDoubleArray(keyValue, |
4447 | (int) sizeof(feaProblem->feaProperty[i].zCoords)/sizeof(double), |
4448 | feaProblem->feaProperty[i].zCoords); |
4449 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4449 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
4450 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4451 | } |
4452 | |
4453 | /*! \page feaProperty |
4454 | * |
4455 | * \if (MYSTRAN || NASTRAN) |
4456 | * <ul> |
4457 | * <li> <B>areaShearFactors[2] = [0.0, 0.0]</B> </li> <br> |
4458 | * Area factors for shear. |
4459 | * </ul> |
4460 | * \elseif ABAQUS |
4461 | * |
4462 | * Something else .... |
4463 | * |
4464 | * \elseif ASTROS |
4465 | * <ul> |
4466 | * <li> <B>areaShearFactors[2] = [0.0, 0.0]</B> </li> <br> |
4467 | * Area factors for shear. |
4468 | * </ul> |
4469 | * \endif |
4470 | */ |
4471 | keyWord = "areaShearFactors"; |
4472 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4473 | if (status == CAPS_SUCCESS0) { |
4474 | status = string_toDoubleArray(keyValue, |
4475 | (int) sizeof(feaProblem->feaProperty[i].areaShearFactors)/sizeof(double), |
4476 | feaProblem->feaProperty[i].areaShearFactors); |
4477 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4477 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
4478 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4479 | } |
4480 | |
4481 | /*! \page feaProperty |
4482 | * |
4483 | * \if (MYSTRAN || NASTRAN) |
4484 | * <ul> |
4485 | * <li> <B>crossProductInertia = 0.0</B> </li> <br> |
4486 | * Section cross-product of inertia. |
4487 | * </ul> |
4488 | * \elseif ABAQUS |
4489 | * |
4490 | * Something else .... |
4491 | * |
4492 | * \elseif ASTROS |
4493 | * <ul> |
4494 | * <li> <B>crossProductInertia = 0.0</B> </li> <br> |
4495 | * Section cross-product of inertia. |
4496 | * </ul> |
4497 | * \endif |
4498 | */ |
4499 | keyWord = "crossProductInertia"; |
4500 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4501 | if (status == CAPS_SUCCESS0) { |
4502 | status = string_toDouble(keyValue, &feaProblem->feaProperty[i].crossProductInertia); |
4503 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4503 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
4504 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4505 | } |
4506 | |
4507 | /*! \page feaProperty |
4508 | * |
4509 | * \if (MYSTRAN || NASTRAN ) |
4510 | * <ul> |
4511 | * <li> <B>crossSecType = NULL</B> </li> <br> |
4512 | * Cross-section type. Must be one of following character variables: BAR, BOX, BOX1, |
4513 | * CHAN, CHAN1, CHAN2, CROSS, H, HAT, HEXA, I, I1, ROD, T, T1, T2, TUBE, or Z. |
4514 | * </ul> |
4515 | * \elseif ASTROS |
4516 | * <ul> |
4517 | * <li> <B>crossSecType = NULL</B> </li> <br> |
4518 | * Cross-section type. Must be one of following character variables: I, T, BOX, BAR, |
4519 | * TUBE, ROD, HAT, or GBOX. |
4520 | * </ul> |
4521 | * \endif |
4522 | */ |
4523 | keyWord = "crossSecType"; |
4524 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4525 | if (status == CAPS_SUCCESS0) { |
4526 | feaProblem->feaProperty[i].crossSecType = string_removeQuotation(keyValue); |
4527 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4528 | } |
4529 | |
4530 | /*! \page feaProperty |
4531 | * |
4532 | * \if (MYSTRAN || NASTRAN || ASTROS) |
4533 | * <ul> |
4534 | * <li> <B>crossSecDimension = [0,0,0,....]</B> </li> <br> |
4535 | * Cross-sectional dimensions (length of array is dependent on the "crossSecType"). Max |
4536 | * supported length array is 10! |
4537 | * </ul> |
4538 | * \endif |
4539 | */ |
4540 | keyWord = "crossSecDimension"; |
4541 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4542 | if (status == CAPS_SUCCESS0) { |
4543 | status = string_toDoubleArray(keyValue, |
4544 | (int) sizeof(feaProblem->feaProperty[i].crossSecDimension)/sizeof(double), |
4545 | feaProblem->feaProperty[i].crossSecDimension); |
4546 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4546 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
4547 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4548 | } |
4549 | |
4550 | |
4551 | /* UNDOCUMENTED orientation vector of bars - MAY be changed in the future without warning |
4552 | */ |
4553 | keyWord = "orientationVec"; |
4554 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4555 | if (status == CAPS_SUCCESS0) { |
4556 | status = string_toDoubleArray(keyValue, |
4557 | (int) sizeof(feaProblem->feaProperty[i].orientationVec)/sizeof(double), |
4558 | feaProblem->feaProperty[i].orientationVec); |
4559 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4559 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
4560 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4561 | } |
4562 | |
4563 | |
4564 | // Shear |
4565 | |
4566 | // Shell |
4567 | |
4568 | /*! \page feaProperty |
4569 | * |
4570 | * \if (MYSTRAN || NASTRAN || MASSTRAN) |
4571 | * <ul> |
4572 | * <li> <B>membraneThickness = 0.0</B> </li> <br> |
4573 | * Membrane thickness. |
4574 | * </ul> |
4575 | * \elseif ABAQUS |
4576 | * |
4577 | * Something else .... |
4578 | * |
4579 | * \elseif ASTROS |
4580 | * <ul> |
4581 | * <li> <B>membraneThickness = 0.0</B> </li> <br> |
4582 | * Membrane thickness. |
4583 | * </ul> |
4584 | * \endif |
4585 | */ |
4586 | keyWord = "membraneThickness"; |
4587 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4588 | if (status == CAPS_SUCCESS0) { |
4589 | if ( feaUnits->length != NULL((void*)0) ) { |
4590 | status = string_toDoubleUnits(aimInfo, keyValue, feaUnits->length, &feaProblem->feaProperty[i].membraneThickness); |
4591 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4591 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
4592 | } else { |
4593 | status = string_toDouble(keyValue, &feaProblem->feaProperty[i].membraneThickness); |
4594 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4594 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
4595 | } |
4596 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4597 | } |
4598 | |
4599 | |
4600 | /*! \page feaProperty |
4601 | * |
4602 | * \if (MYSTRAN || NASTRAN) |
4603 | * <ul> |
4604 | * <li> <B>bendingInertiaRatio = 1.0</B> </li> <br> |
4605 | * Ratio of actual bending moment inertia to the bending inertia of a solid plate of thickness "membraneThickness" |
4606 | * </ul> |
4607 | * \elseif ABAQUS |
4608 | * |
4609 | * Something else .... |
4610 | * |
4611 | * \elseif ASTROS |
4612 | * <ul> |
4613 | * <li> <B>bendingInertiaRatio = 1.0</B> </li> <br> |
4614 | * Ratio of actual bending moment inertia to the bending inertia of a solid plate of thickness "membraneThickness" |
4615 | * </ul> |
4616 | * \endif |
4617 | */ |
4618 | keyWord = "bendingInertiaRatio"; |
4619 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4620 | if (status == CAPS_SUCCESS0) { |
4621 | status = string_toDouble(keyValue, &feaProblem->feaProperty[i].bendingInertiaRatio); |
4622 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4622 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
4623 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4624 | } |
4625 | |
4626 | |
4627 | /*! \page feaProperty |
4628 | * |
4629 | * \if (MYSTRAN || NASTRAN) |
4630 | * <ul> |
4631 | * <li> <B>shearMembraneRatio = 5.0/6.0</B> </li> <br> |
4632 | * Ratio shear thickness to membrane thickness. |
4633 | * </ul> |
4634 | * \elseif ABAQUS |
4635 | * |
4636 | * Something else .... |
4637 | * |
4638 | * \elseif ASTROS |
4639 | * <ul> |
4640 | * <li> <B>shearMembraneRatio = 5.0/6.0</B> </li> <br> |
4641 | * Ratio shear thickness to membrane thickness. |
4642 | * </ul> |
4643 | * \endif |
4644 | */ |
4645 | keyWord = "shearMembraneRatio"; |
4646 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4647 | if (status == CAPS_SUCCESS0) { |
4648 | status = string_toDouble(keyValue, &feaProblem->feaProperty[i].shearMembraneRatio); |
4649 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4649 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
4650 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4651 | } |
4652 | |
4653 | /*! \page feaProperty |
4654 | * |
4655 | * \if (MYSTRAN || NASTRAN) |
4656 | * <ul> |
4657 | * <li> <B>materialBending = "Material Name" (\ref feaMaterial)</B> </li> <br> |
4658 | * "Material Name" from \ref feaMaterial to use for property bending. If no material is given and |
4659 | * "bendingInertiaRatio" is greater than 0, the material name provided in "material" is used. |
4660 | * </ul> |
4661 | * \elseif ABAQUS |
4662 | * |
4663 | * Something else .... |
4664 | * |
4665 | * \elseif ASTROS |
4666 | * <ul> |
4667 | * <li> <B>materialBending = "Material Name" (\ref feaMaterial)</B> </li> <br> |
4668 | * "Material Name" from \ref feaMaterial to use for property bending. |
4669 | * </ul> |
4670 | * \endif |
4671 | */ |
4672 | keyWord = "materialBending"; // Shell specific materials |
4673 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4674 | if (status == CAPS_SUCCESS0) { |
4675 | |
4676 | found = (int) false0; |
4677 | for (matIndex = 0; matIndex < feaProblem->numMaterial; matIndex++ ) { |
4678 | |
4679 | if (tempString != NULL((void*)0)) EG_free(tempString); |
4680 | tempString = string_removeQuotation(keyValue); |
4681 | |
4682 | if (strcasecmp(feaProblem->feaMaterial[matIndex].name, tempString) == 0) { |
4683 | feaProblem->feaProperty[i].materialBendingID = feaProblem->feaMaterial[matIndex].materialID; |
4684 | found = (int) true1; |
4685 | |
4686 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4687 | break; |
4688 | } |
4689 | |
4690 | } |
4691 | |
4692 | AIM_FREE(tempString){ EG_free(tempString); tempString = ((void*)0); }; |
4693 | |
4694 | if (found == (int) false0) { |
4695 | AIM_ERROR(aimInfo, "\tUnrecognized \"%s\" specified (%s) for Property tuple %s. No match in Material tuple\n", keyWord,{ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 4697, __func__ , "\tUnrecognized \"%s\" specified (%s) for Property tuple %s. No match in Material tuple\n" , keyWord, keyValue, propertyTuple[i].name); } |
4696 | keyValue,{ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 4697, __func__ , "\tUnrecognized \"%s\" specified (%s) for Property tuple %s. No match in Material tuple\n" , keyWord, keyValue, propertyTuple[i].name); } |
4697 | propertyTuple[i].name){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 4697, __func__ , "\tUnrecognized \"%s\" specified (%s) for Property tuple %s. No match in Material tuple\n" , keyWord, keyValue, propertyTuple[i].name); }; |
4698 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4699 | status = CAPS_NOTFOUND-303; |
4700 | goto cleanup; |
4701 | } |
4702 | |
4703 | } else { // Don't default to anything - yet |
4704 | |
4705 | /* |
4706 | printf("No \"%s\" specified for Property tuple %s which is a shell element, " |
4707 | " no bending material will be specified\n", keyWord, |
4708 | propertyTuple[i].name); |
4709 | |
4710 | feaProblem->feaProperty[i].materialBendingID = 0; |
4711 | */ |
4712 | |
4713 | if (feaProblem->feaProperty[i].bendingInertiaRatio > 0) { |
4714 | |
4715 | feaProblem->feaProperty[i].materialBendingID = feaProblem->feaProperty[i].materialID; |
4716 | } |
4717 | } |
4718 | |
4719 | /*! \page feaProperty |
4720 | * |
4721 | * \if (MYSTRAN || NASTRAN) |
4722 | * <ul> |
4723 | * <li> <B>materialShear = "Material Name" (\ref feaMaterial)</B> </li> <br> |
4724 | * "Material Name" from \ref feaMaterial to use for property shear. If no material is given and |
4725 | * "shearMembraneRatio" is greater than 0, the material name provided in "material" is used. |
4726 | * </ul> |
4727 | * \elseif ABAQUS |
4728 | * |
4729 | * Something else .... |
4730 | * |
4731 | * \elseif ASTROS |
4732 | * <ul> |
4733 | * <li> <B>materialShear = "Material Name" (\ref feaMaterial)</B> </li> <br> |
4734 | * "Material Name" from \ref feaMaterial to use for property shear. |
4735 | * </ul> |
4736 | * \endif |
4737 | */ |
4738 | keyWord = "materialShear"; // Shell specific materials |
4739 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4740 | if (status == CAPS_SUCCESS0) { |
4741 | |
4742 | found = (int) false0; |
4743 | for (matIndex = 0; matIndex < feaProblem->numMaterial; matIndex++ ) { |
4744 | |
4745 | if (tempString != NULL((void*)0)) EG_free(tempString); |
4746 | tempString = string_removeQuotation(keyValue); |
4747 | |
4748 | if (strcasecmp(feaProblem->feaMaterial[matIndex].name, tempString) == 0) { |
4749 | feaProblem->feaProperty[i].materialShearID = feaProblem->feaMaterial[matIndex].materialID; |
4750 | found = (int) true1; |
4751 | |
4752 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4753 | break; |
4754 | } |
4755 | |
4756 | } |
4757 | |
4758 | AIM_FREE(tempString){ EG_free(tempString); tempString = ((void*)0); }; |
4759 | |
4760 | if (found == (int) false0) { |
4761 | AIM_ERROR(aimInfo, "Unrecognized \"%s\" specified (%s) for Property tuple %s. No match in Material tuple\n", keyWord,{ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 4763, __func__ , "Unrecognized \"%s\" specified (%s) for Property tuple %s. No match in Material tuple\n" , keyWord, keyValue, propertyTuple[i].name); } |
4762 | keyValue,{ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 4763, __func__ , "Unrecognized \"%s\" specified (%s) for Property tuple %s. No match in Material tuple\n" , keyWord, keyValue, propertyTuple[i].name); } |
4763 | propertyTuple[i].name){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 4763, __func__ , "Unrecognized \"%s\" specified (%s) for Property tuple %s. No match in Material tuple\n" , keyWord, keyValue, propertyTuple[i].name); }; |
4764 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4765 | status = CAPS_NOTFOUND-303; |
4766 | goto cleanup; |
4767 | } |
4768 | |
4769 | } else { |
4770 | /* |
4771 | printf("No \"%s\" specified for Property tuple %s which is a shell element, " |
4772 | " no shear material will be specified\n", keyWord, |
4773 | propertyTuple[i].name); |
4774 | |
4775 | feaProblem->feaProperty[i].materialShearID = 0; |
4776 | */ |
4777 | |
4778 | if (feaProblem->feaProperty[i].shearMembraneRatio > 0) { |
4779 | feaProblem->feaProperty[i].materialShearID = feaProblem->feaProperty[i].materialID; |
4780 | } |
4781 | } |
4782 | |
4783 | /*! \page feaProperty |
4784 | * |
4785 | * \if (HSM || MASSTRAN) |
4786 | * <ul> |
4787 | * <li> <B>massPerArea = 0.0</B> </li> <br> |
4788 | * Mass per unit area. |
4789 | * </ul> |
4790 | * \elseif (MYSTRAN || NASTRAN || ASTROS || ABAQUS) |
4791 | * |
4792 | * <ul> |
4793 | * <li> <B>massPerArea = 0.0</B> </li> <br> |
4794 | * Non-structural mass per unit area. |
4795 | * </ul> |
4796 | * \endif |
4797 | */ |
4798 | keyWord = "massPerArea"; |
4799 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4800 | if (status == CAPS_SUCCESS0) { |
4801 | if ( feaUnits->densityArea != NULL((void*)0) ) { |
4802 | status = string_toDoubleUnits(aimInfo, keyValue, feaUnits->densityArea, &feaProblem->feaProperty[i].massPerArea); |
4803 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4803 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
4804 | } else { |
4805 | status = string_toDouble(keyValue, &feaProblem->feaProperty[i].massPerArea); |
4806 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4806 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
4807 | } |
4808 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4809 | } |
4810 | |
4811 | /*! \page feaProperty |
4812 | * |
4813 | * \if (MYSTRAN || NASTRAN || ASTROS) |
4814 | * <ul> |
4815 | * <li> <B>zOffsetRel = 0.0</B> </li> <br> |
4816 | * Relative offset from the surface of grid points to the element reference |
4817 | * plane as a percentage of the thickness. zOffSet = thickness*zOffsetRel/100 |
4818 | * |
4819 | * </ul> |
4820 | * \endif |
4821 | */ |
4822 | keyWord = "zOffsetRel"; |
4823 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4824 | if (status == CAPS_SUCCESS0) { |
4825 | status = string_toDouble(keyValue, &feaProblem->feaProperty[i].zOffsetRel); |
4826 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4826 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
4827 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4828 | } |
4829 | |
4830 | // Composite |
4831 | |
4832 | /*! \page feaProperty |
4833 | * |
4834 | * \if (MYSTRAN || NASTRAN) |
4835 | * <ul> |
4836 | * <li> <B>compositeMaterial = "no default" </B> </li> <br> |
4837 | * List of "Material Name"s, ["Material Name -1", "Material Name -2", ...], from \ref feaMaterial to use for composites. |
4838 | * </ul> |
4839 | * \elseif ABAQUS |
4840 | * |
4841 | * Something else .... |
4842 | * |
4843 | * \elseif ASTROS |
4844 | * <ul> |
4845 | * <li> <B>compositeMaterial = "no default" </B> </li> <br> |
4846 | * List of "Material Name"s, ["Material Name -1", "Material Name -2", ...], from \ref feaMaterial to use for composites. |
4847 | * </ul> |
4848 | * \endif |
4849 | */ |
4850 | keyWord = "compositeMaterial"; |
4851 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4852 | if (status == CAPS_SUCCESS0) { |
4853 | |
4854 | status = string_toStringDynamicArray(keyValue, &feaProblem->feaProperty[i].numPly, &tempStringArray); |
4855 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4855 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
4856 | |
4857 | AIM_ALLOC(feaProblem->feaProperty[i].compositeMaterialID, feaProblem->feaProperty[i].numPly, int, aimInfo, status){ if (feaProblem->feaProperty[i].compositeMaterialID != (( void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c" , 4857, __func__, 1, "AIM_ALLOC: %s != NULL", "feaProblem->feaProperty[i].compositeMaterialID" ); goto cleanup; } size_t memorysize = feaProblem->feaProperty [i].numPly; feaProblem->feaProperty[i].compositeMaterialID = (int *) EG_alloc(memorysize*sizeof(int)); if (feaProblem-> feaProperty[i].compositeMaterialID == ((void*)0)) { status = - 4; aim_status(aimInfo, status, "feaUtils.c", 4857, __func__, 3 , "AIM_ALLOC: %s size %zu type %s", "feaProblem->feaProperty[i].compositeMaterialID" , memorysize, "int"); goto cleanup; } }; |
4858 | |
4859 | for (j = 0; j < feaProblem->feaProperty[i].numPly; j++) { |
4860 | found = (int) false0; |
4861 | for (matIndex = 0; matIndex < feaProblem->numMaterial; matIndex++ ) { |
4862 | |
4863 | AIM_FREE(tempString){ EG_free(tempString); tempString = ((void*)0); }; |
4864 | tempString = string_removeQuotation(tempStringArray[j]); |
4865 | |
4866 | if (strcasecmp(feaProblem->feaMaterial[matIndex].name, tempString) == 0) { |
4867 | feaProblem->feaProperty[i].compositeMaterialID[j] = feaProblem->feaMaterial[matIndex].materialID; |
4868 | found = (int) true1; |
4869 | break; |
4870 | } |
4871 | |
4872 | } |
4873 | |
4874 | if (found == (int) false0) { |
4875 | AIM_ERROR(aimInfo, "Unrecognized \"%s\" specified (%s) for Property tuple %s. No match in Material tuple\n", keyValue,{ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 4877, __func__ , "Unrecognized \"%s\" specified (%s) for Property tuple %s. No match in Material tuple\n" , keyValue, keyWord, propertyTuple[i].name); } |
4876 | keyWord,{ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 4877, __func__ , "Unrecognized \"%s\" specified (%s) for Property tuple %s. No match in Material tuple\n" , keyValue, keyWord, propertyTuple[i].name); } |
4877 | propertyTuple[i].name){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 4877, __func__ , "Unrecognized \"%s\" specified (%s) for Property tuple %s. No match in Material tuple\n" , keyValue, keyWord, propertyTuple[i].name); }; |
4878 | |
4879 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4880 | AIM_FREE(tempString){ EG_free(tempString); tempString = ((void*)0); }; |
4881 | |
4882 | (void) string_freeArray(feaProblem->feaProperty[i].numPly, &tempStringArray); |
4883 | |
4884 | status = CAPS_NOTFOUND-303; |
4885 | goto cleanup; |
4886 | } |
4887 | |
4888 | AIM_FREE(tempString){ EG_free(tempString); tempString = ((void*)0); }; |
4889 | } |
4890 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4891 | status = string_freeArray(feaProblem->feaProperty[i].numPly, &tempStringArray); |
4892 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4892 , __func__, 0); goto cleanup; }; |
4893 | } |
4894 | |
4895 | /*! \page feaProperty |
4896 | * |
4897 | * \if (MYSTRAN || NASTRAN) |
4898 | * <ul> |
4899 | * <li> <B>shearBondAllowable = 0.0 </B> </li> <br> |
4900 | * Allowable interlaminar shear stress. |
4901 | * </ul> |
4902 | * \elseif ABAQUS |
4903 | * |
4904 | * Something else .... |
4905 | * |
4906 | * \elseif ASTROS |
4907 | * <ul> |
4908 | * <li> <B>shearBondAllowable = 0.0 </B> </li> <br> |
4909 | * Allowable interlaminar shear stress. |
4910 | * </ul> |
4911 | * \endif |
4912 | */ |
4913 | keyWord = "shearBondAllowable"; |
4914 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4915 | if (status == CAPS_SUCCESS0) { |
4916 | status = string_toDouble(keyValue, &feaProblem->feaProperty[i].compositeShearBondAllowable); |
4917 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4917 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
4918 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4919 | } |
4920 | |
4921 | /*! \page feaProperty |
4922 | * |
4923 | * \if (MYSTRAN || NASTRAN) |
4924 | * <ul> |
4925 | * <li> <B>symmetricLaminate = False </B> </li> <br> |
4926 | * Symmetric lamination option. True- SYM only half the plies are specified, for odd number plies 1/2 thickness |
4927 | * of center ply is specified with the first ply being the bottom ply in the stack, default (False) all plies specified. |
4928 | * </ul> |
4929 | * \elseif (ASTROS) |
4930 | * <ul> |
4931 | * <li> <B>symmetricLaminate = False </B> </li> <br> |
4932 | * Symmetric lamination option. If "True" only half the plies are specified (the plies will be repeated in |
4933 | * reverse order internally in the PCOMP card). For an odd number of plies, the 1/2 thickness |
4934 | * of the center ply is specified with the first ply being the bottom ply in the stack, default (False) all plies specified. |
4935 | * </ul> |
4936 | * \endif |
4937 | */ |
4938 | keyWord = "symmetricLaminate"; |
4939 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4940 | if (status == CAPS_SUCCESS0) { |
4941 | status = string_toBoolean(keyValue, &feaProblem->feaProperty[i].compositeSymmetricLaminate); |
4942 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4942 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
4943 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4944 | } |
4945 | |
4946 | /*! \page feaProperty |
4947 | * |
4948 | * \if (MYSTRAN || NASTRAN) |
4949 | * <ul> |
4950 | * <li> <B>compositeFailureTheory = "(no default)" </B> </li> <br> |
4951 | * Composite failure theory. Options: "HILL", "HOFF", "TSAI", and "STRN" |
4952 | * </ul> |
4953 | * \elseif ABAQUS |
4954 | * |
4955 | * Something else .... |
4956 | * |
4957 | * \elseif ASTROS |
4958 | * <ul> |
4959 | * <li> <B>compositeFailureTheory = "(no default)" </B> </li> <br> |
4960 | * Composite failure theory. |
4961 | * </ul> |
4962 | * \endif |
4963 | */ |
4964 | keyWord = "compositeFailureTheory"; |
4965 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4966 | if (status == CAPS_SUCCESS0) { |
4967 | feaProblem->feaProperty[i].compositeFailureTheory = string_removeQuotation(keyValue); |
4968 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4968 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
4969 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
4970 | } |
4971 | |
4972 | /*! \page feaProperty |
4973 | * |
4974 | * \if (MYSTRAN || NASTRAN) |
4975 | * <ul> |
4976 | * <li> <B>compositeThickness = (no default) </B> </li> <br> |
4977 | * List of composite thickness for each layer (e.g. [1.2, 4.0, 3.0]). If the length of this list doesn't match the length |
4978 | * of the "compositeMaterial" list, the list is either truncated [ >length("compositeMaterial")] or expanded [ <length("compositeMaterial")] |
4979 | * in which case the last thickness provided is repeated. |
4980 | * </ul> |
4981 | * \elseif ABAQUS |
4982 | * |
4983 | * Something else .... |
4984 | * |
4985 | * \elseif ASTROS |
4986 | * <ul> |
4987 | * <li> <B>compositeThickness = (no default) </B> </li> <br> |
4988 | * List of composite thickness for each layer (e.g. [1.2, 4.0, 3.0]). If the length of this list doesn't match the length |
4989 | * of the "compositeMaterial" list, the list is either truncated [ >length("compositeMaterial")] or expanded [ <length("compositeMaterial")] |
4990 | * in which case the last thickness provided is repeated. |
4991 | * </ul> |
4992 | * \endif |
4993 | */ |
4994 | keyWord = "compositeThickness"; |
4995 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
4996 | if (status == CAPS_SUCCESS0) { |
4997 | status = string_toDoubleDynamicArray(keyValue, &tempInteger, |
4998 | &feaProblem->feaProperty[i].compositeThickness); |
4999 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 4999 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
5000 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
5001 | |
5002 | if (tempInteger < feaProblem->feaProperty[i].numPly) { |
5003 | |
5004 | printf("\tThe number of thicknesses provided does not match the number of materials for the composite. " |
5005 | "The last thickness will be repeated %d times\n", feaProblem->feaProperty[i].numPly - tempInteger); |
5006 | |
5007 | AIM_REALL(feaProblem->feaProperty[i].compositeThickness,{ size_t memorysize = feaProblem->feaProperty[i].numPly; feaProblem ->feaProperty[i].compositeThickness = (double *) EG_reall( feaProblem->feaProperty[i].compositeThickness, memorysize* sizeof(double)); if (feaProblem->feaProperty[i].compositeThickness == ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c" , 5008, __func__, 3, "AIM_REALL: %s size %zu type %s", "feaProblem->feaProperty[i].compositeThickness" , memorysize, "double"); goto cleanup; } } |
5008 | feaProblem->feaProperty[i].numPly, double, aimInfo, status){ size_t memorysize = feaProblem->feaProperty[i].numPly; feaProblem ->feaProperty[i].compositeThickness = (double *) EG_reall( feaProblem->feaProperty[i].compositeThickness, memorysize* sizeof(double)); if (feaProblem->feaProperty[i].compositeThickness == ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c" , 5008, __func__, 3, "AIM_REALL: %s size %zu type %s", "feaProblem->feaProperty[i].compositeThickness" , memorysize, "double"); goto cleanup; } }; |
5009 | |
5010 | for (j = 0; j < feaProblem->feaProperty[i].numPly - tempInteger; j++) { |
5011 | |
5012 | feaProblem->feaProperty[i].compositeThickness[j+tempInteger] = feaProblem->feaProperty[i].compositeThickness[tempInteger-1]; |
5013 | } |
5014 | } |
5015 | |
5016 | if (tempInteger > feaProblem->feaProperty[i].numPly) { |
5017 | |
5018 | printf("\tThe number of thicknesses provided does not match the number of materials for the composite. " |
5019 | "The last %d thicknesses will be not be used\n", tempInteger -feaProblem->feaProperty[i].numPly); |
5020 | |
5021 | AIM_REALL(feaProblem->feaProperty[i].compositeThickness,{ size_t memorysize = feaProblem->feaProperty[i].numPly; feaProblem ->feaProperty[i].compositeThickness = (double *) EG_reall( feaProblem->feaProperty[i].compositeThickness, memorysize* sizeof(double)); if (feaProblem->feaProperty[i].compositeThickness == ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c" , 5022, __func__, 3, "AIM_REALL: %s size %zu type %s", "feaProblem->feaProperty[i].compositeThickness" , memorysize, "double"); goto cleanup; } } |
5022 | feaProblem->feaProperty[i].numPly, double, aimInfo, status){ size_t memorysize = feaProblem->feaProperty[i].numPly; feaProblem ->feaProperty[i].compositeThickness = (double *) EG_reall( feaProblem->feaProperty[i].compositeThickness, memorysize* sizeof(double)); if (feaProblem->feaProperty[i].compositeThickness == ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c" , 5022, __func__, 3, "AIM_REALL: %s size %zu type %s", "feaProblem->feaProperty[i].compositeThickness" , memorysize, "double"); goto cleanup; } }; |
5023 | } |
5024 | } else { |
5025 | |
5026 | if (feaProblem->feaProperty[i].numPly != 0 && |
5027 | feaProblem->feaProperty[i].propertyType == Composite) { |
5028 | |
5029 | AIM_ERROR(aimInfo, "\"compositeMaterial\" have been set but no thicknesses (\"compositeThickness\") provided!!!"){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 5029, __func__ , "\"compositeMaterial\" have been set but no thicknesses (\"compositeThickness\") provided!!!" ); }; |
5030 | status = CAPS_BADVALUE-311; |
5031 | goto cleanup; |
5032 | } |
5033 | } |
5034 | |
5035 | /*! \page feaProperty |
5036 | * |
5037 | * \if (MYSTRAN || NASTRAN) |
5038 | * <ul> |
5039 | * <li> <B>compositeOrientation = (no default) </B> </li> <br> |
5040 | * List of composite orientations (angle relative element material axis) for each layer (eg. [5.0, 10.0, 30.0]). |
5041 | * If the length of this list doesn't match the length of the "compositeMaterial" list, the list is either |
5042 | * truncated [ >length("compositeMaterial")] or expanded [ <length("compositeMaterial")] in which case |
5043 | * the last orientation provided is repeated. |
5044 | * </ul> |
5045 | * \elseif ABAQUS |
5046 | * |
5047 | * Something else .... |
5048 | * |
5049 | * \elseif ASTROS |
5050 | * <ul> |
5051 | * <li> <B>compositeOrientation = (no default) </B> </li> <br> |
5052 | * List of composite orientations (angle relative element material axis) for each layer (eg. [5.0, 10.0, 30.0]). |
5053 | * If the length of this list doesn't match the length of the "compositeMaterial" list, the list is either |
5054 | * truncated [ >length("compositeMaterial")] or expanded [ <length("compositeMaterial")] in which case |
5055 | * the last orientation provided is repeated. |
5056 | * </ul> |
5057 | * \endif |
5058 | */ |
5059 | keyWord = "compositeOrientation"; |
5060 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
5061 | if (status == CAPS_SUCCESS0) { |
5062 | status = string_toDoubleDynamicArray(keyValue, &tempInteger, |
5063 | &feaProblem->feaProperty[i].compositeOrientation); |
5064 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 5064 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
5065 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
5066 | |
5067 | if (tempInteger < feaProblem->feaProperty[i].numPly) { |
5068 | |
5069 | printf("\tThe number of orientations provided does not match the number of materials for the composite. " |
5070 | "The last orientation will be repeated %d times\n", feaProblem->feaProperty[i].numPly - tempInteger); |
5071 | |
5072 | AIM_REALL(feaProblem->feaProperty[i].compositeOrientation,{ size_t memorysize = feaProblem->feaProperty[i].numPly; feaProblem ->feaProperty[i].compositeOrientation = (double *) EG_reall (feaProblem->feaProperty[i].compositeOrientation, memorysize *sizeof(double)); if (feaProblem->feaProperty[i].compositeOrientation == ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c" , 5073, __func__, 3, "AIM_REALL: %s size %zu type %s", "feaProblem->feaProperty[i].compositeOrientation" , memorysize, "double"); goto cleanup; } } |
5073 | feaProblem->feaProperty[i].numPly, double, aimInfo, status){ size_t memorysize = feaProblem->feaProperty[i].numPly; feaProblem ->feaProperty[i].compositeOrientation = (double *) EG_reall (feaProblem->feaProperty[i].compositeOrientation, memorysize *sizeof(double)); if (feaProblem->feaProperty[i].compositeOrientation == ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c" , 5073, __func__, 3, "AIM_REALL: %s size %zu type %s", "feaProblem->feaProperty[i].compositeOrientation" , memorysize, "double"); goto cleanup; } }; |
5074 | |
5075 | for (j = 0; j < feaProblem->feaProperty[i].numPly - tempInteger; j++) { |
5076 | |
5077 | feaProblem->feaProperty[i].compositeOrientation[j+tempInteger] = feaProblem->feaProperty[i].compositeOrientation[tempInteger-1]; |
5078 | } |
5079 | } |
5080 | |
5081 | if (tempInteger > feaProblem->feaProperty[i].numPly) { |
5082 | |
5083 | printf("\tThe number of orientations provided does not match the number of materials for the composite. " |
5084 | "The last %d orientation will be not be used\n", tempInteger -feaProblem->feaProperty[i].numPly); |
5085 | |
5086 | AIM_REALL(feaProblem->feaProperty[i].compositeOrientation,{ size_t memorysize = feaProblem->feaProperty[i].numPly; feaProblem ->feaProperty[i].compositeOrientation = (double *) EG_reall (feaProblem->feaProperty[i].compositeOrientation, memorysize *sizeof(double)); if (feaProblem->feaProperty[i].compositeOrientation == ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c" , 5087, __func__, 3, "AIM_REALL: %s size %zu type %s", "feaProblem->feaProperty[i].compositeOrientation" , memorysize, "double"); goto cleanup; } } |
5087 | feaProblem->feaProperty[i].numPly, double, aimInfo, status){ size_t memorysize = feaProblem->feaProperty[i].numPly; feaProblem ->feaProperty[i].compositeOrientation = (double *) EG_reall (feaProblem->feaProperty[i].compositeOrientation, memorysize *sizeof(double)); if (feaProblem->feaProperty[i].compositeOrientation == ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c" , 5087, __func__, 3, "AIM_REALL: %s size %zu type %s", "feaProblem->feaProperty[i].compositeOrientation" , memorysize, "double"); goto cleanup; } }; |
5088 | } |
5089 | |
5090 | } else { |
5091 | |
5092 | if (feaProblem->feaProperty[i].numPly != 0 && |
5093 | feaProblem->feaProperty[i].propertyType == Composite) { |
5094 | |
5095 | AIM_ERROR(aimInfo, "\"compositeMaterial\" have been set but no Orientation (\"compositeOrientation\") provided!!!"){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 5095, __func__ , "\"compositeMaterial\" have been set but no Orientation (\"compositeOrientation\") provided!!!" ); }; |
5096 | status = CAPS_BADVALUE-311; |
5097 | goto cleanup; |
5098 | } |
5099 | } |
5100 | |
5101 | // Mass |
5102 | |
5103 | /*! \page feaProperty |
5104 | * |
5105 | * \if (MYSTRAN || NASTRAN) |
5106 | * <ul> |
5107 | * <li> <B>mass = 0.0</B> </li> <br> |
5108 | * Mass value. |
5109 | * </ul> |
5110 | * \elseif ABAQUS |
5111 | * |
5112 | * Something else .... |
5113 | * |
5114 | * \elseif ASTROS |
5115 | * <ul> |
5116 | * <li> <B>mass = 0.0</B> </li> <br> |
5117 | * Mass value. |
5118 | * </ul> |
5119 | * \endif |
5120 | */ |
5121 | keyWord = "mass"; |
5122 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
5123 | if (status == CAPS_SUCCESS0) { |
5124 | status = string_toDouble(keyValue, &feaProblem->feaProperty[i].mass); |
5125 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 5125 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
5126 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
5127 | } |
5128 | |
5129 | /*! \page feaProperty |
5130 | * |
5131 | * \if (MYSTRAN || NASTRAN || MASSTRAN) |
5132 | * <ul> |
5133 | * <li> <B>massOffset = [0.0, 0.0, 0.0]</B> </li> <br> |
5134 | * Offset distance from the grid point to the center of gravity for a concentrated mass. |
5135 | * </ul> |
5136 | * \elseif ABAQUS |
5137 | * |
5138 | * Something else .... |
5139 | * |
5140 | * \elseif ASTROS |
5141 | * <ul> |
5142 | * <li> <B>massOffset = [0.0, 0.0, 0.0]</B> </li> <br> |
5143 | * Offset distance from the grid point to the center of gravity for a concentrated mass. |
5144 | * </ul> |
5145 | * \endif |
5146 | */ |
5147 | keyWord = "massOffset"; |
5148 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
5149 | if (status == CAPS_SUCCESS0) { |
5150 | status = string_toDoubleArray(keyValue, |
5151 | (int) sizeof(feaProblem->feaProperty[i].massOffset)/sizeof(double), |
5152 | feaProblem->feaProperty[i].massOffset); |
5153 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 5153 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
5154 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
5155 | } |
5156 | |
5157 | /*! \page feaProperty |
5158 | * |
5159 | * \if (MYSTRAN || NASTRAN || MASSTRAN) |
5160 | * <ul> |
5161 | * <li> <B>massInertia = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]</B> </li> <br> |
5162 | * Mass moment of inertia measured at the mass center of gravity. |
5163 | * </ul> |
5164 | * \elseif ABAQUS |
5165 | *v |
5166 | * Something else .... |
5167 | * |
5168 | * \elseif ASTROS |
5169 | * <ul> |
5170 | * <li> <B>massInertia = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]</B> </li> <br> |
5171 | * Mass moment of inertia measured at the mass center of gravity. |
5172 | * </ul> |
5173 | * \endif |
5174 | */ |
5175 | keyWord = "massInertia"; |
5176 | status = search_jsonDictionary( propertyTuple[i].value, keyWord, &keyValue); |
5177 | if (status == CAPS_SUCCESS0) { |
5178 | status = string_toDoubleArray(keyValue, |
5179 | (int) sizeof(feaProblem->feaProperty[i].massInertia)/sizeof(double), |
5180 | feaProblem->feaProperty[i].massInertia); |
5181 | AIM_STATUS(aimInfo, status, "While parsing \"%s\":\"%s\"", keyWord, keyValue)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 5181 , __func__, 3, "While parsing \"%s\":\"%s\"", keyWord, keyValue ); goto cleanup; }; |
5182 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
5183 | } |
5184 | |
5185 | } else { |
5186 | |
5187 | /*! \page feaProperty |
5188 | * \section keyStringProperty Single Value String |
5189 | * |
5190 | * If "Value" is a string, the string value may correspond to an entry in a predefined property lookup |
5191 | * table. NOT YET IMPLEMENTED!!!! |
5192 | * |
5193 | */ |
5194 | |
5195 | // CALL property look up |
5196 | AIM_ERROR(aimInfo, "Property tuple value ('s') is expected to be a JSON string", propertyTuple[i].value){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 5196, __func__ , "Property tuple value ('s') is expected to be a JSON string" , propertyTuple[i].value); }; |
5197 | status = CAPS_BADVALUE-311; |
5198 | goto cleanup; |
5199 | } |
5200 | } |
5201 | |
5202 | printf("\tDone getting FEA properties\n"); |
5203 | status = CAPS_SUCCESS0; |
5204 | |
5205 | cleanup: |
5206 | AIM_FREE(tempString){ EG_free(tempString); tempString = ((void*)0); }; |
5207 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
5208 | |
5209 | return status; |
5210 | } |
5211 | |
5212 | // Get the constraint properties from a capsTuple |
5213 | int fea_getConstraint(int numConstraintTuple, |
5214 | capsTuple constraintTuple[], |
5215 | mapAttrToIndexStruct *attrMap, |
5216 | feaProblemStruct *feaProblem) { |
5217 | |
5218 | /*! \page feaConstraint FEA Constraint |
5219 | * Structure for the constraint tuple = ("Constraint Name", "Value"). |
5220 | * "Constraint Name" defines the reference name for the constraint being specified. |
5221 | * The "Value" can either be a JSON String dictionary (see Section \ref jsonStringConstraint) or a single string keyword |
5222 | * (see Section \ref keyStringConstraint). |
5223 | */ |
5224 | |
5225 | int status; //Function return |
5226 | |
5227 | int i, groupIndex, attrIndex, nodeIndex; // Indexing |
5228 | |
5229 | char *keyValue = NULL((void*)0); // Key values from tuple searches |
5230 | char *keyWord = NULL((void*)0); // Key words to find in the tuples |
5231 | |
5232 | int numGroupName = 0; |
5233 | char **groupName = NULL((void*)0); |
5234 | |
5235 | feaMeshDataStruct *feaData; |
5236 | |
5237 | // Destroy our constraint structures coming in if aren't 0 and NULL already |
5238 | if (feaProblem->feaConstraint != NULL((void*)0)) { |
5239 | for (i = 0; i < feaProblem->numConstraint; i++) { |
5240 | status = destroy_feaConstraintStruct(&feaProblem->feaConstraint[i]); |
5241 | if (status != CAPS_SUCCESS0) return status; |
5242 | } |
5243 | } |
5244 | if (feaProblem->feaConstraint != NULL((void*)0)) EG_free(feaProblem->feaConstraint); |
5245 | feaProblem->feaConstraint = NULL((void*)0); |
5246 | feaProblem->numConstraint = 0; |
5247 | |
5248 | printf("\nGetting FEA constraints.......\n"); |
5249 | |
5250 | feaProblem->numConstraint = numConstraintTuple; |
5251 | |
5252 | printf("\tNumber of constraints - %d\n", feaProblem->numConstraint); |
5253 | |
5254 | // Allocate constraints |
5255 | if (feaProblem->numConstraint > 0) { |
5256 | feaProblem->feaConstraint = (feaConstraintStruct *) EG_alloc(feaProblem->numConstraint * sizeof(feaConstraintStruct)); |
5257 | |
5258 | if (feaProblem->feaConstraint == NULL((void*)0) ) return EGADS_MALLOC-4; |
5259 | } |
5260 | |
5261 | // Initiate constraints to default values |
5262 | for (i = 0; i < feaProblem->numConstraint; i++) { |
5263 | status = initiate_feaConstraintStruct(&feaProblem->feaConstraint[i]); |
5264 | if (status != CAPS_SUCCESS0) return status; |
5265 | } |
5266 | |
5267 | // Loop through tuples and fill out the constraint structures |
5268 | for (i = 0; i < feaProblem->numConstraint; i++) { |
5269 | |
5270 | printf("\tConstraint name - %s\n", constraintTuple[i].name ); |
5271 | |
5272 | // Set constraint name to tuple attribute name |
5273 | feaProblem->feaConstraint[i].name = (char *) EG_alloc((strlen(constraintTuple[i].name) + 1)*sizeof(char)); |
5274 | if (feaProblem->feaConstraint[i].name == NULL((void*)0)) return EGADS_MALLOC-4; |
5275 | |
5276 | memcpy(feaProblem->feaConstraint[i].name, constraintTuple[i].name, strlen(constraintTuple[i].name)*sizeof(char)); |
5277 | feaProblem->feaConstraint[i].name[strlen(constraintTuple[i].name)] = '\0'; |
5278 | |
5279 | // Set constraint id -> 1 bias |
5280 | feaProblem->feaConstraint[i].constraintID = i+1; |
5281 | |
5282 | // Do we have a json string? |
5283 | if (strncmp(constraintTuple[i].value, "{", 1) == 0) { |
5284 | //printf("JSON String - %s\n", constraintTuple[i].value); |
5285 | |
5286 | /*! \page feaConstraint |
5287 | * \section jsonStringConstraint JSON String Dictionary |
5288 | * |
5289 | * If "Value" is JSON string dictionary |
5290 | * \if (MYSTRAN || NASTRAN || ASTROS || HSM || ABAQUS) |
5291 | * (eg. "Value" = {"groupName": "plateEdge", "dofConstraint": 123456}) |
5292 | * \endif |
5293 | * the following keywords ( = default values) may be used: |
5294 | * |
5295 | * \if (MYSTRAN || NASTRAN || ASTROS || HSM || ABAQUS) |
5296 | * <ul> |
5297 | * <li> <B>constraintType = "ZeroDisplacement"</B> </li> <br> |
5298 | * Type of constraint. Options: "Displacement", "ZeroDisplacement". |
5299 | * </ul> |
5300 | * \endif |
5301 | * |
5302 | */ |
5303 | // Get constraint Type |
5304 | keyWord = "constraintType"; |
5305 | status = search_jsonDictionary( constraintTuple[i].value, keyWord, &keyValue); |
5306 | if (status == CAPS_SUCCESS0) { |
5307 | |
5308 | //{UnknownConstraint, Displacement, ZeroDisplacement} |
5309 | if (strcasecmp(keyValue, "\"Displacement\"") == 0) feaProblem->feaConstraint[i].constraintType = Displacement; |
5310 | else if (strcasecmp(keyValue, "\"ZeroDisplacement\"") == 0) feaProblem->feaConstraint[i].constraintType = ZeroDisplacement; |
5311 | else { |
5312 | |
5313 | printf("\tUnrecognized \"%s\" specified (%s) for Constraint tuple %s, defaulting to \"ZeroDisplacement\"\n", keyWord, |
5314 | keyValue, |
5315 | constraintTuple[i].name); |
5316 | feaProblem->feaConstraint[i].constraintType = ZeroDisplacement; |
5317 | } |
5318 | |
5319 | } else { |
5320 | |
5321 | printf("\tNo \"%s\" specified for Constraint tuple %s, defaulting to \"ZeroDisplacement\"\n", keyWord, |
5322 | constraintTuple[i].name); |
5323 | feaProblem->feaConstraint[i].constraintType = ZeroDisplacement; |
5324 | } |
5325 | |
5326 | if (keyValue != NULL((void*)0)) { |
5327 | EG_free(keyValue); |
5328 | keyValue = NULL((void*)0); |
5329 | } |
5330 | |
5331 | // Get constraint node set |
5332 | |
5333 | /*! \page feaConstraint |
5334 | * |
5335 | * \if MYSTRAN || NASTRAN || ASTROS || HSM || ABAQUS) |
5336 | * <ul> |
5337 | * <li> <B>groupName = "(no default)"</B> </li> <br> |
5338 | * Single or list of <c>capsConstraint</c> names on which to apply the constraint |
5339 | * (e.g. "Name1" or ["Name1","Name2",...]. If not provided, the constraint tuple name will be |
5340 | * used. |
5341 | * </ul> |
5342 | * \endif |
5343 | * |
5344 | */ |
5345 | keyWord = "groupName"; |
5346 | status = search_jsonDictionary( constraintTuple[i].value, keyWord, &keyValue); |
5347 | if (status == CAPS_SUCCESS0) { |
5348 | |
5349 | status = string_toStringDynamicArray(keyValue, &numGroupName, &groupName); |
5350 | if (keyValue != NULL((void*)0)) EG_free(keyValue); |
5351 | keyValue = NULL((void*)0); |
5352 | |
5353 | if (status != CAPS_SUCCESS0) return status; |
5354 | |
5355 | } else { |
5356 | |
5357 | printf("\tNo \"%s\" specified for Constraint tuple %s, going to use constraint name\n", keyWord, |
5358 | constraintTuple[i].name); |
5359 | |
5360 | status = string_toStringDynamicArray(constraintTuple[i].name, &numGroupName, &groupName); |
5361 | if (status != CAPS_SUCCESS0) return status; |
5362 | |
5363 | } |
5364 | |
5365 | // Determine how many point constraints we have |
5366 | feaProblem->feaConstraint[i].numGridID = 0; |
5367 | for (groupIndex = 0; groupIndex < numGroupName; groupIndex++) { |
5368 | |
5369 | status = get_mapAttrToIndexIndex(attrMap, (const char *) groupName[groupIndex], &attrIndex); |
5370 | |
5371 | if (status == CAPS_NOTFOUND-303) { |
5372 | printf("\tName %s not found in attribute map of capsConstraints!!!!\n", groupName[groupIndex]); |
5373 | continue; |
5374 | } else if (status != CAPS_SUCCESS0) return status; |
5375 | |
5376 | // Now lets loop through the grid to see how many grid points have the attrIndex |
5377 | for (nodeIndex = 0; nodeIndex < feaProblem->feaMesh.numNode; nodeIndex++ ) { |
5378 | |
5379 | if (feaProblem->feaMesh.node[nodeIndex].analysisType == MeshStructure) { |
5380 | feaData = (feaMeshDataStruct *) feaProblem->feaMesh.node[nodeIndex].analysisData; |
5381 | } else { |
5382 | continue; |
5383 | } |
5384 | |
5385 | if (feaData->constraintIndex == attrIndex) { |
5386 | |
5387 | feaProblem->feaConstraint[i].numGridID += 1; |
5388 | |
5389 | // Allocate/Re-allocate grid ID array |
5390 | if (feaProblem->feaConstraint[i].numGridID == 1) { |
5391 | feaProblem->feaConstraint[i].gridIDSet = (int *) EG_alloc(feaProblem->feaConstraint[i].numGridID*sizeof(int)); |
5392 | } else { |
5393 | feaProblem->feaConstraint[i].gridIDSet = (int *) EG_reall(feaProblem->feaConstraint[i].gridIDSet, |
5394 | feaProblem->feaConstraint[i].numGridID*sizeof(int)); |
5395 | } |
5396 | |
5397 | if (feaProblem->feaConstraint[i].gridIDSet == NULL((void*)0)) { |
5398 | status = string_freeArray(numGroupName, &groupName); |
5399 | if (status != CAPS_SUCCESS0) printf("Status %d during string_freeArray\n", status); |
5400 | |
5401 | return EGADS_MALLOC-4; |
5402 | } |
5403 | |
5404 | // Set grid ID value -> 1 bias |
5405 | feaProblem->feaConstraint[i].gridIDSet[feaProblem->feaConstraint[i].numGridID-1] = feaProblem->feaMesh.node[nodeIndex].nodeID; |
5406 | } |
5407 | } |
5408 | } |
5409 | |
5410 | status = string_freeArray(numGroupName, &groupName); |
5411 | if (status != CAPS_SUCCESS0) return status; |
5412 | groupName = NULL((void*)0); |
5413 | |
5414 | |
5415 | //Fill up constraint properties |
5416 | /*! \page feaConstraint |
5417 | * |
5418 | * \if (MYSTRAN || NASTRAN || ASTROS || HSM || ABAQUS) |
5419 | * <ul> |
5420 | * <li> <B>dofConstraint = 0 </B> </li> <br> |
5421 | * Component numbers / degrees of freedom that will be constrained (123 - zero translation in all three |
5422 | * directions). |
5423 | * </ul> |
5424 | * \endif |
5425 | */ |
5426 | keyWord = "dofConstraint"; |
5427 | status = search_jsonDictionary( constraintTuple[i].value, keyWord, &keyValue); |
5428 | if (status == CAPS_SUCCESS0) { |
5429 | |
5430 | status = string_toInteger(keyValue, &feaProblem->feaConstraint[i].dofConstraint); |
5431 | if (keyValue != NULL((void*)0)) { |
5432 | EG_free(keyValue); |
5433 | keyValue = NULL((void*)0); |
5434 | } |
5435 | if (status != CAPS_SUCCESS0) return status; |
5436 | } |
5437 | |
5438 | /*! \page feaConstraint |
5439 | * |
5440 | * \if (MYSTRAN || NASTRAN || ASTROS || HSM || ABAQUS) |
5441 | * <ul> |
5442 | * <li> <B>gridDisplacement = 0.0 </B> </li> <br> |
5443 | * Value of displacement for components defined in "dofConstraint". |
5444 | * </ul> |
5445 | * \endif |
5446 | */ |
5447 | keyWord = "gridDisplacement"; |
5448 | status = search_jsonDictionary( constraintTuple[i].value, keyWord, &keyValue); |
5449 | if (status == CAPS_SUCCESS0) { |
5450 | |
5451 | status = string_toDouble(keyValue, &feaProblem->feaConstraint[i].gridDisplacement); |
5452 | if (keyValue != NULL((void*)0)) { |
5453 | EG_free(keyValue); |
5454 | keyValue = NULL((void*)0); |
5455 | } |
5456 | if (status != CAPS_SUCCESS0) return status; |
5457 | } |
5458 | |
5459 | } else { |
5460 | |
5461 | /*! \page feaConstraint |
5462 | * \section keyStringConstraint Single Value String |
5463 | * |
5464 | * If "Value" is a string, the string value may correspond to an entry in a predefined constraint lookup |
5465 | * table. NOT YET IMPLEMENTED!!!! |
5466 | * |
5467 | */ |
5468 | |
5469 | // Call some look up table maybe? |
5470 | printf("\tError: Constraint tuple value is expected to be a JSON string\n"); |
5471 | return CAPS_BADVALUE-311; |
5472 | } |
5473 | } |
5474 | |
5475 | if (keyValue != NULL((void*)0)) EG_free(keyValue); |
5476 | |
5477 | printf("\tDone getting FEA constraints\n"); |
5478 | return CAPS_SUCCESS0; |
5479 | } |
5480 | |
5481 | // Get the support properties from a capsTuple |
5482 | int fea_getSupport(int numSupportTuple, |
5483 | capsTuple supportTuple[], |
5484 | mapAttrToIndexStruct *attrMap, |
5485 | feaProblemStruct *feaProblem) { |
5486 | |
5487 | /*! \page feaSupport FEA Support |
5488 | * Structure for the support tuple = ("Support Name", "Value"). |
5489 | * "Support Name" defines the reference name for the support being specified. |
5490 | * The "Value" can either be a JSON String dictionary (see Section \ref jsonStringSupport) or a single string keyword |
5491 | * (see Section \ref keyStringSupport). |
5492 | */ |
5493 | |
5494 | int status; //Function return |
5495 | |
5496 | int i, groupIndex, attrIndex, nodeIndex; // Indexing |
5497 | |
5498 | char *keyValue = NULL((void*)0); // Key values from tuple searches |
5499 | char *keyWord = NULL((void*)0); // Key words to find in the tuples |
5500 | |
5501 | int numGroupName = 0; |
5502 | char **groupName = NULL((void*)0); |
5503 | |
5504 | feaMeshDataStruct *feaData; |
5505 | |
5506 | // Destroy our support structures coming in if aren't 0 and NULL already |
5507 | if (feaProblem->feaSupport != NULL((void*)0)) { |
5508 | for (i = 0; i < feaProblem->numSupport; i++) { |
5509 | status = destroy_feaSupportStruct(&feaProblem->feaSupport[i]); |
5510 | if (status != CAPS_SUCCESS0) return status; |
5511 | } |
5512 | } |
5513 | if (feaProblem->feaSupport != NULL((void*)0)) EG_free(feaProblem->feaSupport); |
5514 | feaProblem->feaSupport = NULL((void*)0); |
5515 | feaProblem->numSupport = 0; |
5516 | |
5517 | printf("\nGetting FEA supports.......\n"); |
5518 | |
5519 | feaProblem->numSupport = numSupportTuple; |
5520 | |
5521 | printf("\tNumber of supports - %d\n", feaProblem->numSupport); |
5522 | |
5523 | // Allocate supports |
5524 | if (feaProblem->numSupport > 0) { |
5525 | feaProblem->feaSupport = (feaSupportStruct *) EG_alloc(feaProblem->numSupport * sizeof(feaSupportStruct)); |
5526 | |
5527 | if (feaProblem->feaSupport == NULL((void*)0) ) return EGADS_MALLOC-4; |
5528 | } |
5529 | |
5530 | // Initiate supports to default values |
5531 | for (i = 0; i < feaProblem->numSupport; i++) { |
5532 | status = initiate_feaSupportStruct(&feaProblem->feaSupport[i]); |
5533 | if (status != CAPS_SUCCESS0) return status; |
5534 | } |
5535 | |
5536 | // Loop through tuples and fill out the support structures |
5537 | for (i = 0; i < feaProblem->numSupport; i++) { |
5538 | |
5539 | printf("\tSupport name - %s\n", supportTuple[i].name ); |
5540 | |
5541 | // Set support name to tuple attribute name |
5542 | feaProblem->feaSupport[i].name = (char *) EG_alloc((strlen(supportTuple[i].name) + 1)*sizeof(char)); |
5543 | if (feaProblem->feaSupport[i].name == NULL((void*)0)) return EGADS_MALLOC-4; |
5544 | |
5545 | memcpy(feaProblem->feaSupport[i].name, supportTuple[i].name, strlen(supportTuple[i].name)*sizeof(char)); |
5546 | feaProblem->feaSupport[i].name[strlen(supportTuple[i].name)] = '\0'; |
5547 | |
5548 | // Set support id -> 1 bias |
5549 | feaProblem->feaSupport[i].supportID = i+1; |
5550 | |
5551 | // Do we have a json string? |
5552 | if (strncmp(supportTuple[i].value, "{", 1) == 0) { |
5553 | //printf("JSON String - %s\n", supportTuple[i].value); |
5554 | |
5555 | /*! \page feaSupport |
5556 | * \section jsonStringSupport JSON String Dictionary |
5557 | * |
5558 | * If "Value" is JSON string dictionary |
5559 | * \if (MYSTRAN || NASTRAN || ASTROS) |
5560 | * (eg. "Value" = {"groupName": "plateEdge", "dofSupport": 123456}) |
5561 | * \endif |
5562 | * the following keywords ( = default values) may be used: |
5563 | */ |
5564 | |
5565 | // Get support node set |
5566 | |
5567 | /*! \page feaSupport |
5568 | * |
5569 | * \if (MYSTRAN || NASTRAN || ASTROS) |
5570 | * <ul> |
5571 | * <li> <B>groupName = "(no default)"</B> </li> <br> |
5572 | * Single or list of <c>capsConstraint</c> names on which to apply the support |
5573 | * (e.g. "Name1" or ["Name1","Name2",...]. If not provided, the constraint tuple name will be |
5574 | * used. |
5575 | * </ul> |
5576 | * \endif |
5577 | */ |
5578 | keyWord = "groupName"; |
5579 | status = search_jsonDictionary( supportTuple[i].value, keyWord, &keyValue); |
5580 | if (status == CAPS_SUCCESS0) { |
5581 | |
5582 | status = string_toStringDynamicArray(keyValue, &numGroupName, &groupName); |
5583 | if (keyValue != NULL((void*)0)) EG_free(keyValue); |
5584 | keyValue = NULL((void*)0); |
5585 | |
5586 | if (status != CAPS_SUCCESS0) return status; |
5587 | |
5588 | } else { |
5589 | |
5590 | printf("\tNo \"%s\" specified for Support tuple %s, going to use support name\n", keyWord, |
5591 | supportTuple[i].name); |
5592 | |
5593 | status = string_toStringDynamicArray(supportTuple[i].name, &numGroupName, &groupName); |
5594 | if (status != CAPS_SUCCESS0) return status; |
5595 | |
5596 | } |
5597 | |
5598 | // Determine how many point supports we have |
5599 | feaProblem->feaSupport[i].numGridID = 0; |
5600 | for (groupIndex = 0; groupIndex < numGroupName; groupIndex++) { |
5601 | |
5602 | status = get_mapAttrToIndexIndex(attrMap, (const char *) groupName[groupIndex], &attrIndex); |
5603 | |
5604 | if (status == CAPS_NOTFOUND-303) { |
5605 | printf("\tName %s not found in attribute map of capsConstraints!!!!\n", groupName[groupIndex]); |
5606 | continue; |
5607 | } else if (status != CAPS_SUCCESS0) return status; |
5608 | |
5609 | // Now lets loop through the grid to see how many grid points have the attrIndex |
5610 | for (nodeIndex = 0; nodeIndex < feaProblem->feaMesh.numNode; nodeIndex++ ) { |
5611 | |
5612 | if (feaProblem->feaMesh.node[nodeIndex].analysisType == MeshStructure) { |
5613 | feaData = (feaMeshDataStruct *) feaProblem->feaMesh.node[nodeIndex].analysisData; |
5614 | } else { |
5615 | continue; |
5616 | } |
5617 | |
5618 | if (feaData->constraintIndex == attrIndex) { |
5619 | |
5620 | feaProblem->feaSupport[i].numGridID += 1; |
5621 | |
5622 | // Allocate/Re-allocate grid ID array |
5623 | if (feaProblem->feaSupport[i].numGridID == 1) { |
5624 | feaProblem->feaSupport[i].gridIDSet = (int *) EG_alloc(feaProblem->feaSupport[i].numGridID*sizeof(int)); |
5625 | } else { |
5626 | feaProblem->feaSupport[i].gridIDSet = (int *) EG_reall(feaProblem->feaSupport[i].gridIDSet, |
5627 | feaProblem->feaSupport[i].numGridID*sizeof(int)); |
5628 | } |
5629 | |
5630 | if (feaProblem->feaSupport[i].gridIDSet == NULL((void*)0)) { |
5631 | status = string_freeArray(numGroupName, &groupName); |
5632 | if (status != CAPS_SUCCESS0) printf("Status %d during string_freeArray\n", status); |
5633 | |
5634 | return EGADS_MALLOC-4; |
5635 | } |
5636 | |
5637 | // Set grid ID value -> 1 bias |
5638 | feaProblem->feaSupport[i].gridIDSet[feaProblem->feaSupport[i].numGridID-1] = feaProblem->feaMesh.node[nodeIndex].nodeID; |
5639 | } |
5640 | } |
5641 | } |
5642 | |
5643 | status = string_freeArray(numGroupName, &groupName); |
5644 | if (status != CAPS_SUCCESS0) return status; |
5645 | groupName = NULL((void*)0); |
5646 | |
5647 | //Fill up support properties |
5648 | /*! \page feaSupport |
5649 | * |
5650 | * \if (MYSTRAN || NASTRAN || ASTROS) |
5651 | * <ul> |
5652 | * <li> <B>dofSupport = 0 </B> </li> <br> |
5653 | * Component numbers / degrees of freedom that will be supported (123 - zero translation in all three |
5654 | * directions). |
5655 | * </ul> |
5656 | * \endif |
5657 | */ |
5658 | keyWord = "dofSupport"; |
5659 | status = search_jsonDictionary( supportTuple[i].value, keyWord, &keyValue); |
5660 | if (status == CAPS_SUCCESS0) { |
5661 | |
5662 | status = string_toInteger(keyValue, &feaProblem->feaSupport[i].dofSupport); |
5663 | if (keyValue != NULL((void*)0)) { |
5664 | EG_free(keyValue); |
5665 | keyValue = NULL((void*)0); |
5666 | } |
5667 | if (status != CAPS_SUCCESS0) return status; |
5668 | } |
5669 | |
5670 | } else { |
5671 | |
5672 | /*! \page feaSupport |
5673 | * \section keyStringSupport Single Value String |
5674 | * |
5675 | * If "Value" is a string, the string value may correspond to an entry in a predefined support lookup |
5676 | * table. NOT YET IMPLEMENTED!!!! |
5677 | * |
5678 | */ |
5679 | |
5680 | // Call some look up table maybe? |
5681 | printf("\tError: Support tuple value is expected to be a JSON string\n"); |
5682 | return CAPS_BADVALUE-311; |
5683 | |
5684 | } |
5685 | } |
5686 | |
5687 | if (keyValue != NULL((void*)0)) { |
5688 | EG_free(keyValue); |
5689 | keyValue = NULL((void*)0); |
5690 | } |
5691 | |
5692 | printf("\tDone getting FEA supports\n"); |
5693 | return CAPS_SUCCESS0; |
5694 | } |
5695 | |
5696 | |
5697 | static int fea_setConnection(char *connectionName, |
5698 | feaConnectionTypeEnum connectionType, |
5699 | int connectionID, |
5700 | int elementOffSet, |
5701 | int dofDependent, |
5702 | double stiffnessConst, |
5703 | double dampingConst, |
5704 | double stressCoeff, |
5705 | int componentNumberStart, |
5706 | int componentNumberEnd, |
5707 | int srcNodeID, |
5708 | double masterWeight, |
5709 | int masterComponent, |
5710 | int numNode, int *node, |
5711 | int *numConnect, feaConnectionStruct *feaConnect[]) { // Out |
5712 | |
5713 | int status; |
5714 | int i; |
5715 | |
5716 | if (numNode == 0) { |
5717 | status = CAPS_BADVALUE-311; // Nothing to do |
5718 | goto cleanup; |
5719 | } |
5720 | |
5721 | if (connectionType == RigidBodyInterpolate) { |
5722 | *numConnect += 1; |
5723 | |
5724 | (*feaConnect) = (feaConnectionStruct *) EG_reall((*feaConnect),*numConnect*sizeof(feaConnectionStruct)); |
5725 | if ((*feaConnect) == NULL((void*)0)) { |
5726 | *numConnect = 0; |
5727 | status = EGADS_MALLOC-4; |
5728 | goto cleanup; |
5729 | } |
5730 | |
5731 | status = initiate_feaConnectionStruct(&(*feaConnect)[*numConnect-1]); |
5732 | if (status != CAPS_SUCCESS0) return status; |
5733 | |
5734 | (*feaConnect)[*numConnect-1].connectionID = connectionID; // ConnectionTuple index |
5735 | (*feaConnect)[*numConnect-1].connectionType = connectionType; |
5736 | |
5737 | (*feaConnect)[*numConnect-1].elementID = *numConnect + elementOffSet; |
5738 | |
5739 | (*feaConnect)[*numConnect-1].dofDependent = dofDependent; |
5740 | |
5741 | (*feaConnect)[*numConnect-1].connectivity[1] = srcNodeID; // Dependent |
5742 | (*feaConnect)[*numConnect-1].numMaster = numNode; // Independent |
5743 | |
5744 | (*feaConnect)[*numConnect-1].masterIDSet = (int *) EG_alloc(numNode*sizeof(int)); // [numMaster] |
5745 | if ((*feaConnect)[*numConnect-1].masterIDSet == NULL((void*)0)) { |
5746 | status = EGADS_MALLOC-4; |
5747 | goto cleanup; |
5748 | } |
5749 | (*feaConnect)[*numConnect-1].masterWeighting = (double *) EG_alloc(numNode*sizeof(double));; // [numMaster] |
5750 | if ((*feaConnect)[*numConnect-1].masterWeighting == NULL((void*)0)) { |
5751 | status = EGADS_MALLOC-4; |
5752 | goto cleanup; |
5753 | } |
5754 | |
5755 | (*feaConnect)[*numConnect-1].masterComponent =(int *) EG_alloc(numNode*sizeof(int));; // [numMaster] |
5756 | if ((*feaConnect)[*numConnect-1].masterComponent == NULL((void*)0)) { |
5757 | status = EGADS_MALLOC-4; |
5758 | goto cleanup; |
5759 | } |
5760 | |
5761 | //printf("\tMasters (%d)", numNode); |
5762 | // Master values; |
5763 | for (i = 0; i < numNode; i++) { |
5764 | // printf(" %d", node[i]); |
5765 | |
5766 | (*feaConnect)[*numConnect-1].masterIDSet[i] = node[i]; |
5767 | (*feaConnect)[*numConnect-1].masterWeighting[i] = masterWeight; |
5768 | (*feaConnect)[*numConnect-1].masterComponent[i] = masterComponent; |
5769 | } |
5770 | //printf("\n"); |
5771 | |
5772 | } else { // For all other types of connections create an individual connection - single pair of nodes |
5773 | |
5774 | (*feaConnect) = (feaConnectionStruct *) EG_reall((*feaConnect),(*numConnect+numNode)*sizeof(feaConnectionStruct)); |
5775 | if ((*feaConnect) == NULL((void*)0)) { |
5776 | *numConnect = 0; |
5777 | status = EGADS_MALLOC-4; |
5778 | goto cleanup; |
5779 | } |
5780 | |
5781 | for (i = 0; i < numNode; i++) { |
5782 | status = initiate_feaConnectionStruct(&(*feaConnect)[*numConnect+i]); |
5783 | if (status != CAPS_SUCCESS0) return status; |
5784 | } |
5785 | |
5786 | for (i = 0; i < numNode; i++) { |
5787 | |
5788 | *numConnect += 1; |
5789 | |
5790 | (*feaConnect)[*numConnect-1].name = (char *) EG_alloc((strlen(connectionName) + 1)*sizeof(char)); |
5791 | if ((*feaConnect)[*numConnect-1].name == NULL((void*)0)) return EGADS_MALLOC-4; |
5792 | |
5793 | memcpy((*feaConnect)[*numConnect-1].name, |
5794 | connectionName, |
5795 | strlen(connectionName)*sizeof(char)); |
5796 | (*feaConnect)[*numConnect-1].name[strlen(connectionName)] = '\0'; |
5797 | |
5798 | (*feaConnect)[*numConnect-1].connectionID = connectionID; // ConnectionTuple index |
5799 | |
5800 | (*feaConnect)[*numConnect-1].connectionType = connectionType; |
5801 | (*feaConnect)[*numConnect-1].elementID = *numConnect + elementOffSet; |
5802 | |
5803 | (*feaConnect)[*numConnect-1].connectivity[0] = srcNodeID; |
5804 | (*feaConnect)[*numConnect-1].connectivity[1] = node[i]; |
5805 | |
5806 | (*feaConnect)[*numConnect-1].dofDependent = dofDependent; |
5807 | (*feaConnect)[*numConnect-1].stiffnessConst = stiffnessConst; |
5808 | (*feaConnect)[*numConnect-1].dampingConst = dampingConst; |
5809 | (*feaConnect)[*numConnect-1].stressCoeff = stressCoeff; |
5810 | (*feaConnect)[*numConnect-1].componentNumberStart = componentNumberStart; |
5811 | (*feaConnect)[*numConnect-1].componentNumberEnd = componentNumberEnd; |
5812 | } |
5813 | } |
5814 | |
5815 | status = CAPS_SUCCESS0; |
5816 | goto cleanup; |
5817 | |
5818 | cleanup: |
5819 | if (status != CAPS_SUCCESS0) printf("\tPremature exit in fea_setConnection, status = %d\n", status); |
5820 | return status; |
5821 | } |
5822 | // Get the Connections properties from a capsTuple and create connections based on the mesh |
5823 | int fea_getConnection(int numConnectionTuple, |
5824 | capsTuple connectionTuple[], |
5825 | mapAttrToIndexStruct *attrMap, |
5826 | feaProblemStruct *feaProblem) { |
5827 | |
5828 | /*! \page feaConnection FEA Connection |
5829 | * Structure for the connection tuple = ("Connection Name", "Value"). |
5830 | * "Connection Name" defines the reference name to the capsConnect being specified and denotes the "source" node |
5831 | * for the connection. |
5832 | * The "Value" can either be a JSON String dictionary (see Section \ref jsonStringConnection) or a single string keyword |
5833 | * (see Section \ref keyStringConnection). |
5834 | */ |
5835 | |
5836 | int status; //Function return |
5837 | |
5838 | int i, groupIndex, nodeIndex, nodeIndexDest; // Indexing |
5839 | |
5840 | char *keyValue = NULL((void*)0); // Key values from tuple searches |
5841 | char *keyWord = NULL((void*)0); // Key words to find in the tuples |
5842 | |
5843 | int numGroupName = 0; |
5844 | char **groupName = NULL((void*)0); |
5845 | int attrIndex, attrIndexDest; |
5846 | |
5847 | // Values to set |
5848 | feaConnectionTypeEnum connectionType; |
5849 | int dofDependent = 0, componentNumberStart = 0, componentNumberEnd = 0; |
5850 | double stiffnessConst = 0.0, dampingConst = 0.0, stressCoeff = 0.0, mass = 0.0; |
5851 | |
5852 | double weighting=1; |
5853 | |
5854 | int glue = (int) false0, glueNumMaster = 5; |
5855 | double glueSearchRadius=0; |
5856 | |
5857 | feaMeshDataStruct *feaData, *feaDataDest; |
5858 | |
5859 | int numDestNode=0, *destNode=NULL((void*)0); |
5860 | |
5861 | // Destroy our support structures coming in if aren't 0 and NULL already |
5862 | if (feaProblem->feaConnect != NULL((void*)0)) { |
5863 | for (i = 0; i < feaProblem->numConnect; i++) { |
5864 | status = destroy_feaConnectionStruct(&feaProblem->feaConnect[i]); |
5865 | if (status != CAPS_SUCCESS0) return status; |
5866 | } |
5867 | } |
5868 | if (feaProblem->feaConnect != NULL((void*)0)) EG_free(feaProblem->feaConnect); |
5869 | feaProblem->feaConnect = NULL((void*)0); |
5870 | feaProblem->numConnect = 0; |
5871 | |
5872 | printf("\nGetting FEA connections.......\n"); |
5873 | |
5874 | printf("\tNumber of connection tuples - %d\n", numConnectionTuple); |
5875 | |
5876 | // Loop through tuples and fill out the support structures |
5877 | for (i = 0; i < numConnectionTuple; i++) { |
5878 | |
5879 | // Reset defaults |
5880 | dofDependent = componentNumberStart = componentNumberEnd = 0; |
5881 | stiffnessConst = dampingConst = stressCoeff = mass = 0.0; |
5882 | |
5883 | weighting=1; |
5884 | |
5885 | glue = (int) false0; |
5886 | glueNumMaster = 5; |
5887 | glueSearchRadius = 0; |
5888 | |
5889 | printf("\tConnection name - %s\n", connectionTuple[i].name ); |
5890 | |
5891 | // Look for connection name in connection map |
5892 | status = get_mapAttrToIndexIndex(attrMap, (const char *) connectionTuple[i].name, &attrIndex); |
5893 | if (status == CAPS_NOTFOUND-303) { |
5894 | printf("\tName %s not found in attribute map of capsConnect!!!!\n", connectionTuple[i].name); |
5895 | continue; |
5896 | } else if (status != CAPS_SUCCESS0) return status; |
5897 | |
5898 | // Do we have a json string? |
5899 | if (strncmp(connectionTuple[i].value, "{", 1) == 0) { |
5900 | |
5901 | /*! \page feaConnection |
5902 | * \section jsonStringConnection JSON String Dictionary |
5903 | * |
5904 | * If "Value" is JSON string dictionary |
5905 | * \if (MYSTRAN || NASTRAN || ASTROS) |
5906 | * (e.g. "Value" = {"dofDependent": 1, "propertyType": "RigidBody"}) |
5907 | * \endif |
5908 | * the following keywords ( = default values) may be used: |
5909 | * |
5910 | * |
5911 | * \if (MYSTRAN || NASTRAN) |
5912 | * <ul> |
5913 | * <li> <B>connectionType = RigidBody</B> </li> <br> |
5914 | * Type of connection to apply to a given capsConnect pair defined by "Connection Name" and the "groupName". |
5915 | * Options: Mass (scalar), Spring (scalar), Damper (scalar), RigidBody, RigidBodyInterpolate. |
5916 | * </ul> |
5917 | * \elseif (ASTROS) |
5918 | * <ul> |
5919 | * <li> <B>connectionType = RigidBody</B> </li> <br> |
5920 | * Type of connection to apply to a given capsConnect pair defined by "Connection Name" and the "groupName". |
5921 | * Options: Mass (scalar), Spring (scalar), RigidBody, RigidBodyInterpolate. |
5922 | * </ul> |
5923 | * \endif |
5924 | * |
5925 | */ |
5926 | // Get connection Type |
5927 | keyWord = "connectionType"; |
5928 | status = search_jsonDictionary( connectionTuple[i].value, keyWord, &keyValue); |
5929 | if (status == CAPS_SUCCESS0) { |
5930 | |
5931 | //{UnknownConnection, Mass, Spring, Damper, RigidBody} |
5932 | if (strcasecmp(keyValue, "\"Mass\"") == 0) connectionType = Mass; |
5933 | else if (strcasecmp(keyValue, "\"Spring\"") == 0) connectionType = Spring; |
5934 | else if (strcasecmp(keyValue, "\"Damper\"") == 0) connectionType = Damper; |
5935 | else if (strcasecmp(keyValue, "\"RigidBody\"") == 0) connectionType = RigidBody; |
5936 | else if (strcasecmp(keyValue, "\"RigidBodyInterpolate\"") == 0) connectionType = RigidBodyInterpolate; |
5937 | else { |
5938 | printf("\tUnrecognized \"%s\" specified (%s) for Connection tuple %s, current options are " |
5939 | "\"Mass, Spring, Damper, RigidBody, and RigidBodyInterpolate\"\n", keyWord, |
5940 | keyValue, |
5941 | connectionTuple[i].name); |
5942 | if (keyValue != NULL((void*)0)) { |
5943 | EG_free(keyValue); |
5944 | keyValue = NULL((void*)0); |
5945 | } |
5946 | |
5947 | return CAPS_NOTFOUND-303; |
5948 | } |
5949 | |
5950 | } else { |
5951 | |
5952 | printf("\tNo \"%s\" specified for Connection tuple %s, defaulting to RigidBody\n", keyWord, |
5953 | connectionTuple[i].name); |
5954 | connectionType = RigidBody; |
5955 | } |
5956 | |
5957 | /*! \page feaConnection |
5958 | * |
5959 | * \if (MYSTRAN || NASTRAN || ASTROS) |
5960 | * <ul> |
5961 | * <li> <B>dofDependent = 0 </B> </li> <br> |
5962 | * Component numbers / degrees of freedom of the dependent end of rigid body connections (ex. 123 - translation in all three |
5963 | * directions). |
5964 | * </ul> |
5965 | * \endif |
5966 | * |
5967 | */ |
5968 | keyWord = "dofDependent"; |
5969 | status = search_jsonDictionary( connectionTuple[i].value, keyWord, &keyValue); |
5970 | if (status == CAPS_SUCCESS0) { |
5971 | |
5972 | status = string_toInteger(keyValue, &dofDependent); |
5973 | if (keyValue != NULL((void*)0)) { |
5974 | EG_free(keyValue); |
5975 | keyValue = NULL((void*)0); |
5976 | } |
5977 | if (status != CAPS_SUCCESS0) return status; |
5978 | } |
5979 | |
5980 | |
5981 | /*! \page feaConnection |
5982 | * |
5983 | * \if (MYSTRAN || NASTRAN || ASTROS) |
5984 | * <ul> |
5985 | * <li> <B>componentNumberStart = 0 </B> </li> <br> |
5986 | * Component numbers / degrees of freedom of the starting point of the connection for mass, |
5987 | * spring, and damper elements (scalar) ( 0 <= Integer <= 6). |
5988 | * </ul> |
5989 | * \endif |
5990 | */ |
5991 | keyWord = "componentNumberStart"; |
5992 | status = search_jsonDictionary( connectionTuple[i].value, keyWord, &keyValue); |
5993 | if (status == CAPS_SUCCESS0) { |
5994 | |
5995 | status = string_toInteger(keyValue, &componentNumberStart); |
5996 | if (keyValue != NULL((void*)0)) { |
5997 | EG_free(keyValue); |
5998 | keyValue = NULL((void*)0); |
5999 | } |
6000 | if (status != CAPS_SUCCESS0) return status; |
6001 | } |
6002 | |
6003 | /*! \page feaConnection |
6004 | * |
6005 | * \if (MYSTRAN || NASTRAN || ASTROS) |
6006 | * <ul> |
6007 | * <li> <B>componentNumberEnd= 0 </B> </li> <br> |
6008 | * Component numbers / degrees of freedom of the ending point of the connection for mass, |
6009 | * spring, damper elements (scalar), and rigid body interpolative connection ( 0 <= Integer <= 6). |
6010 | * </ul> |
6011 | * \endif |
6012 | * |
6013 | */ |
6014 | keyWord = "componentNumberEnd"; |
6015 | status = search_jsonDictionary( connectionTuple[i].value, keyWord, &keyValue); |
6016 | if (status == CAPS_SUCCESS0) { |
6017 | |
6018 | status = string_toInteger(keyValue, &componentNumberEnd); |
6019 | if (keyValue != NULL((void*)0)) { |
6020 | EG_free(keyValue); |
6021 | keyValue = NULL((void*)0); |
6022 | } |
6023 | if (status != CAPS_SUCCESS0) return status; |
6024 | } |
6025 | |
6026 | /*! \page feaConnection |
6027 | * |
6028 | * \if (MYSTRAN || NASTRAN || ASTROS) |
6029 | * <ul> |
6030 | * <li> <B>stiffnessConst = 0.0 </B> </li> <br> |
6031 | * Stiffness constant of a spring element (scalar). |
6032 | * </ul> |
6033 | * \endif |
6034 | */ |
6035 | keyWord = "stiffnessConst"; |
6036 | status = search_jsonDictionary( connectionTuple[i].value, keyWord, &keyValue); |
6037 | if (status == CAPS_SUCCESS0) { |
6038 | |
6039 | status = string_toDouble(keyValue, &stiffnessConst); |
6040 | if (keyValue != NULL((void*)0)) { |
6041 | EG_free(keyValue); |
6042 | keyValue = NULL((void*)0); |
6043 | } |
6044 | if (status != CAPS_SUCCESS0) return status; |
6045 | } |
6046 | |
6047 | /*! \page feaConnection |
6048 | * |
6049 | * \if (MYSTRAN || NASTRAN || ASTROS) |
6050 | * <ul> |
6051 | * <li> <B>dampingConst = 0.0 </B> </li> <br> |
6052 | * Damping coefficient/constant of a spring or damping element (scalar). |
6053 | * </ul> |
6054 | * \endif |
6055 | */ |
6056 | keyWord = "dampingConst"; |
6057 | status = search_jsonDictionary( connectionTuple[i].value, keyWord, &keyValue); |
6058 | if (status == CAPS_SUCCESS0) { |
6059 | |
6060 | status = string_toDouble(keyValue, &dampingConst); |
6061 | if (keyValue != NULL((void*)0)) { |
6062 | EG_free(keyValue); |
6063 | keyValue = NULL((void*)0); |
6064 | } |
6065 | if (status != CAPS_SUCCESS0) return status; |
6066 | } |
6067 | |
6068 | /*! \page feaConnection |
6069 | * |
6070 | * \if (MYSTRAN || NASTRAN || ASTROS) |
6071 | * <ul> |
6072 | * <li> <B>stressCoeff = 0.0 </B> </li> <br> |
6073 | * Stress coefficient of a spring element (scalar). |
6074 | * </ul> |
6075 | * \endif |
6076 | */ |
6077 | keyWord = "stressCoeff"; |
6078 | status = search_jsonDictionary( connectionTuple[i].value, keyWord, &keyValue); |
6079 | if (status == CAPS_SUCCESS0) { |
6080 | |
6081 | status = string_toDouble(keyValue, &stressCoeff); |
6082 | if (keyValue != NULL((void*)0)) { |
6083 | EG_free(keyValue); |
6084 | keyValue = NULL((void*)0); |
6085 | } |
6086 | if (status != CAPS_SUCCESS0) return status; |
6087 | } |
6088 | |
6089 | /*! \page feaConnection |
6090 | * |
6091 | * \if (MYSTRAN || NASTRAN || ASTROS) |
6092 | * <ul> |
6093 | * <li> <B>mass = 0.0 </B> </li> <br> |
6094 | * Mass of a mass element (scalar). |
6095 | * </ul> |
6096 | * \endif |
6097 | */ |
6098 | keyWord = "mass"; |
6099 | status = search_jsonDictionary( connectionTuple[i].value, keyWord, &keyValue); |
6100 | if (status == CAPS_SUCCESS0) { |
6101 | |
6102 | status = string_toDouble(keyValue, &mass); |
6103 | if (keyValue != NULL((void*)0)) { |
6104 | EG_free(keyValue); |
6105 | keyValue = NULL((void*)0); |
6106 | } |
6107 | if (status != CAPS_SUCCESS0) return status; |
6108 | } |
6109 | |
6110 | /* \page feaConnection |
6111 | * |
6112 | * \if (MYSTRAN || NASTRAN || ASTROS) |
6113 | * <ul> |
6114 | * <li> <B>glue = False </B> </li> <br> |
6115 | * Turn on gluing for the connection. |
6116 | * </ul> |
6117 | * \endif |
6118 | */ |
6119 | keyWord = "glue"; |
6120 | status = search_jsonDictionary( connectionTuple[i].value, keyWord, &keyValue); |
6121 | if (status == CAPS_SUCCESS0) { |
6122 | |
6123 | status = string_toBoolean(keyValue, &glue); |
6124 | if (keyValue != NULL((void*)0)) { |
6125 | EG_free(keyValue); |
6126 | keyValue = NULL((void*)0); |
6127 | } |
6128 | if (status != CAPS_SUCCESS0) return status; |
6129 | } |
6130 | |
6131 | /* \page feaConnection |
6132 | * |
6133 | * \if (MYSTRAN || NASTRAN || ASTROS) |
6134 | * <ul> |
6135 | * <li> <B>glueNumMaster = 5 </B> </li> <br> |
6136 | * Maximum number of the masters for a glue connections. |
6137 | * </ul> |
6138 | * \endif |
6139 | */ |
6140 | keyWord = "glueNumMaster"; |
6141 | status = search_jsonDictionary( connectionTuple[i].value, keyWord, &keyValue); |
6142 | if (status == CAPS_SUCCESS0) { |
6143 | |
6144 | status = string_toInteger(keyValue, &glueNumMaster); |
6145 | if (keyValue != NULL((void*)0)) { |
6146 | EG_free(keyValue); |
6147 | keyValue = NULL((void*)0); |
6148 | } |
6149 | if (status != CAPS_SUCCESS0) return status; |
6150 | } |
6151 | |
6152 | /* \page feaConnection |
6153 | * |
6154 | * \if (MYSTRAN || NASTRAN || ASTROS) |
6155 | * <ul> |
6156 | * <li> <B>glueSearchRadius = 0 </B> </li> <br> |
6157 | * Search radius when looking for masters for a glue connections. |
6158 | * </ul> |
6159 | * \endif |
6160 | */ |
6161 | keyWord = "glueSearchRadius"; |
6162 | status = search_jsonDictionary( connectionTuple[i].value, keyWord, &keyValue); |
6163 | if (status == CAPS_SUCCESS0) { |
6164 | |
6165 | status = string_toDouble(keyValue, &glueSearchRadius); |
6166 | if (keyValue != NULL((void*)0)) { |
6167 | EG_free(keyValue); |
6168 | keyValue = NULL((void*)0); |
6169 | } |
6170 | if (status != CAPS_SUCCESS0) return status; |
6171 | } |
6172 | |
6173 | /*! \page feaConnection |
6174 | * |
6175 | * \if (MYSTRAN || NASTRAN || ASTROS) |
6176 | * <ul> |
6177 | * <li> <B>weighting = 1 </B> </li> <br> |
6178 | * Weighting factor for a rigid body interpolative connections. |
6179 | * </ul> |
6180 | * \endif |
6181 | */ |
6182 | keyWord = "weighting"; |
6183 | status = search_jsonDictionary( connectionTuple[i].value, keyWord, &keyValue); |
6184 | if (status == CAPS_SUCCESS0) { |
6185 | |
6186 | status = string_toDouble(keyValue, &weighting); |
6187 | if (keyValue != NULL((void*)0)) { |
6188 | EG_free(keyValue); |
6189 | keyValue = NULL((void*)0); |
6190 | } |
6191 | if (status != CAPS_SUCCESS0) return status; |
6192 | } |
6193 | |
6194 | /*! \page feaConnection |
6195 | * |
6196 | * \if (MYSTRAN || NASTRAN || ASTROS) |
6197 | * <ul> |
6198 | * <li> <B>groupName = "(no default)"</B> </li> <br> |
6199 | * Single or list of <c>capsConnect</c> names on which to connect the nodes found with the |
6200 | * tuple name ("Connection Name") to. (e.g. "Name1" or ["Name1","Name2",...]. |
6201 | * </ul> |
6202 | * \endif |
6203 | */ |
6204 | numGroupName = 0; |
6205 | keyWord = "groupName"; |
6206 | status = search_jsonDictionary( connectionTuple[i].value, keyWord, &keyValue); |
6207 | if (status == CAPS_SUCCESS0) { |
6208 | |
6209 | status = string_toStringDynamicArray(keyValue, &numGroupName, &groupName); |
6210 | if (keyValue != NULL((void*)0)) EG_free(keyValue); |
6211 | keyValue = NULL((void*)0); |
6212 | |
6213 | if (status != CAPS_SUCCESS0) return status; |
6214 | if (glue == (int) true1 && connectionType != RigidBodyInterpolate) { |
6215 | printf("\tInvalid connectionType while glue = True, setting glue to False!\n"); |
6216 | glue = (int) false0; |
6217 | } |
6218 | |
6219 | if (glue == (int) true1 && connectionType == RigidBodyInterpolate) { |
6220 | status = fea_glueMesh(&feaProblem->feaMesh, |
6221 | i+1, //connectionID |
6222 | connectionType, |
6223 | dofDependent, |
6224 | connectionTuple[i].name, |
6225 | numGroupName, |
6226 | groupName, |
6227 | attrMap, |
6228 | glueNumMaster, |
6229 | glueSearchRadius, |
6230 | &feaProblem->numConnect, |
6231 | &feaProblem->feaConnect); |
6232 | if (status != CAPS_SUCCESS0) return status; |
6233 | |
6234 | } else { |
6235 | |
6236 | |
6237 | destNode = (int *) EG_alloc(feaProblem->feaMesh.numNode*sizeof(int)); |
6238 | if (destNode == NULL((void*)0)) { |
6239 | (void) string_freeArray(numGroupName, &groupName); |
6240 | return EGADS_MALLOC-4; |
6241 | } |
6242 | |
6243 | // Find the "source" node in the mesh |
6244 | for (nodeIndex = 0; nodeIndex < feaProblem->feaMesh.numNode; nodeIndex++ ) { |
6245 | |
6246 | feaData = (feaMeshDataStruct *) feaProblem->feaMesh.node[nodeIndex].analysisData; |
6247 | |
6248 | // If "source" doesn't match - continue |
6249 | if (feaData->connectIndex != attrIndex) continue; |
6250 | |
6251 | numDestNode = 0; |
6252 | |
6253 | // Lets loop through the group names and create the connections |
6254 | for (groupIndex = 0; groupIndex < numGroupName; groupIndex++) { |
6255 | |
6256 | status = get_mapAttrToIndexIndex(attrMap, (const char *) groupName[groupIndex], &attrIndexDest); |
6257 | if (status == CAPS_NOTFOUND-303) { |
6258 | printf("\tName %s not found in attribute map of capsConnects!!!!\n", groupName[groupIndex]); |
6259 | continue; |
6260 | } else if (status != CAPS_SUCCESS0) { |
6261 | (void) string_freeArray(numGroupName, &groupName); |
6262 | AIM_FREE(destNode){ EG_free(destNode); destNode = ((void*)0); }; |
6263 | return status; |
6264 | } |
6265 | |
6266 | // Find the "destination" node in the mesh |
6267 | for (nodeIndexDest = 0; nodeIndexDest < feaProblem->feaMesh.numNode; nodeIndexDest++) { |
6268 | |
6269 | feaDataDest = (feaMeshDataStruct *) feaProblem->feaMesh.node[nodeIndexDest].analysisData; |
6270 | |
6271 | // If the "destination" doesn't match - continue |
6272 | if (feaDataDest->connectIndex != attrIndexDest) continue; |
6273 | |
6274 | destNode[numDestNode] = feaProblem->feaMesh.node[nodeIndexDest].nodeID; |
6275 | numDestNode += 1; |
6276 | } // End destination loop |
6277 | |
6278 | } // End group loop |
6279 | |
6280 | if (numDestNode <= 0) { |
6281 | printf("\tNo destination nodes found for connection %s\n", connectionTuple[i].name); |
6282 | } else { |
6283 | |
6284 | status = fea_setConnection(connectionTuple[i].name, |
6285 | connectionType, |
6286 | i+1, |
6287 | feaProblem->feaMesh.numElement, |
6288 | dofDependent, |
6289 | stiffnessConst, |
6290 | dampingConst, |
6291 | stressCoeff, |
6292 | componentNumberStart, |
6293 | componentNumberEnd, |
6294 | feaProblem->feaMesh.node[nodeIndex].nodeID, |
6295 | weighting, |
6296 | componentNumberEnd, |
6297 | numDestNode, destNode, |
6298 | &feaProblem->numConnect, |
6299 | &feaProblem->feaConnect); |
6300 | if (status != CAPS_SUCCESS0) { |
6301 | (void) string_freeArray(numGroupName, &groupName); |
6302 | if (destNode !=NULL((void*)0)) EG_free(destNode); |
6303 | return status; |
6304 | } |
6305 | } |
6306 | } // End source loop |
6307 | } // Glue ifelse |
6308 | |
6309 | if (destNode !=NULL((void*)0)) EG_free(destNode); |
6310 | destNode = NULL((void*)0); |
6311 | |
6312 | status = string_freeArray(numGroupName, &groupName); |
6313 | if (status != CAPS_SUCCESS0) return status; |
6314 | |
6315 | } else { |
6316 | printf("\tNo \"%s\" specified for Connection tuple %s!\n", keyWord, connectionTuple[i].name); |
6317 | } |
6318 | |
6319 | // Create automatic connections from the "capsConnectLink" tag |
6320 | printf("\tLooking for automatic connections from the use of capsConnectLink for %s\n", connectionTuple[i].name); |
6321 | |
6322 | destNode = (int *) EG_alloc(feaProblem->feaMesh.numNode*sizeof(int)); |
6323 | if (destNode == NULL((void*)0)) return EGADS_MALLOC-4; |
6324 | |
6325 | // Find the "source" node in the mesh |
6326 | for (nodeIndex = 0; nodeIndex < feaProblem->feaMesh.numNode; nodeIndex++ ) { |
6327 | |
6328 | feaData = (feaMeshDataStruct *) feaProblem->feaMesh.node[nodeIndex].analysisData; |
6329 | |
6330 | // If "source" doesn't match - continue |
6331 | if (feaData->connectIndex != attrIndex) continue; |
6332 | |
6333 | numDestNode = 0; |
6334 | // Find the "destination" node in the mesh |
6335 | for (nodeIndexDest = 0; nodeIndexDest < feaProblem->feaMesh.numNode; nodeIndexDest++) { |
6336 | |
6337 | feaDataDest = (feaMeshDataStruct *) feaProblem->feaMesh.node[nodeIndexDest].analysisData; |
6338 | |
6339 | // If the "destination" doesn't match - continue |
6340 | if (feaDataDest->connectLinkIndex != attrIndex) continue; |
6341 | |
6342 | destNode[numDestNode] = feaProblem->feaMesh.node[nodeIndexDest].nodeID; |
6343 | numDestNode += 1; |
6344 | } // End destination loop |
6345 | |
6346 | if (numDestNode > 0) { |
6347 | status = fea_setConnection(connectionTuple[i].name, |
6348 | connectionType, |
6349 | i+1, |
6350 | feaProblem->feaMesh.numElement, |
6351 | dofDependent, |
6352 | stiffnessConst, |
6353 | dampingConst, |
6354 | stressCoeff, |
6355 | componentNumberStart, |
6356 | componentNumberEnd, |
6357 | feaProblem->feaMesh.node[nodeIndex].nodeID, |
6358 | weighting, |
6359 | componentNumberEnd, |
6360 | numDestNode, destNode, |
6361 | &feaProblem->numConnect, |
6362 | &feaProblem->feaConnect); |
6363 | if (status != CAPS_SUCCESS0) { |
6364 | if (destNode !=NULL((void*)0)) EG_free(destNode); |
6365 | return status; |
6366 | } |
6367 | } |
6368 | |
6369 | if (numDestNode > 0) { |
6370 | printf("\t%d automatic connections were made for capsConnect %s (node id %d)\n", numDestNode, |
6371 | connectionTuple[i].name, |
6372 | feaProblem->feaMesh.node[nodeIndex].nodeID); |
6373 | } |
6374 | } // End source loop |
6375 | |
6376 | if (destNode !=NULL((void*)0)) EG_free(destNode); |
6377 | destNode = NULL((void*)0); |
6378 | |
6379 | } else { |
6380 | |
6381 | /*! \page feaConnection |
6382 | * \section keyStringConnection Single Value String |
6383 | * |
6384 | * If "Value" is a string, the string value may correspond to an entry in a predefined connection lookup |
6385 | * table. NOT YET IMPLEMENTED!!!! |
6386 | * |
6387 | */ |
6388 | |
6389 | // Call some look up table maybe? |
6390 | printf("\tError: Connection tuple value is expected to be a JSON string\n"); |
6391 | return CAPS_BADVALUE-311; |
6392 | |
6393 | } |
6394 | } |
6395 | |
6396 | if (keyValue != NULL((void*)0)) { |
6397 | EG_free(keyValue); |
6398 | keyValue = NULL((void*)0); |
6399 | } |
6400 | |
6401 | printf("\tDone getting FEA connections\n"); |
6402 | return CAPS_SUCCESS0; |
6403 | } |
6404 | |
6405 | #ifdef FEA_GETCONNECTIONORIG_DEPREICATE |
6406 | // Get the Connections properties from a capsTuple and create connections based on the mesh |
6407 | static int fea_getConnectionOrig(int numConnectionTuple, |
6408 | capsTuple connectionTuple[], |
6409 | mapAttrToIndexStruct *attrMap, |
6410 | feaProblemStruct *feaProblem) { |
6411 | |
6412 | /* \page feaConnection FEA Connection |
6413 | * Structure for the connection tuple = ("Connection Name", "Value"). |
6414 | * "Connection Name" defines the reference name to the capsConnect being specified and denotes the "source" node |
6415 | * for the connection. |
6416 | * The "Value" can either be a JSON String dictionary (see Section \ref jsonStringConnection) or a single string keyword |
6417 | * (see Section \ref keyStringConnection). |
6418 | */ |
6419 | |
6420 | int status; //Function return |
6421 | |
6422 | int i, groupIndex, nodeIndex, nodeIndexDest, counter = 0; // Indexing |
6423 | |
6424 | char *keyValue = NULL((void*)0); // Key values from tuple searches |
6425 | char *keyWord = NULL((void*)0); // Key words to find in the tuples |
6426 | |
6427 | int numGroupName = 0; |
6428 | char **groupName = NULL((void*)0); |
6429 | int attrIndex, attrIndexDest; |
6430 | |
6431 | // Values to set |
6432 | feaConnectionTypeEnum connectionType; |
6433 | int dofDependent = 0, componentNumberStart = 0, componentNumberEnd = 0; |
6434 | double stiffnessConst = 0.0, dampingConst = 0.0, stressCoeff = 0.0, mass = 0.0; |
6435 | |
6436 | feaMeshDataStruct *feaData, *feaDataDest; |
6437 | |
6438 | // Destroy our support structures coming in if aren't 0 and NULL already |
6439 | if (feaProblem->feaConnect != NULL((void*)0)) { |
6440 | for (i = 0; i < feaProblem->numConnect; i++) { |
6441 | status = destroy_feaConnectionStruct(&feaProblem->feaConnect[i]); |
6442 | if (status != CAPS_SUCCESS0) return status; |
6443 | } |
6444 | } |
6445 | if (feaProblem->feaConnect != NULL((void*)0)) EG_free(feaProblem->feaConnect); |
6446 | feaProblem->feaConnect = NULL((void*)0); |
6447 | feaProblem->numConnect = 0; |
6448 | |
6449 | printf("\nGetting FEA connections.......\n"); |
6450 | |
6451 | printf("\tNumber of connection tuples - %d\n", numConnectionTuple); |
6452 | |
6453 | // Loop through tuples and fill out the support structures |
6454 | for (i = 0; i < numConnectionTuple; i++) { |
6455 | |
6456 | // Reset defaults |
6457 | dofDependent = componentNumberStart = componentNumberEnd = 0; |
6458 | stiffnessConst = dampingConst = stressCoeff = mass = 0.0; |
6459 | |
6460 | printf("\tConnection name - %s\n", connectionTuple[i].name ); |
6461 | |
6462 | // Look for connection name in connection map |
6463 | status = get_mapAttrToIndexIndex(attrMap, (const char *) connectionTuple[i].name, &attrIndex); |
6464 | if (status == CAPS_NOTFOUND-303) { |
6465 | printf("\tName %s not found in attribute map of capsConnect!!!!\n", connectionTuple[i].name); |
6466 | continue; |
6467 | } else if (status != CAPS_SUCCESS0) return status; |
6468 | |
6469 | // Do we have a json string? |
6470 | if (strncmp(connectionTuple[i].value, "{", 1) == 0) { |
6471 | |
6472 | /* \page feaConnection |
6473 | * \section jsonStringConnection JSON String Dictionary |
6474 | * |
6475 | * If "Value" is JSON string dictionary |
6476 | * \if (MYSTRAN || NASTRAN || ASTROS) |
6477 | * (e.g. "Value" = {"dofDependent": 1, "propertyType": "RigidBody"}) |
6478 | * \endif |
6479 | * the following keywords ( = default values) may be used: |
6480 | * |
6481 | * |
6482 | * \if (MYSTRAN || NASTRAN) |
6483 | * <ul> |
6484 | * <li> <B>connectionType = RigidBody</B> </li> <br> |
6485 | * Type of connection to apply to a given capsConnect pair defined by "Connection Name" and the "groupName". |
6486 | * Options: Mass (scalar), Spring (scalar), Damper (scalar), RigidBody. |
6487 | * </ul> |
6488 | * \elseif (ASTROS) |
6489 | * <ul> |
6490 | * <li> <B>connectionType = RigidBody</B> </li> <br> |
6491 | * Type of connection to apply to a given capsConnect pair defined by "Connection Name" and the "groupName". |
6492 | * Options: Mass (scalar), Spring (scalar), RigidBody. |
6493 | * </ul> |
6494 | * \elseif ABAQUS |
6495 | * |
6496 | * Something else .... |
6497 | * |
6498 | * \else |
6499 | * <ul> |
6500 | * <li> <B>connectionType = RigidBody</B> </li> <br> |
6501 | * Type of connection to apply to a given capsConnect pair defined by "Connection Name" and the "groupName". |
6502 | * Options: Mass (scalar), Spring (scalar), Damper (scalar), RigidBody. |
6503 | * </ul> |
6504 | * \endif |
6505 | * |
6506 | */ |
6507 | |
6508 | // Get connection Type |
6509 | keyWord = "connectionType"; |
6510 | status = search_jsonDictionary( connectionTuple[i].value, keyWord, &keyValue); |
6511 | if (status == CAPS_SUCCESS0) { |
6512 | |
6513 | //{UnknownConnection, Mass, Spring, Damper, RigidBody} |
6514 | if (strcasecmp(keyValue, "\"Mass\"") == 0) connectionType = Mass; |
6515 | else if (strcasecmp(keyValue, "\"Spring\"") == 0) connectionType = Spring; |
6516 | else if (strcasecmp(keyValue, "\"Damper\"") == 0) connectionType = Damper; |
6517 | else if (strcasecmp(keyValue, "\"RigidBody\"") == 0) connectionType = RigidBody; |
6518 | else { |
6519 | printf("\tUnrecognized \"%s\" specified (%s) for Connection tuple %s, current options are " |
6520 | "\"Mass, Spring, Damper, and RigidBody\"\n", keyWord, |
6521 | keyValue, |
6522 | connectionTuple[i].name); |
6523 | if (keyValue != NULL((void*)0)) { |
6524 | EG_free(keyValue); |
6525 | keyValue = NULL((void*)0); |
6526 | } |
6527 | |
6528 | return CAPS_NOTFOUND-303; |
6529 | } |
6530 | |
6531 | } else { |
6532 | |
6533 | printf("\tNo \"%s\" specified for Connection tuple %s, defaulting to RigidBody\n", keyWord, |
6534 | connectionTuple[i].name); |
6535 | connectionType = RigidBody; |
6536 | } |
6537 | |
6538 | /* \page feaConnection |
6539 | * |
6540 | * \if (MYSTRAN || NASTRAN || ASTROS) |
6541 | * <ul> |
6542 | * <li> <B>dofDependent = 0 </B> </li> <br> |
6543 | * Component numbers / degrees of freedom of the dependent end of rigid body connections (ex. 123 - translation in all three |
6544 | * directions). |
6545 | * </ul> |
6546 | * \elseif ABAQUS |
6547 | * |
6548 | * Something else .... |
6549 | * |
6550 | * \else |
6551 | * <ul> |
6552 | * <li> <B>dofDependent = 0 </B> </li> <br> |
6553 | * Component numbers / degrees of freedom of the dependent end of rigid body connections (ex. 123 - translation in all three |
6554 | * directions). |
6555 | * </ul> |
6556 | * \endif |
6557 | * |
6558 | */ |
6559 | keyWord = "dofDependent"; |
6560 | status = search_jsonDictionary( connectionTuple[i].value, keyWord, &keyValue); |
6561 | if (status == CAPS_SUCCESS0) { |
6562 | |
6563 | status = string_toInteger(keyValue, &dofDependent); |
6564 | if (keyValue != NULL((void*)0)) { |
6565 | EG_free(keyValue); |
6566 | keyValue = NULL((void*)0); |
6567 | } |
6568 | if (status != CAPS_SUCCESS0) return status; |
6569 | } |
6570 | |
6571 | |
6572 | /* \page feaConnection |
6573 | * |
6574 | * \if (MYSTRAN || NASTRAN || ASTROS) |
6575 | * <ul> |
6576 | * <li> <B>componentNumberStart = 0 </B> </li> <br> |
6577 | * Component numbers / degrees of freedom of the starting point of the connection for mass, |
6578 | * spring, and damper elements (scalar) ( 0 <= Integer <= 6). |
6579 | * </ul> |
6580 | * \elseif ABAQUS |
6581 | * |
6582 | * Something else .... |
6583 | * |
6584 | * \else |
6585 | * <ul> |
6586 | * <li> <B>componentNumberStart = 0 </B> </li> <br> |
6587 | * Component numbers / degrees of freedom of the starting point of the connection for mass, |
6588 | * spring, and damper elements (scalar) ( 0 <= Integer <= 6). |
6589 | * </ul> |
6590 | * \endif |
6591 | * |
6592 | */ |
6593 | keyWord = "componentNumberStart"; |
6594 | status = search_jsonDictionary( connectionTuple[i].value, keyWord, &keyValue); |
6595 | if (status == CAPS_SUCCESS0) { |
6596 | |
6597 | status = string_toInteger(keyValue, &componentNumberStart); |
6598 | if (keyValue != NULL((void*)0)) { |
6599 | EG_free(keyValue); |
6600 | keyValue = NULL((void*)0); |
6601 | } |
6602 | if (status != CAPS_SUCCESS0) return status; |
6603 | } |
6604 | |
6605 | /* \page feaConnection |
6606 | * |
6607 | * \if (MYSTRAN || NASTRAN || ASTROS) |
6608 | * <ul> |
6609 | * <li> <B>componentNumberEnd= 0 </B> </li> <br> |
6610 | * Component numbers / degrees of freedom of the ending point of the connection for mass, |
6611 | * spring, and damper elements (scalar) ( 0 <= Integer <= 6). |
6612 | * </ul> |
6613 | * \elseif ABAQUS |
6614 | * |
6615 | * Something else .... |
6616 | * |
6617 | * \else |
6618 | * <ul> |
6619 | * <li> <B>componentNumberEnd = 0 </B> </li> <br> |
6620 | * Component numbers / degrees of freedom of the ending point of the connection for mass, |
6621 | * spring, and damper elements (scalar) ( 0 <= Integer <= 6). |
6622 | * </ul> |
6623 | * \endif |
6624 | * |
6625 | */ |
6626 | keyWord = "componentNumberEnd"; |
6627 | status = search_jsonDictionary( connectionTuple[i].value, keyWord, &keyValue); |
6628 | if (status == CAPS_SUCCESS0) { |
6629 | |
6630 | status = string_toInteger(keyValue, &componentNumberEnd); |
6631 | if (keyValue != NULL((void*)0)) { |
6632 | EG_free(keyValue); |
6633 | keyValue = NULL((void*)0); |
6634 | } |
6635 | if (status != CAPS_SUCCESS0) return status; |
6636 | } |
6637 | |
6638 | /* \page feaConnection |
6639 | * |
6640 | * \if (MYSTRAN || NASTRAN || ASTROS) |
6641 | * <ul> |
6642 | * <li> <B>stiffnessConst = 0.0 </B> </li> <br> |
6643 | * Stiffness constant of a spring element (scalar). |
6644 | * </ul> |
6645 | * \elseif ABAQUS |
6646 | * |
6647 | * Something else .... |
6648 | * |
6649 | * \else |
6650 | * <ul> |
6651 | * <li> <B>stiffnessConst = 0.00 </B> </li> <br> |
6652 | * Stiffness constant of a spring element (scalar). |
6653 | * </ul> |
6654 | * \endif |
6655 | * |
6656 | */ |
6657 | keyWord = "stiffnessConst"; |
6658 | status = search_jsonDictionary( connectionTuple[i].value, keyWord, &keyValue); |
6659 | if (status == CAPS_SUCCESS0) { |
6660 | |
6661 | status = string_toDouble(keyValue, &stiffnessConst); |
6662 | if (keyValue != NULL((void*)0)) { |
6663 | EG_free(keyValue); |
6664 | keyValue = NULL((void*)0); |
6665 | } |
6666 | if (status != CAPS_SUCCESS0) return status; |
6667 | } |
6668 | |
6669 | /* \page feaConnection |
6670 | * |
6671 | * \if (MYSTRAN || NASTRAN || ASTROS) |
6672 | * <ul> |
6673 | * <li> <B>dampingConst = 0.0 </B> </li> <br> |
6674 | * Damping coefficient/constant of a spring or damping element (scalar). |
6675 | * </ul> |
6676 | * \elseif ABAQUS |
6677 | * |
6678 | * Something else .... |
6679 | * |
6680 | * \else |
6681 | * <ul> |
6682 | * <li> <B>dampingConst = 0.0 </B> </li> <br> |
6683 | * Damping constant of a spring or damping element (scalar). |
6684 | * </ul> |
6685 | * \endif |
6686 | * |
6687 | */ |
6688 | keyWord = "dampingConst"; |
6689 | status = search_jsonDictionary( connectionTuple[i].value, keyWord, &keyValue); |
6690 | if (status == CAPS_SUCCESS0) { |
6691 | |
6692 | status = string_toDouble(keyValue, &dampingConst); |
6693 | if (keyValue != NULL((void*)0)) { |
6694 | EG_free(keyValue); |
6695 | keyValue = NULL((void*)0); |
6696 | } |
6697 | if (status != CAPS_SUCCESS0) return status; |
6698 | } |
6699 | |
6700 | /* \page feaConnection |
6701 | * |
6702 | * \if (MYSTRAN || NASTRAN || ASTROS) |
6703 | * <ul> |
6704 | * <li> <B>stressCoeff = 0.0 </B> </li> <br> |
6705 | * Stress coefficient of a spring element (scalar). |
6706 | * </ul> |
6707 | * \elseif ABAQUS |
6708 | * |
6709 | * Something else .... |
6710 | * |
6711 | * \else |
6712 | * <ul> |
6713 | * <li> <B>stressCoeff = 0.0 </B> </li> <br> |
6714 | * Stress coefficient of a spring element (scalar). |
6715 | * </ul> |
6716 | * \endif |
6717 | * |
6718 | */ |
6719 | keyWord = "stressCoeff"; |
6720 | status = search_jsonDictionary( connectionTuple[i].value, keyWord, &keyValue); |
6721 | if (status == CAPS_SUCCESS0) { |
6722 | |
6723 | status = string_toDouble(keyValue, &stressCoeff); |
6724 | if (keyValue != NULL((void*)0)) { |
6725 | EG_free(keyValue); |
6726 | keyValue = NULL((void*)0); |
6727 | } |
6728 | if (status != CAPS_SUCCESS0) return status; |
6729 | } |
6730 | |
6731 | /* \page feaConnection |
6732 | * |
6733 | * \if (MYSTRAN || NASTRAN || ASTROS) |
6734 | * <ul> |
6735 | * <li> <B>mass = 0.0 </B> </li> <br> |
6736 | * Mass of a mass element (scalar). |
6737 | * </ul> |
6738 | * \elseif ABAQUS |
6739 | * |
6740 | * Something else .... |
6741 | * |
6742 | * \else |
6743 | * <ul> |
6744 | * <li> <B>mass = 0.0 </B> </li> <br> |
6745 | * Mass of a mass element (scalar). |
6746 | * </ul> |
6747 | * \endif |
6748 | * |
6749 | */ |
6750 | keyWord = "mass"; |
6751 | status = search_jsonDictionary( connectionTuple[i].value, keyWord, &keyValue); |
6752 | if (status == CAPS_SUCCESS0) { |
6753 | |
6754 | status = string_toDouble(keyValue, &mass); |
6755 | if (keyValue != NULL((void*)0)) { |
6756 | EG_free(keyValue); |
6757 | keyValue = NULL((void*)0); |
6758 | } |
6759 | if (status != CAPS_SUCCESS0) return status; |
6760 | } |
6761 | |
6762 | /* \page feaConnection |
6763 | * |
6764 | * \if (MYSTRAN || NASTRAN || ASTROS) |
6765 | * <ul> |
6766 | * <li> <B>groupName = "(no default)"</B> </li> <br> |
6767 | * Single or list of <c>capsConnect</c> names on which to connect the nodes found with the |
6768 | * tuple name ("Connection Name") to. (e.g. "Name1" or ["Name1","Name2",...]. |
6769 | * </ul> |
6770 | * \elseif ABAQUS |
6771 | * |
6772 | * Something else .... |
6773 | * |
6774 | * \else |
6775 | * <ul> |
6776 | * <li> <B>groupName = "(no default)"</B> </li> <br> |
6777 | * Single or list of <c>capsConnect</c> names on which to connect the nodes found with the |
6778 | * tuple name ("Connection Name") to. (e.g. "Name1" or ["Name1","Name2",...]. |
6779 | * </ul> |
6780 | * \endif |
6781 | * |
6782 | */ |
6783 | numGroupName = 0; |
6784 | keyWord = "groupName"; |
6785 | status = search_jsonDictionary( connectionTuple[i].value, keyWord, &keyValue); |
6786 | if (status == CAPS_SUCCESS0) { |
6787 | |
6788 | status = string_toStringDynamicArray(keyValue, &numGroupName, &groupName); |
6789 | if (keyValue != NULL((void*)0)) EG_free(keyValue); |
6790 | keyValue = NULL((void*)0); |
6791 | |
6792 | if (status != CAPS_SUCCESS0) return status; |
6793 | |
6794 | // Lets loop through the group names and create the connections |
6795 | for (groupIndex = 0; groupIndex < numGroupName; groupIndex++) { |
6796 | |
6797 | status = get_mapAttrToIndexIndex(attrMap, (const char *) groupName[groupIndex], &attrIndexDest); |
6798 | if (status == CAPS_NOTFOUND-303) { |
6799 | printf("\tName %s not found in attribute map of capsConnects!!!!\n", groupName[groupIndex]); |
6800 | continue; |
6801 | } else if (status != CAPS_SUCCESS0) { |
6802 | (void) string_freeArray(numGroupName, &groupName); |
6803 | return status; |
6804 | } |
6805 | |
6806 | // Find the "source" node in the mesh |
6807 | for (nodeIndex = 0; nodeIndex < feaProblem->feaMesh.numNode; nodeIndex++ ) { |
6808 | |
6809 | feaData = (feaMeshDataStruct *) feaProblem->feaMesh.node[nodeIndex].analysisData; |
6810 | |
6811 | // If "source" doesn't match - continue |
6812 | if (feaData->connectIndex != attrIndex) continue; |
6813 | |
6814 | // Find the "destination" node in the mesh |
6815 | for (nodeIndexDest = 0; nodeIndexDest < feaProblem->feaMesh.numNode; nodeIndexDest++) { |
6816 | |
6817 | feaDataDest = (feaMeshDataStruct *) feaProblem->feaMesh.node[nodeIndexDest].analysisData; |
6818 | |
6819 | // If the "destination" doesn't match - continue |
6820 | if (feaDataDest->connectIndex != attrIndexDest) continue; |
6821 | |
6822 | feaProblem->numConnect += 1; |
6823 | |
6824 | if (feaProblem->numConnect == 1) { |
6825 | feaProblem->feaConnect = (feaConnectionStruct *) EG_alloc(sizeof(feaConnectionStruct)); |
6826 | } else { |
6827 | feaProblem->feaConnect = (feaConnectionStruct *) EG_reall(feaProblem->feaConnect , |
6828 | feaProblem->numConnect*sizeof(feaConnectionStruct)); |
6829 | } |
6830 | |
6831 | if (feaProblem->feaConnect == NULL((void*)0)) { |
6832 | feaProblem->numConnect = 0; |
6833 | (void) string_freeArray(numGroupName, &groupName); |
6834 | return EGADS_MALLOC-4; |
6835 | } |
6836 | |
6837 | status = initiate_feaConnectionStruct(&feaProblem->feaConnect[feaProblem->numConnect-1]); |
6838 | if (status != CAPS_SUCCESS0) return status; |
6839 | |
6840 | feaProblem->feaConnect[feaProblem->numConnect-1].name = (char *) EG_alloc((strlen(connectionTuple[i].name) + 1)*sizeof(char)); |
6841 | if (feaProblem->feaConnect[feaProblem->numConnect-1].name == NULL((void*)0)) { |
6842 | (void) string_freeArray(numGroupName, &groupName); |
6843 | return EGADS_MALLOC-4; |
6844 | } |
6845 | |
6846 | memcpy(feaProblem->feaConnect[feaProblem->numConnect-1].name, |
6847 | connectionTuple[i].name, |
6848 | strlen(connectionTuple[i].name)*sizeof(char)); |
6849 | feaProblem->feaConnect[feaProblem->numConnect-1].name[strlen(connectionTuple[i].name)] = '\0'; |
6850 | |
6851 | feaProblem->feaConnect[feaProblem->numConnect-1].connectionID = i+1; // ConnectionTuple index |
6852 | |
6853 | feaProblem->feaConnect[feaProblem->numConnect-1].connectionType = connectionType; |
6854 | feaProblem->feaConnect[feaProblem->numConnect-1].elementID = feaProblem->numConnect + feaProblem->feaMesh.numElement; |
6855 | feaProblem->feaConnect[feaProblem->numConnect-1].connectivity[0] = feaProblem->feaMesh.node[nodeIndex].nodeID; |
6856 | feaProblem->feaConnect[feaProblem->numConnect-1].connectivity[1] = feaProblem->feaMesh.node[nodeIndexDest].nodeID; |
6857 | |
6858 | feaProblem->feaConnect[feaProblem->numConnect-1].dofDependent = dofDependent; |
6859 | feaProblem->feaConnect[feaProblem->numConnect-1].stiffnessConst = stiffnessConst; |
6860 | feaProblem->feaConnect[feaProblem->numConnect-1].dampingConst = dampingConst; |
6861 | feaProblem->feaConnect[feaProblem->numConnect-1].stressCoeff = stressCoeff; |
6862 | feaProblem->feaConnect[feaProblem->numConnect-1].mass = mass; |
6863 | feaProblem->feaConnect[feaProblem->numConnect-1].componentNumberStart = componentNumberStart; |
6864 | feaProblem->feaConnect[feaProblem->numConnect-1].componentNumberEnd = componentNumberEnd; |
6865 | } // End destination loop |
6866 | } // End source loop |
6867 | } // End group loop |
6868 | |
6869 | status = string_freeArray(numGroupName, &groupName); |
6870 | if (status != CAPS_SUCCESS0) return status; |
6871 | |
6872 | } else { |
6873 | printf("\tNo \"%s\" specified for Connection tuple %s!\n", keyWord, |
6874 | connectionTuple[i].name); |
6875 | } |
6876 | |
6877 | |
6878 | // Create automatic connections from the "capsConnectLink" tag |
6879 | printf("\tLooking for automatic connections from the use of capsConnectLink for %s\n", connectionTuple[i].name); |
6880 | |
6881 | // Find the "source" node in the mesh |
6882 | for (nodeIndex = 0; nodeIndex < feaProblem->feaMesh.numNode; nodeIndex++ ) { |
6883 | |
6884 | feaData = (feaMeshDataStruct *) feaProblem->feaMesh.node[nodeIndex].analysisData; |
6885 | |
6886 | // If "source" doesn't match - continue |
6887 | if (feaData->connectIndex != attrIndex) continue; |
6888 | |
6889 | counter = 0; |
6890 | // Find the "destination" node in the mesh |
6891 | for (nodeIndexDest = 0; nodeIndexDest < feaProblem->feaMesh.numNode; nodeIndexDest++) { |
6892 | |
6893 | feaDataDest = (feaMeshDataStruct *) feaProblem->feaMesh.node[nodeIndexDest].analysisData; |
6894 | |
6895 | // If the "destination" doesn't match - continue |
6896 | if (feaDataDest->connectLinkIndex != attrIndex) continue; |
6897 | |
6898 | counter +=1; |
6899 | |
6900 | feaProblem->numConnect += 1; |
6901 | |
6902 | if (feaProblem->numConnect == 1) { |
6903 | feaProblem->feaConnect = (feaConnectionStruct *) EG_alloc(sizeof(feaConnectionStruct)); |
6904 | } else { |
6905 | feaProblem->feaConnect = (feaConnectionStruct *) EG_reall(feaProblem->feaConnect , |
6906 | feaProblem->numConnect*sizeof(feaConnectionStruct)); |
6907 | } |
6908 | |
6909 | if (feaProblem->feaConnect == NULL((void*)0)) { |
6910 | feaProblem->numConnect = 0; |
6911 | return EGADS_MALLOC-4; |
6912 | } |
6913 | |
6914 | feaProblem->feaConnect[feaProblem->numConnect-1].name = (char *) EG_alloc((strlen(connectionTuple[i].name) + 1)*sizeof(char)); |
6915 | if (feaProblem->feaConnect[feaProblem->numConnect-1].name == NULL((void*)0)) return EGADS_MALLOC-4; |
6916 | |
6917 | memcpy(feaProblem->feaConnect[feaProblem->numConnect-1].name, |
6918 | connectionTuple[i].name, |
6919 | strlen(connectionTuple[i].name)*sizeof(char)); |
6920 | feaProblem->feaConnect[feaProblem->numConnect-1].name[strlen(connectionTuple[i].name)] = '\0'; |
6921 | |
6922 | feaProblem->feaConnect[feaProblem->numConnect-1].connectionID = i+1; // ConnectionTuple index |
6923 | |
6924 | feaProblem->feaConnect[feaProblem->numConnect-1].connectionType = connectionType; |
6925 | feaProblem->feaConnect[feaProblem->numConnect-1].elementID = feaProblem->numConnect + feaProblem->feaMesh.numElement; |
6926 | feaProblem->feaConnect[feaProblem->numConnect-1].connectivity[0] = feaProblem->feaMesh.node[nodeIndex].nodeID; |
6927 | feaProblem->feaConnect[feaProblem->numConnect-1].connectivity[1] = feaProblem->feaMesh.node[nodeIndexDest].nodeID; |
6928 | |
6929 | feaProblem->feaConnect[feaProblem->numConnect-1].dofDependent = dofDependent; |
6930 | feaProblem->feaConnect[feaProblem->numConnect-1].stiffnessConst = stiffnessConst; |
6931 | feaProblem->feaConnect[feaProblem->numConnect-1].dampingConst = dampingConst; |
6932 | feaProblem->feaConnect[feaProblem->numConnect-1].stressCoeff = stressCoeff; |
6933 | feaProblem->feaConnect[feaProblem->numConnect-1].componentNumberStart = componentNumberStart; |
6934 | feaProblem->feaConnect[feaProblem->numConnect-1].componentNumberEnd = componentNumberEnd; |
6935 | } // End destination loop |
6936 | |
6937 | printf("\t%d automatic connections were made for capsConnect %s\n", counter, |
6938 | connectionTuple[i].name); |
6939 | } // End source loop |
6940 | } else { |
6941 | |
6942 | /* \page feaConnection |
6943 | * \section keyStringConnection Single Value String |
6944 | * |
6945 | * If "Value" is a string, the string value may correspond to an entry in a predefined connection lookup |
6946 | * table. NOT YET IMPLEMENTED!!!! |
6947 | * |
6948 | */ |
6949 | |
6950 | // Call some look up table maybe? |
6951 | printf("\tError: Connection tuple value is expected to be a JSON string\n"); |
6952 | return CAPS_BADVALUE-311; |
6953 | |
6954 | } |
6955 | } |
6956 | |
6957 | if (keyValue != NULL((void*)0)) { |
6958 | EG_free(keyValue); |
6959 | keyValue = NULL((void*)0); |
6960 | } |
6961 | |
6962 | printf("\tDone getting FEA connections\n"); |
6963 | return CAPS_SUCCESS0; |
6964 | } |
6965 | #endif |
6966 | |
6967 | // Get the load properties from a capsTuple |
6968 | int fea_getLoad(int numLoadTuple, |
6969 | capsTuple loadTuple[], |
6970 | mapAttrToIndexStruct *attrMap, |
6971 | feaProblemStruct *feaProblem) { |
6972 | |
6973 | /*! \page feaLoad FEA Load |
6974 | * Structure for the load tuple = ("Load Name", "Value"). |
6975 | * "Load Name" defines the reference name for the load being specified. |
6976 | * The "Value" can either be a JSON String dictionary (see Section \ref jsonStringLoad) or a single string keyword |
6977 | * (see Section \ref keyStringLoad). |
6978 | */ |
6979 | |
6980 | int status; //Function return |
6981 | |
6982 | int i, groupIndex, attrIndex, nodeIndex, elementIndex; // Indexing |
6983 | |
6984 | char *keyValue = NULL((void*)0); // Key values from tuple searches |
6985 | char *keyWord = NULL((void*)0); // Key words to find in the tuples |
6986 | |
6987 | int numGroupName = 0; |
6988 | char **groupName = NULL((void*)0); |
6989 | |
6990 | char *tempString = NULL((void*)0); // Temporary string holder |
6991 | |
6992 | feaMeshDataStruct *feaData; |
6993 | |
6994 | // Destroy our load structures coming in if aren't 0 and NULL already |
6995 | if (feaProblem->feaLoad != NULL((void*)0)) { |
6996 | for (i = 0; i < feaProblem->numLoad; i++) { |
6997 | status = destroy_feaLoadStruct(&feaProblem->feaLoad[i]); |
6998 | if (status != CAPS_SUCCESS0) return status; |
6999 | } |
7000 | } |
7001 | AIM_FREE(feaProblem->feaLoad){ EG_free(feaProblem->feaLoad); feaProblem->feaLoad = ( (void*)0); }; |
7002 | feaProblem->numLoad = 0; |
7003 | |
7004 | printf("\nGetting FEA loads.......\n"); |
7005 | |
7006 | feaProblem->numLoad = numLoadTuple; |
7007 | |
7008 | printf("\tNumber of loads - %d\n", feaProblem->numLoad); |
7009 | |
7010 | // Allocate loads |
7011 | if (feaProblem->numLoad > 0) { |
7012 | feaProblem->feaLoad = (feaLoadStruct *) EG_alloc(feaProblem->numLoad * sizeof(feaLoadStruct)); |
7013 | |
7014 | if (feaProblem->feaLoad == NULL((void*)0) ) return EGADS_MALLOC-4; |
7015 | } |
7016 | |
7017 | // Initiate loads to default values |
7018 | for (i = 0; i < feaProblem->numLoad; i++) { |
7019 | status = initiate_feaLoadStruct(&feaProblem->feaLoad[i]); |
7020 | if (status != CAPS_SUCCESS0) return status; |
7021 | } |
7022 | |
7023 | // Loop through tuples and fill out the load structures |
7024 | for (i = 0; i < feaProblem->numLoad; i++) { |
7025 | |
7026 | printf("\tLoad name - %s\n", loadTuple[i].name ); |
7027 | |
7028 | // Set load name to tuple attribute name |
7029 | feaProblem->feaLoad[i].name = (char *) EG_alloc((strlen(loadTuple[i].name) + 1)*sizeof(char)); |
7030 | if (feaProblem->feaLoad[i].name == NULL((void*)0)) return EGADS_MALLOC-4; |
7031 | |
7032 | memcpy(feaProblem->feaLoad[i].name, loadTuple[i].name, strlen(loadTuple[i].name)*sizeof(char)); |
7033 | feaProblem->feaLoad[i].name[strlen(loadTuple[i].name)] = '\0'; |
7034 | |
7035 | // Set load id -> 1 bias |
7036 | feaProblem->feaLoad[i].loadID = i+1; |
7037 | |
7038 | // Do we have a json string? |
7039 | if (strncmp(loadTuple[i].value, "{", 1) == 0) { |
7040 | //printf("JSON String - %s\n", constraintTuple[i].value); |
7041 | |
7042 | /*! \page feaLoad |
7043 | * \section jsonStringLoad JSON String Dictionary |
7044 | * |
7045 | * If "Value" is JSON string dictionary |
7046 | * \if (MYSTRAN || NASTRAN || HSM || ASTROS || ABAQUS || TACS) |
7047 | * (e.g. "Value" = {"groupName": "plate", "loadType": "Pressure", "pressureForce": 2000000.0}) |
7048 | * \endif |
7049 | * the following keywords ( = default values) may be used: |
7050 | * |
7051 | * \if (MYSTRAN || NASTRAN || ASTROS || TACS) |
7052 | * <ul> |
7053 | * <li> <B>loadType = "(no default)"</B> </li> <br> |
7054 | * Type of load. Options: "GridForce", "GridMoment", "Rotational", "Thermal", |
7055 | * "Pressure", "PressureDistribute", "PressureExternal", "TermalExternal", "Gravity". |
7056 | * </ul> |
7057 | * \elseif ABAQUS |
7058 | * <ul> |
7059 | * <li> <B>loadType = "(no default)"</B> </li> <br> |
7060 | * Type of load. Options: "Pressure", "Gravity". |
7061 | * </ul> |
7062 | * \elseif HSM |
7063 | * <ul> |
7064 | * <li> <B>loadType = "(no default)"</B> </li> <br> |
7065 | * Type of load. Options: "GridForce", "GridMoment", "LineForce", "LineMoment", "Rotational", |
7066 | * "Pressure", "PressureDistribute", "PressureExternal", "Gravity". |
7067 | * </ul> |
7068 | * \else |
7069 | * \endif |
7070 | * |
7071 | */ |
7072 | // Get load Type |
7073 | keyWord = "loadType"; |
7074 | status = search_jsonDictionary(loadTuple[i].value, keyWord, &keyValue); |
7075 | if (status == CAPS_SUCCESS0) { |
7076 | |
7077 | //{UnknownLoad, GridForce, GridMoment, Gravity, Pressure, Rotational, Thermal} |
7078 | if (strcasecmp(keyValue, "\"GridForce\"") == 0) feaProblem->feaLoad[i].loadType = GridForce; |
7079 | else if (strcasecmp(keyValue, "\"GridMoment\"") == 0) feaProblem->feaLoad[i].loadType = GridMoment; |
7080 | else if (strcasecmp(keyValue, "\"LineForce\"") == 0) feaProblem->feaLoad[i].loadType = LineForce; |
7081 | else if (strcasecmp(keyValue, "\"LineMoment\"") == 0) feaProblem->feaLoad[i].loadType = LineMoment; |
7082 | else if (strcasecmp(keyValue, "\"Rotational\"") == 0) feaProblem->feaLoad[i].loadType = Rotational; |
7083 | else if (strcasecmp(keyValue, "\"Thermal\"") == 0) feaProblem->feaLoad[i].loadType = Thermal; |
7084 | else if (strcasecmp(keyValue, "\"Pressure\"") == 0) feaProblem->feaLoad[i].loadType = Pressure; |
7085 | else if (strcasecmp(keyValue, "\"PressureDistribute\"") == 0) feaProblem->feaLoad[i].loadType = PressureDistribute; |
7086 | else if (strcasecmp(keyValue, "\"PressureExternal\"") == 0) feaProblem->feaLoad[i].loadType = PressureExternal; |
7087 | else if (strcasecmp(keyValue, "\"ThermalExternal\"") == 0) feaProblem->feaLoad[i].loadType = ThermalExternal; |
7088 | else if (strcasecmp(keyValue, "\"Gravity\"") == 0) feaProblem->feaLoad[i].loadType = Gravity; |
7089 | else { |
7090 | printf("\tUnrecognized \"%s\" specified (%s) for Load tuple %s\n", keyWord, |
7091 | keyValue, |
7092 | loadTuple[i].name); |
7093 | if (keyValue != NULL((void*)0)) EG_free(keyValue); |
7094 | return CAPS_NOTFOUND-303; |
7095 | } |
7096 | |
7097 | } else { |
7098 | printf("\t\"loadType\" variable not found in tuple %s, this is required input!!\n", loadTuple[i].name); |
7099 | |
7100 | if (keyValue != NULL((void*)0)) EG_free(keyValue); |
7101 | return status; |
7102 | } |
7103 | |
7104 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
7105 | |
7106 | // Get load node/element set |
7107 | /*! \page feaLoad |
7108 | * |
7109 | * \if (MYSTRAN || NASTRAN || HSM || ASTROS || ABAQUS || TACS) |
7110 | * <ul> |
7111 | * <li> <B>groupName = "(no default)"</B> </li> <br> |
7112 | * Single or list of <c>capsLoad</c> names on which to apply the load |
7113 | * (e.g. "Name1" or ["Name1","Name2",...]. If not provided, the load tuple name will be |
7114 | * used. |
7115 | * </ul> |
7116 | * \endif |
7117 | * |
7118 | */ |
7119 | keyWord = "groupName"; |
7120 | status = search_jsonDictionary( loadTuple[i].value, keyWord, &keyValue); |
7121 | if (status == CAPS_SUCCESS0) { |
7122 | |
7123 | status = string_toStringDynamicArray(keyValue, &numGroupName, &groupName); |
7124 | if (keyValue != NULL((void*)0)) EG_free(keyValue); |
7125 | keyValue = NULL((void*)0); |
7126 | |
7127 | if (status != CAPS_SUCCESS0) return status; |
7128 | |
7129 | } else { |
7130 | |
7131 | printf("\tNo \"%s\" specified for Load tuple %s, going to use load name\n", keyWord, |
7132 | loadTuple[i].name); |
7133 | |
7134 | status = string_toStringDynamicArray(loadTuple[i].name, &numGroupName, &groupName); |
7135 | if (status != CAPS_SUCCESS0) return status; |
7136 | |
7137 | } |
7138 | |
7139 | // Determine how many element/point loads we have |
7140 | feaProblem->feaLoad[i].numGridID = 0; |
7141 | feaProblem->feaLoad[i].numElementID = 0; |
7142 | for (groupIndex = 0; groupIndex < numGroupName; groupIndex++) { |
7143 | |
7144 | // Do nothing for PressureExternal, ThermalExternal, and Gravity loads |
7145 | if (feaProblem->feaLoad[i].loadType == PressureExternal) continue; |
7146 | if (feaProblem->feaLoad[i].loadType == ThermalExternal) continue; |
7147 | if (feaProblem->feaLoad[i].loadType == Gravity) continue; |
7148 | |
7149 | status = get_mapAttrToIndexIndex(attrMap, (const char *) groupName[groupIndex], &attrIndex); |
7150 | |
7151 | if (status == CAPS_NOTFOUND-303) { |
7152 | printf("\tName %s not found in attribute map of capsLoads!!!!\n", groupName[groupIndex]); |
7153 | continue; |
7154 | |
7155 | } else if (status != CAPS_SUCCESS0) { |
7156 | |
7157 | (void) string_freeArray(numGroupName, &groupName); |
7158 | return status; |
7159 | } |
7160 | |
7161 | //{UnknownLoad, GridForce, GridMoment, Gravity, Pressure, Rotational, Thermal} |
7162 | if (feaProblem->feaLoad[i].loadType == GridForce || |
7163 | feaProblem->feaLoad[i].loadType == GridMoment || |
7164 | feaProblem->feaLoad[i].loadType == Rotational || |
7165 | feaProblem->feaLoad[i].loadType == Thermal) { |
7166 | |
7167 | // Now lets loop through the grid to see how many grid points have the attrIndex |
7168 | for (nodeIndex = 0; nodeIndex < feaProblem->feaMesh.numNode; nodeIndex++ ) { |
7169 | |
7170 | if (feaProblem->feaMesh.node[nodeIndex].analysisType == MeshStructure) { |
7171 | feaData = (feaMeshDataStruct *) feaProblem->feaMesh.node[nodeIndex].analysisData; |
7172 | } else { |
7173 | continue; |
7174 | } |
7175 | |
7176 | if (feaData->loadIndex == attrIndex) { |
7177 | |
7178 | feaProblem->feaLoad[i].numGridID += 1; |
7179 | |
7180 | // Allocate/Re-allocate grid ID array |
7181 | if (feaProblem->feaLoad[i].numGridID == 1) { |
7182 | |
7183 | feaProblem->feaLoad[i].gridIDSet = (int *) EG_alloc(feaProblem->feaLoad[i].numGridID*sizeof(int)); |
7184 | |
7185 | } else { |
7186 | |
7187 | feaProblem->feaLoad[i].gridIDSet = (int *) EG_reall(feaProblem->feaLoad[i].gridIDSet, |
7188 | feaProblem->feaLoad[i].numGridID*sizeof(int)); |
7189 | } |
7190 | |
7191 | if (feaProblem->feaLoad[i].gridIDSet == NULL((void*)0)) { |
7192 | status = string_freeArray(numGroupName, &groupName); |
7193 | if (status == CAPS_SUCCESS0) return status; |
7194 | |
7195 | return EGADS_MALLOC-4; |
7196 | } |
7197 | |
7198 | // Set grid ID value -> 1 bias |
7199 | feaProblem->feaLoad[i].gridIDSet[feaProblem->feaLoad[i].numGridID-1] = feaProblem->feaMesh.node[nodeIndex].nodeID; |
7200 | |
7201 | //printf("GroupName = %s %d\n", groupName[groupIndex], feaProblem->feaMesh.node[nodeIndex].nodeID); |
7202 | |
7203 | } |
7204 | } |
7205 | |
7206 | } else if (feaProblem->feaLoad[i].loadType == LineForce || |
7207 | feaProblem->feaLoad[i].loadType == LineMoment ) { |
7208 | |
7209 | for (elementIndex = 0; elementIndex < feaProblem->feaMesh.numElement; elementIndex++) { |
7210 | |
7211 | if (feaProblem->feaMesh.element[elementIndex].elementType != Line) { |
7212 | continue; |
7213 | } |
7214 | |
7215 | if (feaProblem->feaMesh.element[elementIndex].analysisType == MeshStructure) { |
7216 | feaData = (feaMeshDataStruct *) feaProblem->feaMesh.element[elementIndex].analysisData; |
7217 | } else { |
7218 | continue; |
7219 | } |
7220 | |
7221 | if (feaData->loadIndex == attrIndex) { |
7222 | |
7223 | feaProblem->feaLoad[i].numElementID += 1; |
7224 | |
7225 | feaProblem->feaLoad[i].elementIDSet = (int *) EG_reall(feaProblem->feaLoad[i].elementIDSet, |
7226 | feaProblem->feaLoad[i].numElementID*sizeof(int)); |
7227 | |
7228 | if (feaProblem->feaLoad[i].elementIDSet == NULL((void*)0)) { |
7229 | string_freeArray(numGroupName, &groupName); |
7230 | return EGADS_MALLOC-4; |
7231 | } |
7232 | |
7233 | // Set element ID value -> 1 bias |
7234 | feaProblem->feaLoad[i].elementIDSet[feaProblem->feaLoad[i].numElementID-1] = feaProblem->feaMesh.element[elementIndex].elementID; |
7235 | } |
7236 | } |
7237 | |
7238 | } else if (feaProblem->feaLoad[i].loadType == LineForce || |
7239 | feaProblem->feaLoad[i].loadType == LineMoment || |
7240 | feaProblem->feaLoad[i].loadType == Pressure || |
7241 | feaProblem->feaLoad[i].loadType == PressureDistribute) { |
7242 | |
7243 | // Now lets loop through the elements to see how many elements have the attrIndex |
7244 | |
7245 | // Element types - CTRIA3, CTRIA3K, CQUAD4, CQUAD4K |
7246 | for (elementIndex = 0; elementIndex < feaProblem->feaMesh.numElement; elementIndex++) { |
7247 | |
7248 | if (feaProblem->feaMesh.element[elementIndex].elementType != Triangle && |
7249 | feaProblem->feaMesh.element[elementIndex].elementType != Triangle_6 && |
7250 | feaProblem->feaMesh.element[elementIndex].elementType != Quadrilateral && |
7251 | feaProblem->feaMesh.element[elementIndex].elementType != Quadrilateral_8) { |
7252 | continue; |
7253 | } |
7254 | |
7255 | if (feaProblem->feaMesh.element[elementIndex].analysisType == MeshStructure) { |
7256 | feaData = (feaMeshDataStruct *) feaProblem->feaMesh.element[elementIndex].analysisData; |
7257 | } else { |
7258 | continue; |
7259 | } |
7260 | |
7261 | if (feaData->loadIndex == attrIndex) { |
7262 | |
7263 | feaProblem->feaLoad[i].numElementID += 1; |
7264 | |
7265 | // Allocate/Re-allocate element ID array |
7266 | if (feaProblem->feaLoad[i].numElementID == 1) { |
7267 | |
7268 | feaProblem->feaLoad[i].elementIDSet = (int *) EG_alloc(feaProblem->feaLoad[i].numElementID*sizeof(int)); |
7269 | |
7270 | } else { |
7271 | |
7272 | feaProblem->feaLoad[i].elementIDSet = (int *) EG_reall(feaProblem->feaLoad[i].elementIDSet, |
7273 | feaProblem->feaLoad[i].numElementID*sizeof(int)); |
7274 | } |
7275 | |
7276 | if (feaProblem->feaLoad[i].elementIDSet == NULL((void*)0)) { |
7277 | string_freeArray(numGroupName, &groupName); |
7278 | return EGADS_MALLOC-4; |
7279 | } |
7280 | |
7281 | // Set element ID value -> 1 bias |
7282 | feaProblem->feaLoad[i].elementIDSet[feaProblem->feaLoad[i].numElementID-1] = feaProblem->feaMesh.element[elementIndex].elementID; |
7283 | } |
7284 | } |
7285 | |
7286 | } |
7287 | } // End attr search loop |
7288 | |
7289 | status = string_freeArray(numGroupName, &groupName); |
7290 | if (status != CAPS_SUCCESS0) return status; |
7291 | groupName = NULL((void*)0); |
7292 | |
7293 | // Free keyValue (just in case) |
7294 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
7295 | |
7296 | //Fill up load properties |
7297 | |
7298 | /*! \page feaLoad |
7299 | * |
7300 | * \if (MYSTRAN || NASTRAN || ASTROS || TACS) |
7301 | * <ul> |
7302 | * <li> <B>loadScaleFactor = 1.0 </B> </li> <br> |
7303 | * Scale factor to use when combining loads. |
7304 | * </ul> |
7305 | * \endif |
7306 | */ |
7307 | keyWord = "loadScaleFactor"; |
7308 | status = search_jsonDictionary( loadTuple[i].value, keyWord, &keyValue); |
7309 | if (status == CAPS_SUCCESS0) { |
7310 | |
7311 | status = string_toDouble(keyValue, &feaProblem->feaLoad[i].loadScaleFactor); |
7312 | if (keyValue != NULL((void*)0)) { |
7313 | EG_free(keyValue); |
7314 | keyValue = NULL((void*)0); |
7315 | } |
7316 | if (status != CAPS_SUCCESS0) return status; |
7317 | } |
7318 | |
7319 | /*! \page feaLoad |
7320 | * |
7321 | * \if (MYSTRAN || NASTRAN || HSM || ASTROS || TACS) |
7322 | * <ul> |
7323 | * <li> <B>forceScaleFactor = 0.0 </B> </li> <br> |
7324 | * Overall scale factor for the force for a "GridForce" load. |
7325 | * </ul> |
7326 | * \endif |
7327 | */ |
7328 | keyWord = "forceScaleFactor"; |
7329 | status = search_jsonDictionary( loadTuple[i].value, keyWord, &keyValue); |
7330 | if (status == CAPS_SUCCESS0) { |
7331 | |
7332 | status = string_toDouble(keyValue, &feaProblem->feaLoad[i].forceScaleFactor); |
7333 | if (keyValue != NULL((void*)0)) { |
7334 | EG_free(keyValue); |
7335 | keyValue = NULL((void*)0); |
7336 | } |
7337 | if (status != CAPS_SUCCESS0) return status; |
7338 | } |
7339 | |
7340 | /*! \page feaLoad |
7341 | * |
7342 | * \if (MYSTRAN || NASTRAN || HSM || ASTROS || TACS) |
7343 | * <ul> |
7344 | * <li> <B>directionVector = [0.0, 0.0, 0.0] </B> </li> <br> |
7345 | * X-, y-, and z- components of the force vector for a "GridForce", "GridMoment", or "Gravity" load. |
7346 | * </ul> |
7347 | * \elseif ABAQUS |
7348 | * <ul> |
7349 | * <li> <B>directionVector = [0.0, 0.0, 0.0] </B> </li> <br> |
7350 | * X-, y-, and z- components of the force vector for a "Gravity" load. |
7351 | * </ul> |
7352 | * \endif |
7353 | * |
7354 | */ |
7355 | keyWord = "directionVector"; |
7356 | status = search_jsonDictionary( loadTuple[i].value, keyWord, &keyValue); |
7357 | if (status == CAPS_SUCCESS0) { |
7358 | |
7359 | status = string_toDoubleArray(keyValue, |
7360 | (int) sizeof(feaProblem->feaLoad[i].directionVector)/sizeof(double), |
7361 | feaProblem->feaLoad[i].directionVector); |
7362 | if (keyValue != NULL((void*)0)) { |
7363 | EG_free(keyValue); |
7364 | keyValue = NULL((void*)0); |
7365 | } |
7366 | if (status != CAPS_SUCCESS0) return status; |
7367 | } |
7368 | |
7369 | /*! \page feaLoad |
7370 | * |
7371 | * \if (MYSTRAN || NASTRAN || HSM || ASTROS || TACS) |
7372 | * <ul> |
7373 | * <li> <B>momentScaleFactor = 0.0 </B> </li> <br> |
7374 | * Overall scale factor for the moment for a "GridMoment" load. |
7375 | * </ul> |
7376 | * \endif |
7377 | * |
7378 | */ |
7379 | keyWord = "momentScaleFactor"; |
7380 | status = search_jsonDictionary( loadTuple[i].value, keyWord, &keyValue); |
7381 | if (status == CAPS_SUCCESS0) { |
7382 | |
7383 | status = string_toDouble(keyValue, &feaProblem->feaLoad[i].momentScaleFactor); |
7384 | if (keyValue != NULL((void*)0)) { |
7385 | EG_free(keyValue); |
7386 | keyValue = NULL((void*)0); |
7387 | } |
7388 | if (status != CAPS_SUCCESS0) return status; |
7389 | } |
7390 | |
7391 | /*! \page feaLoad |
7392 | * |
7393 | * \if (MYSTRAN || NASTRAN || HSM || ASTROS || ABAQUS || TACS) |
7394 | * <ul> |
7395 | * <li> <B>gravityAcceleration = 0.0 </B> </li> <br> |
7396 | * Acceleration value for a "Gravity" load. |
7397 | * </ul> |
7398 | * \endif |
7399 | */ |
7400 | keyWord = "gravityAcceleration"; |
7401 | status = search_jsonDictionary( loadTuple[i].value, keyWord, &keyValue); |
7402 | if (status == CAPS_SUCCESS0) { |
7403 | |
7404 | status = string_toDouble(keyValue, &feaProblem->feaLoad[i].gravityAcceleration); |
7405 | if (keyValue != NULL((void*)0)) { |
7406 | EG_free(keyValue); |
7407 | keyValue = NULL((void*)0); |
7408 | } |
7409 | if (status != CAPS_SUCCESS0) return status; |
7410 | } |
7411 | |
7412 | /*! \page feaLoad |
7413 | * |
7414 | * \if MYSTRAN |
7415 | * <ul> |
7416 | * <li> <B>pressureForce = 0.0 </B> </li> <br> |
7417 | * Uniform pressure force for a "Pressure" load (only applicable to 2D elements). |
7418 | * </ul> |
7419 | * \elseif (NASTRAN || HSM || ASTROS || ABAQUS || TACS) |
7420 | * <ul> |
7421 | * <li> <B>pressureForce = 0.0 </B> </li> <br> |
7422 | * Uniform pressure force for a "Pressure" load. |
7423 | * </ul> |
7424 | * \endif |
7425 | */ |
7426 | keyWord = "pressureForce"; |
7427 | status = search_jsonDictionary( loadTuple[i].value, keyWord, &keyValue); |
7428 | if (status == CAPS_SUCCESS0) { |
7429 | |
7430 | status = string_toDouble(keyValue, &feaProblem->feaLoad[i].pressureForce); |
7431 | if (keyValue != NULL((void*)0)) { |
7432 | EG_free(keyValue); |
7433 | keyValue = NULL((void*)0); |
7434 | } |
7435 | if (status != CAPS_SUCCESS0) return status; |
7436 | } |
7437 | |
7438 | /*! \page feaLoad |
7439 | * |
7440 | * \if MYSTRAN |
7441 | * <ul> |
7442 | * <li> <B>pressureDistributeForce = [0.0, 0.0, 0.0, 0.0] </B> </li> <br> |
7443 | * Distributed pressure force for a "PressureDistribute" load (only applicable to 2D elements). The four values |
7444 | * correspond to the 4 (quadrilateral elements) or 3 (triangle elements) node locations. |
7445 | * </ul> |
7446 | * \elseif (NASTRAN || HSM || ASTROS || TACS) |
7447 | * <ul> |
7448 | * <li> <B>pressureDistributeForce = [0.0, 0.0, 0.0, 0.0] </B> </li> <br> |
7449 | * Distributed pressure force for a "PressureDistribute" load. The four values |
7450 | * correspond to the 4 (quadrilateral elements) or 3 (triangle elements) node locations. |
7451 | * </ul> |
7452 | * \endif |
7453 | */ |
7454 | keyWord = "pressureDistributeForce"; |
7455 | status = search_jsonDictionary( loadTuple[i].value, keyWord, &keyValue); |
7456 | if (status == CAPS_SUCCESS0) { |
7457 | |
7458 | status = string_toDoubleArray(keyValue, |
7459 | (int) sizeof(feaProblem->feaLoad[i].pressureDistributeForce)/sizeof(double), |
7460 | feaProblem->feaLoad[i].pressureDistributeForce); |
7461 | if (keyValue != NULL((void*)0)) { |
7462 | EG_free(keyValue); |
7463 | keyValue = NULL((void*)0); |
7464 | } |
7465 | if (status != CAPS_SUCCESS0) return status; |
7466 | } |
7467 | |
7468 | /*! \page feaLoad |
7469 | * |
7470 | * \if (MYSTRAN || NASTRAN || ASTROS || TACS) |
7471 | * <ul> |
7472 | * <li> <B>angularVelScaleFactor = 0.0 </B> </li> <br> |
7473 | * An overall scale factor for the angular velocity in revolutions per unit time for a "Rotational" load. |
7474 | * </ul> |
7475 | * \elseif HSM |
7476 | * <ul> |
7477 | * <li> <B>angularVelScaleFactor = 0.0 </B> </li> <br> |
7478 | * An overall scale factor for the angular velocity in revolutions per unit time for a "Rotational" load - applied in a global sense. |
7479 | * </ul> |
7480 | * \endif |
7481 | */ |
7482 | keyWord = "angularVelScaleFactor"; |
7483 | status = search_jsonDictionary( loadTuple[i].value, keyWord, &keyValue); |
7484 | if (status == CAPS_SUCCESS0) { |
7485 | |
7486 | status = string_toDouble(keyValue, &feaProblem->feaLoad[i].angularVelScaleFactor); |
7487 | if (keyValue != NULL((void*)0)) { |
7488 | EG_free(keyValue); |
7489 | keyValue = NULL((void*)0); |
7490 | } |
7491 | if (status != CAPS_SUCCESS0) return status; |
7492 | } |
7493 | |
7494 | /*! \page feaLoad |
7495 | * |
7496 | * \if (MYSTRAN || NASTRAN || ASTROS || TACS) |
7497 | * <ul> |
7498 | * <li> <B>angularAccScaleFactor = 0.0 </B> </li> <br> |
7499 | * An overall scale factor for the angular acceleration in revolutions per unit time squared for a "Rotational" load. |
7500 | * </ul> |
7501 | * \elseif HSM |
7502 | * <ul> |
7503 | * <li> <B>angularAccScaleFactor = 0.0 </B> </li> <br> |
7504 | * An overall scale factor for the angular acceleration in revolutions per unit time squared for a "Rotational" load - applied in a global sense. |
7505 | * </ul> |
7506 | * \endif |
7507 | */ |
7508 | keyWord = "angularAccScaleFactor"; |
7509 | status = search_jsonDictionary( loadTuple[i].value, keyWord, &keyValue); |
7510 | if (status == CAPS_SUCCESS0) { |
7511 | |
7512 | status = string_toDouble(keyValue, &feaProblem->feaLoad[i].angularAccScaleFactor); |
7513 | if (keyValue != NULL((void*)0)) { |
7514 | EG_free(keyValue); |
7515 | keyValue = NULL((void*)0); |
7516 | } |
7517 | if (status != CAPS_SUCCESS0) return status; |
7518 | } |
7519 | |
7520 | /*! \page feaLoad |
7521 | * |
7522 | * \if (MYSTRAN || NASTRAN || ASTROS || TACS) |
7523 | * <ul> |
7524 | * <li> <B>coordinateSystem = "(no default)" </B> </li> <br> |
7525 | * Name of coordinate system in which defined force components are in reference to. If no value |
7526 | * is provided the global system is assumed. |
7527 | * </ul> |
7528 | * \endif |
7529 | * |
7530 | */ |
7531 | keyWord = "coordinateSystem"; |
7532 | status = search_jsonDictionary( loadTuple[i].value, keyWord, &keyValue); |
7533 | if (status == CAPS_SUCCESS0) { |
7534 | |
7535 | tempString = string_removeQuotation(keyValue); |
7536 | |
7537 | for (attrIndex = 0; attrIndex < feaProblem->numCoordSystem; attrIndex++) { |
7538 | |
7539 | if (strcasecmp(tempString, feaProblem->feaCoordSystem[attrIndex].name) == 0) { |
7540 | feaProblem->feaLoad[i].coordSystemID = feaProblem->feaCoordSystem[attrIndex].coordSystemID; |
7541 | break; |
7542 | } |
7543 | } |
7544 | |
7545 | if (feaProblem->feaLoad[i].coordSystemID == 0) { |
7546 | printf("\tCoordinate system %s not found, defaulting to global system!!", keyValue); |
7547 | } |
7548 | |
7549 | if (keyValue != NULL((void*)0)) { |
7550 | EG_free(keyValue); |
7551 | keyValue = NULL((void*)0); |
7552 | } |
7553 | |
7554 | if (tempString != NULL((void*)0)) { |
7555 | EG_free(tempString); |
7556 | tempString = NULL((void*)0); |
7557 | } |
7558 | } |
7559 | |
7560 | |
7561 | /*! \page feaLoad |
7562 | * |
7563 | * \if (MYSTRAN || NASTRAN || ASTROS || TACS) |
7564 | * <ul> |
7565 | * <li> <B>temperature = 0.0 </B> </li> <br> |
7566 | * Temperature at a given node for a "Temperature" load. |
7567 | * </ul> |
7568 | * \endif |
7569 | */ |
7570 | keyWord = "temperature"; |
7571 | status = search_jsonDictionary( loadTuple[i].value, keyWord, &keyValue); |
7572 | if (status == CAPS_SUCCESS0) { |
7573 | |
7574 | status = string_toDouble(keyValue, &feaProblem->feaLoad[i].temperature); |
7575 | if (keyValue != NULL((void*)0)) { |
7576 | EG_free(keyValue); |
7577 | keyValue = NULL((void*)0); |
7578 | } |
7579 | if (status != CAPS_SUCCESS0) return status; |
7580 | } |
7581 | |
7582 | /*! \page feaLoad |
7583 | * |
7584 | * \if (MYSTRAN || NASTRAN || ASTROS || TACS) |
7585 | * <ul> |
7586 | * <li> <B>temperatureDefault = 0.0 </B> </li> <br> |
7587 | * Default temperature at a node not explicitly being used for a "Temperature" load. |
7588 | * </ul> |
7589 | * \endif |
7590 | */ |
7591 | keyWord = "temperatureDefault"; |
7592 | status = search_jsonDictionary( loadTuple[i].value, keyWord, &keyValue); |
7593 | if (status == CAPS_SUCCESS0) { |
7594 | |
7595 | status = string_toDouble(keyValue, &feaProblem->feaLoad[i].temperatureDefault); |
7596 | if (keyValue != NULL((void*)0)) { |
7597 | EG_free(keyValue); |
7598 | keyValue = NULL((void*)0); |
7599 | } |
7600 | if (status != CAPS_SUCCESS0) return status; |
7601 | } |
7602 | |
7603 | |
7604 | } else { // if not a JSON string search |
7605 | |
7606 | /*! \page feaLoad |
7607 | * \section keyStringLoad Single Value String |
7608 | * |
7609 | * If "Value" is a string, the string value may correspond to an entry in a predefined load lookup |
7610 | * table. NOT YET IMPLEMENTED!!!! |
7611 | * |
7612 | */ |
7613 | |
7614 | // Call some look up table maybe? |
7615 | printf("\tError: Load tuple value is expected to be a JSON string\n"); |
7616 | return CAPS_BADVALUE-311; |
7617 | } |
7618 | } |
7619 | |
7620 | /// Free keyValue and tempString (just in case) |
7621 | if (keyValue != NULL((void*)0)) EG_free(keyValue); |
7622 | |
7623 | if (tempString != NULL((void*)0)) EG_free(tempString); |
7624 | |
7625 | printf("\tDone getting FEA loads\n"); |
7626 | |
7627 | return CAPS_SUCCESS0; |
7628 | } |
7629 | |
7630 | // Get the analysis properties from a capsTuple |
7631 | int fea_getAnalysis(int numAnalysisTuple, |
7632 | capsTuple analysisTuple[], |
7633 | feaProblemStruct *feaProblem) { |
7634 | |
7635 | /*! \page feaAnalysis FEA Analysis |
7636 | * Structure for the analysis tuple = (`Analysis Name', `Value'). |
7637 | * 'Analysis Name' defines the reference name for the analysis being specified. |
7638 | * The "Value" can either be a JSON String dictionary (see Section \ref jsonStringAnalysis) or a single string keyword |
7639 | * (see Section \ref keyStringAnalysis). |
7640 | */ |
7641 | |
7642 | int status; //Function return |
7643 | |
7644 | int i, j, groupIndex, attrIndex; // Indexing |
7645 | |
7646 | |
7647 | char *keyValue = NULL((void*)0); |
7648 | char *keyWord = NULL((void*)0); |
7649 | |
7650 | char *tempString = NULL((void*)0); |
7651 | |
7652 | char **groupName = NULL((void*)0); |
7653 | int numGroupName = 0; |
7654 | |
7655 | int tempInt=0; // Temporary integer |
7656 | |
7657 | // Destroy our analysis structures coming in if aren't 0 and NULL already |
7658 | if (feaProblem->feaAnalysis != NULL((void*)0)) { |
7659 | for (i = 0; i < feaProblem->numAnalysis; i++) { |
7660 | status = destroy_feaAnalysisStruct(&feaProblem->feaAnalysis[i]); |
7661 | if (status != CAPS_SUCCESS0) return status; |
7662 | } |
7663 | } |
7664 | |
7665 | if (feaProblem->feaAnalysis != NULL((void*)0)) EG_free(feaProblem->feaAnalysis); |
7666 | feaProblem->feaAnalysis = NULL((void*)0); |
7667 | feaProblem->numAnalysis = 0; |
7668 | |
7669 | printf("\nGetting FEA analyses.......\n"); |
7670 | |
7671 | feaProblem->numAnalysis = numAnalysisTuple; |
7672 | |
7673 | printf("\tNumber of analyses - %d\n", feaProblem->numAnalysis); |
7674 | |
7675 | if (feaProblem->numAnalysis > 0) { |
7676 | feaProblem->feaAnalysis = (feaAnalysisStruct *) EG_alloc(feaProblem->numAnalysis * sizeof(feaAnalysisStruct)); |
7677 | } else { |
7678 | printf("\tNumber of analysis values in input tuple is 0\n"); |
7679 | return CAPS_NOTFOUND-303; |
7680 | } |
7681 | |
7682 | for (i = 0; i < feaProblem->numAnalysis; i++) { |
7683 | status = initiate_feaAnalysisStruct(&feaProblem->feaAnalysis[i]); |
7684 | if (status != CAPS_SUCCESS0) return status; |
7685 | } |
7686 | |
7687 | for (i = 0; i < feaProblem->numAnalysis; i++) { |
7688 | |
7689 | printf("\tAnalysis name - %s\n", analysisTuple[i].name); |
7690 | |
7691 | feaProblem->feaAnalysis[i].name = (char *) EG_alloc(((strlen(analysisTuple[i].name)) + 1)*sizeof(char)); |
7692 | if (feaProblem->feaAnalysis[i].name == NULL((void*)0)) return EGADS_MALLOC-4; |
7693 | |
7694 | memcpy(feaProblem->feaAnalysis[i].name, analysisTuple[i].name, strlen(analysisTuple[i].name)*sizeof(char)); |
7695 | feaProblem->feaAnalysis[i].name[strlen(analysisTuple[i].name)] = '\0'; |
7696 | |
7697 | feaProblem->feaAnalysis[i].analysisID = i + 1; |
7698 | |
7699 | // Do we have a json string? |
7700 | if (strncmp(analysisTuple[i].value, "{", 1) == 0) { |
7701 | //printf("JSON String - %s\n", analysisTuple[i].value); |
7702 | |
7703 | /*! \page feaAnalysis |
7704 | * \section jsonStringAnalysis JSON String Dictionary |
7705 | * |
7706 | * If "Value" is JSON string dictionary |
7707 | * \if (MYSTRAN || NASTRAN || ASTROS || ABAQUS) |
7708 | * (e.g. "Value" = {"numDesiredEigenvalue": 10, "eigenNormaliztion": "MASS", "numEstEigenvalue": 1, |
7709 | * "extractionMethod": "GIV", "frequencyRange": [0, 10000]}) |
7710 | * \endif |
7711 | * the following keywords ( = default values) may be used: |
7712 | * |
7713 | * \if MYSTRAN |
7714 | * <ul> |
7715 | * <li> <B>analysisType = "Modal"</B> </li> <br> |
7716 | * Type of load. Options: "Modal", "Static". |
7717 | * </ul> |
7718 | * \elseif (NASTRAN || ASTROS) |
7719 | * <ul> |
7720 | * <li> <B>analysisType = "Modal"</B> </li> <br> |
7721 | * Type of load. Options: "Modal", "Static", "AeroelasticTrim", "AeroelasticFlutter" |
7722 | * Note: "AeroelasticStatic" is still supported but refers to "AeroelasticTrim" |
7723 | * Note: "Optimization" and "StaticOpt" are not valid - Optimization is initialized by the Analysis_Type AIM Input |
7724 | * </ul> |
7725 | * \elseif ABAQUS |
7726 | * <ul> |
7727 | * <li> <B>analysisType = "Modal"</B> </li> <br> |
7728 | * Type of load. Options: "Modal", "Static" |
7729 | * </ul> |
7730 | * \endif |
7731 | * |
7732 | */ |
7733 | // Get analysis Type |
7734 | keyWord = "analysisType"; |
7735 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
7736 | if (status == CAPS_SUCCESS0) { |
7737 | |
7738 | //{UnknownAnalysis, Modal, Static} |
7739 | if (strcasecmp(keyValue, "\"Modal\"") == 0) feaProblem->feaAnalysis[i].analysisType = Modal; |
7740 | else if (strcasecmp(keyValue, "\"Static\"") == 0) feaProblem->feaAnalysis[i].analysisType = Static; |
7741 | else if (strcasecmp(keyValue, "\"StaticOpt\"") == 0) feaProblem->feaAnalysis[i].analysisType = Optimization; |
7742 | else if (strcasecmp(keyValue, "\"Optimization\"") == 0) feaProblem->feaAnalysis[i].analysisType = Optimization; |
7743 | else if (strcasecmp(keyValue, "\"AeroelasticTrim\"") == 0) feaProblem->feaAnalysis[i].analysisType = AeroelasticTrim; |
7744 | else if (strcasecmp(keyValue, "\"AeroelasticStatic\"") == 0) feaProblem->feaAnalysis[i].analysisType = AeroelasticTrim; |
7745 | else if (strcasecmp(keyValue, "\"AeroelasticFlutter\"") == 0) feaProblem->feaAnalysis[i].analysisType = AeroelasticFlutter; |
7746 | else { |
7747 | |
7748 | printf("\tUnrecognized \"%s\" specified (%s) for Analysis tuple %s, defaulting to \"Modal\"\n", keyWord, |
7749 | keyValue, |
7750 | analysisTuple[i].name); |
7751 | feaProblem->feaAnalysis[i].analysisType = Modal; |
7752 | } |
7753 | |
7754 | } else { |
7755 | |
7756 | printf("\tNo \"%s\" specified for Analysis tuple %s, defaulting to \"Modal\"\n", keyWord, analysisTuple[i].name); |
7757 | |
7758 | feaProblem->feaAnalysis[i].analysisType = Modal; |
7759 | } |
7760 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
7761 | |
7762 | // Get loads to be applied for a given analysis |
7763 | |
7764 | /*! \page feaAnalysis |
7765 | * |
7766 | * \if (MYSTRAN || NASTRAN || ASTROS || ABAQUS) |
7767 | * <ul> |
7768 | * <li> <B>analysisLoad = "(no default)"</B> </li> <br> |
7769 | * Single or list of "Load Name"s defined in \ref feaLoad in which to use for the analysis (e.g. "Name1" or ["Name1","Name2",...]. |
7770 | * </ul> |
7771 | * \endif |
7772 | */ |
7773 | keyWord = "analysisLoad"; |
7774 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
7775 | if (status == CAPS_SUCCESS0) { |
7776 | |
7777 | status = string_toStringDynamicArray(keyValue, &numGroupName, &groupName); |
7778 | if (keyValue != NULL((void*)0)) { |
7779 | EG_free(keyValue); |
7780 | keyValue = NULL((void*)0); |
7781 | } |
7782 | |
7783 | if (status != CAPS_SUCCESS0) return status; |
7784 | |
7785 | feaProblem->feaAnalysis[i].numLoad = 0; |
7786 | for (groupIndex = 0; groupIndex < numGroupName; groupIndex++) { |
7787 | |
7788 | for (attrIndex = 0; attrIndex < feaProblem->numLoad; attrIndex++) { |
7789 | |
7790 | if (strcasecmp(feaProblem->feaLoad[attrIndex].name, groupName[groupIndex]) == 0) { |
7791 | |
7792 | // if (feaProblem->feaLoad[attrIndex].loadType == Thermal) { |
7793 | // printf("Combining Thermal loads in a subcase isn't supported yet!\n"); |
7794 | // status = string_freeArray(numGroupName, &groupName); |
7795 | // if (status != CAPS_SUCCESS) return status; |
7796 | // groupName = NULL; |
7797 | // return CAPS_BADVALUE; |
7798 | // } |
7799 | |
7800 | feaProblem->feaAnalysis[i].numLoad += 1; |
7801 | |
7802 | if (feaProblem->feaAnalysis[i].numLoad == 1) { |
7803 | |
7804 | feaProblem->feaAnalysis[i].loadSetID = (int *) EG_alloc(feaProblem->feaAnalysis[i].numLoad *sizeof(int)); |
7805 | |
7806 | } else { |
7807 | |
7808 | feaProblem->feaAnalysis[i].loadSetID = (int *) EG_reall(feaProblem->feaAnalysis[i].loadSetID, |
7809 | feaProblem->feaAnalysis[i].numLoad *sizeof(int)); |
7810 | } |
7811 | |
7812 | if (feaProblem->feaAnalysis[i].loadSetID == NULL((void*)0)) { |
7813 | status = string_freeArray(numGroupName, &groupName); |
7814 | if (status != CAPS_SUCCESS0) return status; |
7815 | groupName = NULL((void*)0); |
7816 | return EGADS_MALLOC-4; |
7817 | } |
7818 | |
7819 | feaProblem->feaAnalysis[i].loadSetID[feaProblem->feaAnalysis[i].numLoad-1] = feaProblem->feaLoad[attrIndex].loadID; |
7820 | break; |
7821 | } |
7822 | } |
7823 | |
7824 | if (feaProblem->feaAnalysis[i].numLoad != groupIndex+1) { |
7825 | |
7826 | printf("\tWarning: Analysis load name, %s, not found in feaLoad structure\n", groupName[groupIndex]); |
7827 | |
7828 | } |
7829 | } |
7830 | |
7831 | status = string_freeArray(numGroupName, &groupName); |
7832 | if (status != CAPS_SUCCESS0) return status; |
7833 | groupName = NULL((void*)0); |
7834 | |
7835 | } |
7836 | |
7837 | // Get constraints to be applied for a given analysis |
7838 | /*! \page feaAnalysis |
7839 | * |
7840 | * \if (MYSTRAN || NASTRAN || ASTROS || ABAQUS) |
7841 | * <ul> |
7842 | * <li> <B>analysisConstraint = "(no default)"</B> </li> <br> |
7843 | * Single or list of "Constraint Name"s defined in \ref feaConstraint in which to use for the analysis (e.g. "Name1" or ["Name1","Name2",...]. |
7844 | * </ul> |
7845 | * \endif |
7846 | */ |
7847 | keyWord = "analysisConstraint"; |
7848 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
7849 | if (status == CAPS_SUCCESS0) { |
7850 | |
7851 | status = string_toStringDynamicArray(keyValue, &numGroupName, &groupName); |
7852 | if (keyValue != NULL((void*)0)) { |
7853 | EG_free(keyValue); |
7854 | keyValue = NULL((void*)0); |
7855 | } |
7856 | |
7857 | if (status != CAPS_SUCCESS0) return status; |
7858 | |
7859 | feaProblem->feaAnalysis[i].numConstraint = 0; |
7860 | for (groupIndex = 0; groupIndex < numGroupName; groupIndex++) { |
7861 | |
7862 | for (attrIndex = 0; attrIndex < feaProblem->numConstraint; attrIndex++) { |
7863 | |
7864 | if (strcasecmp(feaProblem->feaConstraint[attrIndex].name, groupName[groupIndex]) == 0) { |
7865 | |
7866 | feaProblem->feaAnalysis[i].numConstraint += 1; |
7867 | |
7868 | if (feaProblem->feaAnalysis[i].numConstraint == 1) { |
7869 | |
7870 | feaProblem->feaAnalysis[i].constraintSetID = (int *) EG_alloc(feaProblem->feaAnalysis[i].numConstraint *sizeof(int)); |
7871 | |
7872 | } else { |
7873 | |
7874 | feaProblem->feaAnalysis[i].constraintSetID = (int *) EG_reall(feaProblem->feaAnalysis[i].constraintSetID, |
7875 | feaProblem->feaAnalysis[i].numConstraint *sizeof(int)); |
7876 | } |
7877 | |
7878 | if (feaProblem->feaAnalysis[i].constraintSetID == NULL((void*)0)) { |
7879 | status = string_freeArray(numGroupName, &groupName); |
7880 | if (status != CAPS_SUCCESS0) return status; |
7881 | groupName = NULL((void*)0); |
7882 | return EGADS_MALLOC-4; |
7883 | } |
7884 | |
7885 | feaProblem->feaAnalysis[i].constraintSetID[feaProblem->feaAnalysis[i].numConstraint-1] = feaProblem->feaConstraint[attrIndex].constraintID; |
7886 | break; |
7887 | } |
7888 | } |
7889 | |
7890 | if (feaProblem->feaAnalysis[i].numConstraint != groupIndex+1) { |
7891 | |
7892 | printf("\tWarning: Analysis constraint name, %s, not found in feaConstraint structure\n", groupName[groupIndex]); |
7893 | |
7894 | } |
7895 | } |
7896 | |
7897 | status = string_freeArray(numGroupName, &groupName); |
7898 | if (status != CAPS_SUCCESS0) return status; |
7899 | groupName = NULL((void*)0); |
7900 | |
7901 | } |
7902 | |
7903 | // Get supports to be applied for a given analysis |
7904 | /*! \page feaAnalysis |
7905 | * |
7906 | * \if (MYSTRAN || NASTRAN || ASTROS) |
7907 | * <ul> |
7908 | * <li> <B>analysisSupport = "(no default)"</B> </li> <br> |
7909 | * Single or list of "Support Name"s defined in \ref feaSupport in which to use for the analysis (e.g. "Name1" or ["Name1","Name2",...]. |
7910 | * </ul> |
7911 | * \endif |
7912 | * |
7913 | */ |
7914 | keyWord = "analysisSupport"; |
7915 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
7916 | if (status == CAPS_SUCCESS0) { |
7917 | |
7918 | status = string_toStringDynamicArray(keyValue, &numGroupName, &groupName); |
7919 | if (keyValue != NULL((void*)0)) { |
7920 | EG_free(keyValue); |
7921 | keyValue = NULL((void*)0); |
7922 | } |
7923 | |
7924 | if (status != CAPS_SUCCESS0) return status; |
7925 | |
7926 | feaProblem->feaAnalysis[i].numSupport = 0; |
7927 | for (groupIndex = 0; groupIndex < numGroupName; groupIndex++) { |
7928 | |
7929 | for (attrIndex = 0; attrIndex < feaProblem->numSupport; attrIndex++) { |
7930 | |
7931 | if (strcasecmp(feaProblem->feaSupport[attrIndex].name, groupName[groupIndex]) == 0) { |
7932 | |
7933 | feaProblem->feaAnalysis[i].numSupport += 1; |
7934 | |
7935 | if (feaProblem->feaAnalysis[i].numSupport == 1) { |
7936 | |
7937 | feaProblem->feaAnalysis[i].supportSetID = (int *) EG_alloc(feaProblem->feaAnalysis[i].numSupport *sizeof(int)); |
7938 | |
7939 | } else { |
7940 | |
7941 | feaProblem->feaAnalysis[i].supportSetID = (int *) EG_reall(feaProblem->feaAnalysis[i].supportSetID, |
7942 | feaProblem->feaAnalysis[i].numSupport *sizeof(int)); |
7943 | } |
7944 | |
7945 | if (feaProblem->feaAnalysis[i].supportSetID == NULL((void*)0)) { |
7946 | status = string_freeArray(numGroupName, &groupName); |
7947 | if (status != CAPS_SUCCESS0) return status; |
7948 | groupName = NULL((void*)0); |
7949 | return EGADS_MALLOC-4; |
7950 | } |
7951 | |
7952 | feaProblem->feaAnalysis[i].supportSetID[feaProblem->feaAnalysis[i].numSupport-1] = feaProblem->feaSupport[attrIndex].supportID; |
7953 | break; |
7954 | } |
7955 | } |
7956 | |
7957 | if (feaProblem->feaAnalysis[i].numSupport != groupIndex+1) { |
7958 | |
7959 | printf("\tWarning: Analysis support name, %s, not found in feaSupport structure\n", groupName[groupIndex]); |
7960 | |
7961 | } |
7962 | } |
7963 | |
7964 | status = string_freeArray(numGroupName, &groupName); |
7965 | if (status != CAPS_SUCCESS0) return status; |
7966 | groupName = NULL((void*)0); |
7967 | |
7968 | } |
7969 | |
7970 | // Get design constraints to be applied for a given analysis |
7971 | |
7972 | /*! \page feaAnalysis |
7973 | * |
7974 | * \if (NASTRAN || ASTROS) |
7975 | * <ul> |
7976 | * <li> <B>analysisDesignConstraint = "(no default)"</B> </li> <br> |
7977 | * Single or list of "Design Constraint Name"s defined in \ref feaDesignConstraint in which to use for the analysis (e.g. "Name1" or ["Name1","Name2",...]. |
7978 | * </ul> |
7979 | * \endif |
7980 | */ |
7981 | keyWord = "analysisDesignConstraint"; |
7982 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
7983 | if (status == CAPS_SUCCESS0) { |
7984 | |
7985 | status = string_toStringDynamicArray(keyValue, &numGroupName, &groupName); |
7986 | if (keyValue != NULL((void*)0)) { |
7987 | EG_free(keyValue); |
7988 | keyValue = NULL((void*)0); |
7989 | } |
7990 | |
7991 | if (status != CAPS_SUCCESS0) return status; |
7992 | |
7993 | feaProblem->feaAnalysis[i].numDesignConstraint = 0; |
7994 | for (groupIndex = 0; groupIndex < numGroupName; groupIndex++) { |
7995 | |
7996 | for (attrIndex = 0; attrIndex < feaProblem->numDesignConstraint; attrIndex++) { |
7997 | |
7998 | if (strcasecmp(feaProblem->feaDesignConstraint[attrIndex].name, groupName[groupIndex]) == 0) { |
7999 | |
8000 | feaProblem->feaAnalysis[i].numDesignConstraint += 1; |
8001 | |
8002 | if (feaProblem->feaAnalysis[i].numDesignConstraint == 1) { |
8003 | |
8004 | feaProblem->feaAnalysis[i].designConstraintSetID = (int *) EG_alloc(feaProblem->feaAnalysis[i].numDesignConstraint *sizeof(int)); |
8005 | |
8006 | } else { |
8007 | |
8008 | feaProblem->feaAnalysis[i].designConstraintSetID = (int *) EG_reall(feaProblem->feaAnalysis[i].designConstraintSetID, |
8009 | feaProblem->feaAnalysis[i].numDesignConstraint *sizeof(int)); |
8010 | } |
8011 | |
8012 | if (feaProblem->feaAnalysis[i].designConstraintSetID == NULL((void*)0)) { |
8013 | status = string_freeArray(numGroupName, &groupName); |
8014 | if (status != CAPS_SUCCESS0) return status; |
8015 | groupName = NULL((void*)0); |
8016 | return EGADS_MALLOC-4; |
8017 | } |
8018 | |
8019 | feaProblem->feaAnalysis[i].designConstraintSetID[feaProblem->feaAnalysis[i].numDesignConstraint-1] = feaProblem->feaDesignConstraint[attrIndex].designConstraintID; |
8020 | break; |
8021 | } |
8022 | } |
8023 | |
8024 | if (feaProblem->feaAnalysis[i].numDesignConstraint != groupIndex+1) { |
8025 | |
8026 | printf("\tWarning: Analysis design constraint name, %s, not found in feaDesignConstraint structure\n", groupName[groupIndex]); |
8027 | |
8028 | } |
8029 | } |
8030 | |
8031 | status = string_freeArray(numGroupName, &groupName); |
8032 | if (status != CAPS_SUCCESS0) { |
8033 | if (tempString != NULL((void*)0)) EG_free(tempString); |
8034 | |
8035 | return status; |
8036 | } |
8037 | groupName = NULL((void*)0); |
8038 | |
8039 | } |
8040 | |
8041 | //Fill up analysis properties |
8042 | /*! \page feaAnalysis |
8043 | * |
8044 | * \if (MYSTRAN || NASTRAN || ASTROS || ABAQUS) |
8045 | * <ul> |
8046 | * <li> <B>extractionMethod = "(no default)"</B> </li> <br> |
8047 | * Extraction method for modal analysis. |
8048 | * </ul> |
8049 | * \endif |
8050 | */ |
8051 | keyWord = "extractionMethod"; |
8052 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
8053 | if (status == CAPS_SUCCESS0) { |
8054 | |
8055 | tempString = string_removeQuotation(keyValue); |
8056 | |
8057 | if (keyValue != NULL((void*)0)) { |
8058 | EG_free(keyValue); |
8059 | keyValue = NULL((void*)0); |
8060 | } |
8061 | |
8062 | feaProblem->feaAnalysis[i].extractionMethod = EG_alloc((strlen(tempString) + 1)*sizeof(char)); |
8063 | if(feaProblem->feaAnalysis[i].extractionMethod == NULL((void*)0)) { |
8064 | if (tempString != NULL((void*)0)) EG_free(tempString); |
8065 | return EGADS_MALLOC-4; |
8066 | } |
8067 | |
8068 | memcpy(feaProblem->feaAnalysis[i].extractionMethod, tempString, strlen(tempString)*sizeof(char)); |
8069 | feaProblem->feaAnalysis[i].extractionMethod[strlen(tempString)] = '\0'; |
8070 | |
8071 | if (tempString != NULL((void*)0)) { |
8072 | EG_free(tempString); |
8073 | tempString = NULL((void*)0); |
8074 | } |
8075 | } |
8076 | |
8077 | |
8078 | /*! \page feaAnalysis |
8079 | * |
8080 | * \if (MYSTRAN || NASTRAN || ASTROS || ABAQUS) |
8081 | * <ul> |
8082 | * <li> <B>frequencyRange = [0.0, 0.0] </B> </li> <br> |
8083 | * Frequency range of interest for modal analysis. |
8084 | * </ul> |
8085 | * \endif |
8086 | */ |
8087 | keyWord = "frequencyRange"; |
8088 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
8089 | if (status == CAPS_SUCCESS0) { |
8090 | |
8091 | status = string_toDoubleArray(keyValue, |
8092 | (int) sizeof(feaProblem->feaAnalysis[i].frequencyRange)/sizeof(double), |
8093 | feaProblem->feaAnalysis[i].frequencyRange); |
8094 | if (keyValue != NULL((void*)0)) { |
8095 | EG_free(keyValue); |
8096 | keyValue = NULL((void*)0); |
8097 | } |
8098 | if (status != CAPS_SUCCESS0) return status; |
8099 | } |
8100 | |
8101 | /*! \page feaAnalysis |
8102 | * |
8103 | * \if (MYSTRAN || NASTRAN || ASTROS) |
8104 | * <ul> |
8105 | * <li> <B>numEstEigenvalue = 0 </B> </li> <br> |
8106 | * Number of estimated eigenvalues for modal analysis. |
8107 | * </ul> |
8108 | * \endif |
8109 | */ |
8110 | keyWord = "numEstEigenvalue"; |
8111 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
8112 | if (status == CAPS_SUCCESS0) { |
8113 | |
8114 | status = string_toInteger(keyValue, &feaProblem->feaAnalysis[i].numEstEigenvalue); |
8115 | if (keyValue != NULL((void*)0)) { |
8116 | EG_free(keyValue); |
8117 | keyValue = NULL((void*)0); |
8118 | } |
8119 | if (status != CAPS_SUCCESS0) return status; |
8120 | } |
8121 | |
8122 | /*! \page feaAnalysis |
8123 | * |
8124 | * \if (MYSTRAN || NASTRAN || ASTROS || ABAQUS) |
8125 | * <ul> |
8126 | * <li> <B>numDesiredEigenvalue = 0</B> </li> <br> |
8127 | * Number of desired eigenvalues for modal analysis. |
8128 | * </ul> |
8129 | * \endif |
8130 | * |
8131 | */ |
8132 | keyWord = "numDesiredEigenvalue"; |
8133 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
8134 | if (status == CAPS_SUCCESS0) { |
8135 | |
8136 | status = string_toInteger(keyValue, &feaProblem->feaAnalysis[i].numDesiredEigenvalue); |
8137 | if (keyValue != NULL((void*)0)) { |
8138 | EG_free(keyValue); |
8139 | keyValue = NULL((void*)0); |
8140 | } |
8141 | if (status != CAPS_SUCCESS0) return status; |
8142 | } |
8143 | |
8144 | /*! \page feaAnalysis |
8145 | * |
8146 | * \if (MYSTRAN || NASTRAN || ASTROS) |
8147 | * <ul> |
8148 | * <li> <B>eigenNormaliztion = "(no default)"</B> </li> <br> |
8149 | * Method of eigenvector renormalization. Options: "POINT", "MAX", "MASS" |
8150 | * </ul> |
8151 | * \elseif ABAQUS |
8152 | * <ul> |
8153 | * <li> <B>eigenNormaliztion = "(no default)"</B> </li> <br> |
8154 | * Method of eigenvector renormalization. Options: "DISPLACEMENT", "MASS" |
8155 | * </ul> |
8156 | * \endif |
8157 | */ |
8158 | keyWord = "eigenNormaliztion"; |
8159 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
8160 | if (status == CAPS_SUCCESS0) { |
8161 | |
8162 | tempString = string_removeQuotation(keyValue); |
8163 | |
8164 | feaProblem->feaAnalysis[i].eigenNormaliztion = EG_alloc((strlen(tempString) + 1)*sizeof(char)); |
8165 | if(feaProblem->feaAnalysis[i].eigenNormaliztion == NULL((void*)0)) { |
8166 | if (tempString != NULL((void*)0)) EG_free(tempString); |
8167 | |
8168 | return EGADS_MALLOC-4; |
8169 | } |
8170 | |
8171 | memcpy(feaProblem->feaAnalysis[i].eigenNormaliztion, tempString, strlen(tempString)*sizeof(char)); |
8172 | feaProblem->feaAnalysis[i].eigenNormaliztion[strlen(tempString)] = '\0'; |
8173 | |
8174 | if (keyValue != NULL((void*)0)) { |
8175 | EG_free(keyValue); |
8176 | keyValue = NULL((void*)0); |
8177 | } |
8178 | if (tempString != NULL((void*)0)) { |
8179 | EG_free(tempString); |
8180 | tempString = NULL((void*)0); |
8181 | } |
8182 | } |
8183 | |
8184 | /*! \page feaAnalysis |
8185 | * |
8186 | * \if (MYSTRAN || NASTRAN || ASTROS) |
8187 | * <ul> |
8188 | * <li> <B>gridNormaliztion = 0 </B> </li> <br> |
8189 | * Grid point to be used in normalizing eigenvector to 1.0 when using eigenNormaliztion = "POINT" |
8190 | * </ul> |
8191 | * \endif |
8192 | */ |
8193 | keyWord = "gridNormaliztion"; |
8194 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
8195 | if (status == CAPS_SUCCESS0) { |
8196 | |
8197 | status = string_toInteger(keyValue, &feaProblem->feaAnalysis[i].gridNormaliztion); |
8198 | if (keyValue != NULL((void*)0)) { |
8199 | EG_free(keyValue); |
8200 | keyValue = NULL((void*)0); |
8201 | } |
8202 | if (status != CAPS_SUCCESS0) return status; |
8203 | } |
8204 | |
8205 | /*! \page feaAnalysis |
8206 | * |
8207 | * \if (MYSTRAN || NASTRAN || ASTROS) |
8208 | * <ul> |
8209 | * <li> <B>componentNormaliztion = 0</B> </li> <br> |
8210 | * Degree of freedom about "gridNormalization" to be used in normalizing eigenvector to 1.0 |
8211 | * when using eigenNormaliztion = "POINT" |
8212 | * </ul> |
8213 | * \endif |
8214 | * |
8215 | */ |
8216 | keyWord = "componentNormaliztion"; |
8217 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
8218 | if (status == CAPS_SUCCESS0) { |
8219 | |
8220 | status = string_toInteger(keyValue, &feaProblem->feaAnalysis[i].componentNormaliztion); |
8221 | if (keyValue != NULL((void*)0)) { |
8222 | EG_free(keyValue); |
8223 | keyValue = NULL((void*)0); |
8224 | } |
8225 | if (status != CAPS_SUCCESS0) return status; |
8226 | } |
8227 | |
8228 | /*! \page feaAnalysis |
8229 | * |
8230 | * \if (MYSTRAN || NASTRAN) |
8231 | * <ul> |
8232 | * <li> <B>lanczosMode = 2</B> </li> <br> |
8233 | * Mode refers to the Lanczos mode type to be used in the solution. In mode 3 the mass matrix, Maa,must |
8234 | * be nonsingular whereas in mode 2 the matrix K aa - sigma*Maa must be nonsingular |
8235 | * </ul> |
8236 | * \endif |
8237 | */ |
8238 | keyWord = "lanczosMode"; |
8239 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
8240 | if (status == CAPS_SUCCESS0) { |
8241 | |
8242 | status = string_toInteger(keyValue, &feaProblem->feaAnalysis[i].lanczosMode); |
8243 | if (keyValue != NULL((void*)0)) { |
8244 | EG_free(keyValue); |
8245 | keyValue = NULL((void*)0); |
8246 | } |
8247 | if (status != CAPS_SUCCESS0) return status; |
8248 | } |
8249 | |
8250 | /*! \page feaAnalysis |
8251 | * |
8252 | * \if (MYSTRAN || NASTRAN) |
8253 | * <ul> |
8254 | * <li> <B>lanczosType = "(no default)"</B> </li> <br> |
8255 | * Lanczos matrix type. Options: DPB, DGB. |
8256 | * </ul> |
8257 | * \endif |
8258 | */ |
8259 | keyWord = "lanczosType"; |
8260 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
8261 | if (status == CAPS_SUCCESS0) { |
8262 | |
8263 | tempString = string_removeQuotation(keyValue); |
8264 | |
8265 | feaProblem->feaAnalysis[i].lanczosType = EG_alloc((strlen(tempString) + 1)*sizeof(char)); |
8266 | if(feaProblem->feaAnalysis[i].lanczosType == NULL((void*)0)) { |
8267 | if (tempString != NULL((void*)0)) EG_free(tempString); |
8268 | |
8269 | return EGADS_MALLOC-4; |
8270 | } |
8271 | |
8272 | memcpy(feaProblem->feaAnalysis[i].lanczosType, tempString, strlen(tempString)*sizeof(char)); |
8273 | feaProblem->feaAnalysis[i].lanczosType[strlen(tempString)] = '\0'; |
8274 | |
8275 | if (keyValue != NULL((void*)0)) { |
8276 | EG_free(keyValue); |
8277 | keyValue = NULL((void*)0); |
8278 | } |
8279 | |
8280 | if (tempString != NULL((void*)0)) { |
8281 | EG_free(tempString); |
8282 | tempString = NULL((void*)0); |
8283 | } |
8284 | } |
8285 | |
8286 | /*! \page feaAnalysis |
8287 | * |
8288 | * \if (NASTRAN) |
8289 | * <ul> |
8290 | * <li> <B>machNumber = 0.0 or [0.0, ..., 0.0]</B> </li> <br> |
8291 | * Mach number used in trim analysis OR Mach numbers used in flutter analysis.. |
8292 | * </ul> |
8293 | * \elseif (ASTROS) |
8294 | * <ul> |
8295 | * <li> <B>machNumber = 0.0 or [0.0, ..., 0.0]</B> </li> <br> |
8296 | * Mach number used in trim analysis OR Mach up to 6 values used in flutter analysis.. |
8297 | * </ul> |
8298 | * \endif |
8299 | */ |
8300 | keyWord = "machNumber"; |
8301 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
8302 | if (status == CAPS_SUCCESS0) { |
8303 | |
8304 | status = string_toDoubleDynamicArray(keyValue, &feaProblem->feaAnalysis[i].numMachNumber, &feaProblem->feaAnalysis[i].machNumber); |
8305 | if (keyValue != NULL((void*)0)) { |
8306 | EG_free(keyValue); |
8307 | keyValue = NULL((void*)0); |
8308 | } |
8309 | if (status != CAPS_SUCCESS0) return status; |
8310 | } |
8311 | |
8312 | /*! \page feaAnalysis |
8313 | * |
8314 | * \if (NASTRAN || ASTROS) |
8315 | * <ul> |
8316 | * <li> <B>dynamicPressure = 0.0</B> </li> <br> |
8317 | * Dynamic pressure used in trim analysis. |
8318 | * </ul> |
8319 | * \endif |
8320 | */ |
8321 | keyWord = "dynamicPressure"; |
8322 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
8323 | if (status == CAPS_SUCCESS0) { |
8324 | |
8325 | status = string_toDouble(keyValue, &feaProblem->feaAnalysis[i].dynamicPressure); |
8326 | if (keyValue != NULL((void*)0)) { |
8327 | EG_free(keyValue); |
8328 | keyValue = NULL((void*)0); |
8329 | } |
8330 | if (status != CAPS_SUCCESS0) return status; |
8331 | } |
8332 | |
8333 | /*! \page feaAnalysis |
8334 | * |
8335 | * \if (NASTRAN || ASTROS) |
8336 | * <ul> |
8337 | * <li> <B>density = 0.0</B> </li> <br> |
8338 | * Density used in trim analysis to determine true velocity, or flutter analysis. |
8339 | * </ul> |
8340 | * \endif |
8341 | */ |
8342 | keyWord = "density"; |
8343 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
8344 | if (status == CAPS_SUCCESS0) { |
8345 | |
8346 | status = string_toDouble(keyValue, &feaProblem->feaAnalysis[i].density); |
8347 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
8348 | if (status != CAPS_SUCCESS0) return status; |
8349 | } |
8350 | |
8351 | /*! \page feaAnalysis |
8352 | * |
8353 | * \if (MYSTRAN || NASTRAN || ASTROS) |
8354 | * <ul> |
8355 | * <li> <B>aeroSymmetryXY = "(no default)"</B> </li> <br> |
8356 | * Aerodynamic symmetry about the XY Plane. Options: SYM, ANTISYM, ASYM. |
8357 | * Aerodynamic symmetry about the XY Plane. Options: SYM, ANTISYM, ASYM. SYMMETRIC Indicates that a half span aerodynamic model |
8358 | * is moving in a symmetric manner with respect to the XY plane. |
8359 | * ANTISYMMETRIC Indicates that a half span aerodynamic model is moving in an antisymmetric manner with respect to the XY plane. |
8360 | * ASYMMETRIC Indicates that a full aerodynamic model is provided. |
8361 | * </ul> |
8362 | * \endif |
8363 | */ |
8364 | keyWord = "aeroSymmetryXY"; |
8365 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
8366 | if (status == CAPS_SUCCESS0) { |
8367 | |
8368 | tempString = string_removeQuotation(keyValue); |
8369 | |
8370 | feaProblem->feaAnalysis[i].aeroSymmetryXY = EG_alloc((strlen(tempString) + 1)*sizeof(char)); |
8371 | if(feaProblem->feaAnalysis[i].aeroSymmetryXY == NULL((void*)0)) { |
8372 | if (tempString != NULL((void*)0)) EG_free(tempString); |
8373 | |
8374 | return EGADS_MALLOC-4; |
8375 | } |
8376 | |
8377 | memcpy(feaProblem->feaAnalysis[i].aeroSymmetryXY, tempString, strlen(tempString)*sizeof(char)); |
8378 | feaProblem->feaAnalysis[i].aeroSymmetryXY[strlen(tempString)] = '\0'; |
8379 | |
8380 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
8381 | AIM_FREE(tempString){ EG_free(tempString); tempString = ((void*)0); }; |
8382 | } |
8383 | |
8384 | // check for the old option trimSymmetry |
8385 | keyWord = "trimSymmetry"; |
8386 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
8387 | if (status == CAPS_SUCCESS0) { |
8388 | |
8389 | tempString = string_removeQuotation(keyValue); |
8390 | |
8391 | feaProblem->feaAnalysis[i].aeroSymmetryXY = EG_alloc((strlen(tempString) + 1)*sizeof(char)); |
8392 | if(feaProblem->feaAnalysis[i].aeroSymmetryXY == NULL((void*)0)) { |
8393 | if (tempString != NULL((void*)0)) EG_free(tempString); |
8394 | |
8395 | return EGADS_MALLOC-4; |
8396 | } |
8397 | |
8398 | memcpy(feaProblem->feaAnalysis[i].aeroSymmetryXY, tempString, strlen(tempString)*sizeof(char)); |
8399 | feaProblem->feaAnalysis[i].aeroSymmetryXY[strlen(tempString)] = '\0'; |
8400 | |
8401 | if (keyValue != NULL((void*)0)) { |
8402 | EG_free(keyValue); |
8403 | keyValue = NULL((void*)0); |
8404 | } |
8405 | |
8406 | if (tempString != NULL((void*)0)) { |
8407 | EG_free(tempString); |
8408 | tempString = NULL((void*)0); |
8409 | } |
8410 | } |
8411 | |
8412 | /*! \page feaAnalysis |
8413 | * |
8414 | * \if (MYSTRAN || NASTRAN || ASTROS) |
8415 | * <ul> |
8416 | * <li> <B>aeroSymmetryXZ = "(no default)"</B> </li> <br> |
8417 | * Aerodynamic symmetry about the XZ Plane. Options: SYM, ANTISYM, ASYM. SYMMETRIC Indicates that a half span aerodynamic model |
8418 | * is moving in a symmetric manner with respect to the XZ plane. |
8419 | * ANTISYMMETRIC Indicates that a half span aerodynamic model is moving in an antisymmetric manner with respect to the XZ plane. |
8420 | * ASYMMETRIC Indicates that a full aerodynamic model is provided. |
8421 | * </ul> |
8422 | * \endif |
8423 | */ |
8424 | keyWord = "aeroSymmetryXZ"; |
8425 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
8426 | if (status == CAPS_SUCCESS0) { |
8427 | |
8428 | tempString = string_removeQuotation(keyValue); |
8429 | |
8430 | feaProblem->feaAnalysis[i].aeroSymmetryXZ = EG_alloc((strlen(tempString) + 1)*sizeof(char)); |
8431 | if(feaProblem->feaAnalysis[i].aeroSymmetryXZ == NULL((void*)0)) { |
8432 | if (tempString != NULL((void*)0)) EG_free(tempString); |
8433 | |
8434 | return EGADS_MALLOC-4; |
8435 | } |
8436 | |
8437 | memcpy(feaProblem->feaAnalysis[i].aeroSymmetryXZ, tempString, strlen(tempString)*sizeof(char)); |
8438 | feaProblem->feaAnalysis[i].aeroSymmetryXZ[strlen(tempString)] = '\0'; |
8439 | |
8440 | if (keyValue != NULL((void*)0)) { |
8441 | EG_free(keyValue); |
8442 | keyValue = NULL((void*)0); |
8443 | } |
8444 | |
8445 | if (tempString != NULL((void*)0)) { |
8446 | EG_free(tempString); |
8447 | tempString = NULL((void*)0); |
8448 | } |
8449 | } |
8450 | |
8451 | /*! \page feaAnalysis |
8452 | * |
8453 | * \if (NASTRAN ) |
8454 | * <ul> |
8455 | * <li> <B>rigidVariable = ["no default"]</B> </li> <br> |
8456 | * List of rigid body motions to be used as trim variables during a trim analysis. Nastran |
8457 | * valid labels are: ANGLEA, SIDES, ROLL, PITCH, YAW, URDD1, URDD2, URDD3, URDD4, URDD5, URDD6 |
8458 | * </ul> |
8459 | * \elseif ASTROS |
8460 | * <ul> |
8461 | * <li> <B>rigidVariable = ["no default"]</B> </li> <br> |
8462 | * List of rigid body motions to be used as trim variables during a trim analysis. Nastran format |
8463 | * labels are used and will be converted by the AIM automatically. |
8464 | * Expected inputs: ANGLEA, SIDES, ROLL, PITCH, YAW, URDD1, URDD2, URDD3, URDD4, URDD5, URDD6 |
8465 | * </ul> |
8466 | * \endif |
8467 | */ |
8468 | keyWord = "rigidVariable"; |
8469 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
8470 | if (status == CAPS_SUCCESS0) { |
8471 | |
8472 | status = string_toStringDynamicArray(keyValue, |
8473 | &feaProblem->feaAnalysis[i].numRigidVariable, |
8474 | &feaProblem->feaAnalysis[i].rigidVariable); |
8475 | if (keyValue != NULL((void*)0)) { |
8476 | EG_free(keyValue); |
8477 | keyValue = NULL((void*)0); |
8478 | } |
8479 | if (status != CAPS_SUCCESS0) return status; |
8480 | } |
8481 | |
8482 | /*! \page feaAnalysis |
8483 | * |
8484 | * \if (NASTRAN) |
8485 | * <ul> |
8486 | * <li> <B>rigidConstraint = ["no default"]</B> </li> <br> |
8487 | * List of rigid body motions to be used as trim constraint variables during a trim analysis. Nastran |
8488 | * valid labels are: ANGLEA, SIDES, ROLL, PITCH, YAW, URDD1, URDD2, URDD3, URDD4, URDD5, URDD6 |
8489 | * </ul> |
8490 | * \elseif ASTROS |
8491 | * <ul> |
8492 | * <li> <B>rigidConstraint = ["no default"]</B> </li> <br> |
8493 | * List of rigid body motions to be used as trim constraint variables during a trim analysis. Nastran format |
8494 | * labels are used and will be converted by the AIM automatically. |
8495 | * Expected inputs: ANGLEA, SIDES, ROLL, PITCH, YAW, URDD1, URDD2, URDD3, URDD4, URDD5, URDD6 |
8496 | * </ul> |
8497 | * \endif |
8498 | */ |
8499 | keyWord = "rigidConstraint"; |
8500 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
8501 | if (status == CAPS_SUCCESS0) { |
8502 | |
8503 | status = string_toStringDynamicArray(keyValue, |
8504 | &feaProblem->feaAnalysis[i].numRigidConstraint, |
8505 | &feaProblem->feaAnalysis[i].rigidConstraint); |
8506 | if (keyValue != NULL((void*)0)) { |
8507 | EG_free(keyValue); |
8508 | keyValue = NULL((void*)0); |
8509 | } |
8510 | if (status != CAPS_SUCCESS0) return status; |
8511 | } |
8512 | |
8513 | if (feaProblem->feaAnalysis[i].numRigidConstraint != 0) { |
8514 | /*! \page feaAnalysis |
8515 | * |
8516 | * \if (NASTRAN || ASTROS) |
8517 | * <ul> |
8518 | * <li> <B>magRigidConstraint = [0.0 , 0.0, ...]</B> </li> <br> |
8519 | * List of magnitudes of trim constraint variables. If none and 'rigidConstraint'(s) are specified |
8520 | * then 0.0 is assumed for each rigid constraint. |
8521 | * </ul> |
8522 | * \endif |
8523 | */ |
8524 | keyWord = "magRigidConstraint"; |
8525 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
8526 | if (status == CAPS_SUCCESS0) { |
8527 | |
8528 | status = string_toDoubleDynamicArray(keyValue, |
8529 | &tempInt, |
8530 | &feaProblem->feaAnalysis[i].magRigidConstraint); |
8531 | if (keyValue != NULL((void*)0)) { |
8532 | EG_free(keyValue); |
8533 | keyValue = NULL((void*)0); |
8534 | } |
8535 | if (status != CAPS_SUCCESS0) return status; |
8536 | } else { |
8537 | |
8538 | tempInt = feaProblem->feaAnalysis[i].numRigidConstraint; |
8539 | |
8540 | feaProblem->feaAnalysis[i].magRigidConstraint = (double *) EG_alloc(tempInt*sizeof(double)); |
8541 | if (feaProblem->feaAnalysis[i].magRigidConstraint == NULL((void*)0)) return EGADS_MALLOC-4; |
8542 | |
8543 | for (j = 0; j < feaProblem->feaAnalysis[i].numRigidConstraint; j++) { |
8544 | |
8545 | feaProblem->feaAnalysis[i].magRigidConstraint[j] = 0.0; |
8546 | } |
8547 | } |
8548 | |
8549 | if (tempInt != feaProblem->feaAnalysis[i].numRigidConstraint) { |
8550 | printf("\tDimensional mismatch between 'magRigidConstraint' and 'rigidConstraint'.\n"); |
8551 | printf("\t 'magRigidConstraint' will be resized.\n"); |
8552 | |
8553 | feaProblem->feaAnalysis[i].magRigidConstraint = (double *) EG_reall(feaProblem->feaAnalysis[i].magRigidConstraint, |
8554 | feaProblem->feaAnalysis[i].numRigidConstraint*sizeof(double)); |
8555 | |
8556 | if (feaProblem->feaAnalysis[i].magRigidConstraint == NULL((void*)0)) return EGADS_MALLOC-4; |
8557 | |
8558 | for (j = tempInt; j < feaProblem->feaAnalysis[i].numRigidConstraint; j++) { |
8559 | feaProblem->feaAnalysis[i].magRigidConstraint[j] = 0.0; |
8560 | } |
8561 | } |
8562 | } |
8563 | |
8564 | /*! \page feaAnalysis |
8565 | * |
8566 | * \if (NASTRAN || ASTROS) |
8567 | * <ul> |
8568 | * <li> <B>controlConstraint = ["no default"]</B> </li> <br> |
8569 | * List of controls surfaces to be used as trim constraint variables during a trim analysis. |
8570 | * </ul> |
8571 | * \endif |
8572 | */ |
8573 | keyWord = "controlConstraint"; |
8574 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
8575 | if (status == CAPS_SUCCESS0) { |
8576 | |
8577 | status = string_toStringDynamicArray(keyValue, |
8578 | &feaProblem->feaAnalysis[i].numControlConstraint, |
8579 | &feaProblem->feaAnalysis[i].controlConstraint); |
8580 | if (keyValue != NULL((void*)0)) { |
8581 | EG_free(keyValue); |
8582 | keyValue = NULL((void*)0); |
8583 | } |
8584 | if (status != CAPS_SUCCESS0) return status; |
8585 | } |
8586 | |
8587 | if (feaProblem->feaAnalysis[i].numControlConstraint != 0) { |
8588 | /*! \page feaAnalysis |
8589 | * |
8590 | * \if (NASTRAN || ASTROS) |
8591 | * <ul> |
8592 | * <li> <B>magControlConstraint = [0.0 , 0.0, ...]</B> </li> <br> |
8593 | * List of magnitudes of trim control surface constraint variables. If none and 'controlConstraint'(s) are specified |
8594 | * then 0.0 is assumed for each control surface constraint. |
8595 | * </ul> |
8596 | * \endif |
8597 | */ |
8598 | keyWord = "magControlConstraint"; |
8599 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
8600 | if (status == CAPS_SUCCESS0) { |
8601 | |
8602 | status = string_toDoubleDynamicArray(keyValue, |
8603 | &tempInt, |
8604 | &feaProblem->feaAnalysis[i].magControlConstraint); |
8605 | if (keyValue != NULL((void*)0)) { |
8606 | EG_free(keyValue); |
8607 | keyValue = NULL((void*)0); |
8608 | } |
8609 | if (status != CAPS_SUCCESS0) return status; |
8610 | } else { |
8611 | |
8612 | tempInt = feaProblem->feaAnalysis[i].numControlConstraint; |
8613 | |
8614 | feaProblem->feaAnalysis[i].magControlConstraint = (double *) EG_alloc(tempInt*sizeof(double)); |
8615 | if (feaProblem->feaAnalysis[i].magControlConstraint == NULL((void*)0)) return EGADS_MALLOC-4; |
8616 | |
8617 | for (j = 0; j < feaProblem->feaAnalysis[i].numControlConstraint; j++) { |
8618 | |
8619 | feaProblem->feaAnalysis[i].magControlConstraint[j] = 0.0; |
8620 | } |
8621 | } |
8622 | |
8623 | if (tempInt != feaProblem->feaAnalysis[i].numControlConstraint) { |
8624 | printf("\tDimensional mismatch between 'magControlConstraint' and 'controlConstraint'.\n"); |
8625 | printf("\t 'magControlConstraint' will be resized.\n"); |
8626 | |
8627 | feaProblem->feaAnalysis[i].magControlConstraint = (double *) EG_reall(feaProblem->feaAnalysis[i].magControlConstraint, |
8628 | feaProblem->feaAnalysis[i].numControlConstraint*sizeof(double)); |
8629 | |
8630 | if (feaProblem->feaAnalysis[i].magControlConstraint == NULL((void*)0)) return EGADS_MALLOC-4; |
8631 | |
8632 | for (j = tempInt; j < feaProblem->feaAnalysis[i].numControlConstraint; j++) { |
8633 | feaProblem->feaAnalysis[i].magControlConstraint[j] = 0.0; |
8634 | } |
8635 | } |
8636 | } |
8637 | |
8638 | /*! \page feaAnalysis |
8639 | * |
8640 | * \if (NASTRAN || ASTROS) |
8641 | * <ul> |
8642 | * <li> <B>reducedFreq = [0.1, ..., 20.0], No Default Values are defined.</B> </li> <br> |
8643 | * Reduced Frequencies to be used in Flutter Analysis. Up to 8 values can be defined. |
8644 | * </ul> |
8645 | * \endif |
8646 | */ |
8647 | keyWord = "reducedFreq"; |
8648 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
8649 | if (status == CAPS_SUCCESS0) { |
8650 | |
8651 | status = string_toDoubleDynamicArray(keyValue, &feaProblem->feaAnalysis[i].numReducedFreq, &feaProblem->feaAnalysis[i].reducedFreq); |
8652 | if (keyValue != NULL((void*)0)) { |
8653 | EG_free(keyValue); |
8654 | keyValue = NULL((void*)0); |
8655 | } |
8656 | if (feaProblem->feaAnalysis[i].numReducedFreq > 8) { |
8657 | printf("\tError: The number of reduced frequencies (reducedFreq) entered in an Analysis AIM Input must be eight or less\n"); |
8658 | return CAPS_BADVALUE-311; |
8659 | } |
8660 | if (status != CAPS_SUCCESS0) return status; |
8661 | } |
8662 | |
8663 | /*! \page feaAnalysis |
8664 | * |
8665 | * \if (NASTRAN || ASTROS) |
8666 | * <ul> |
8667 | * <li> <B>flutterVel = [0.1, ..., 20.0]</B> </li> <br> |
8668 | * Velocities to be used in Flutter Analysis. If no values are provided the |
8669 | * following relation is used |
8670 | * |
8671 | * v = sqrt(2*dynamicPressure/density) |
8672 | * dv = (v*2 - v/2) / 20; |
8673 | * |
8674 | * flutterVel[0] = v/10 |
8675 | * flutterVel[i] = v/2 + i*dv; where i = 1....21 |
8676 | * flutterVel[22] = v*10; |
8677 | * </ul> |
8678 | * \endif |
8679 | */ |
8680 | keyWord = "flutterVel"; |
8681 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
8682 | if (status == CAPS_SUCCESS0) { |
8683 | |
8684 | status = string_toDoubleDynamicArray(keyValue, &feaProblem->feaAnalysis[i].numFlutterVel, &feaProblem->feaAnalysis[i].flutterVel); |
8685 | if (keyValue != NULL((void*)0)) { |
8686 | EG_free(keyValue); |
8687 | keyValue = NULL((void*)0); |
8688 | } |
8689 | if (status != CAPS_SUCCESS0) return status; |
8690 | } |
8691 | |
8692 | /*! \page feaAnalysis |
8693 | * |
8694 | * \if (ASTROS) |
8695 | * <ul> |
8696 | * <li> <B>flutterConvergenceParam = 1e-5 </B> </li> <br> |
8697 | * Convergence parameter for flutter eigenvalue. |
8698 | * </ul> |
8699 | * \endif |
8700 | */ |
8701 | keyWord = "flutterConvergenceParam"; |
8702 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
8703 | if (status == CAPS_SUCCESS0) { |
8704 | |
8705 | status = string_toDouble(keyValue, &feaProblem->feaAnalysis[i].flutterConvergenceParam); |
8706 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
8707 | if (status != CAPS_SUCCESS0) return status; |
8708 | } |
8709 | else { |
8710 | feaProblem->feaAnalysis[i].flutterConvergenceParam = 1.e-5; |
8711 | } |
8712 | |
8713 | /*! \page feaAnalysis |
8714 | * |
8715 | * \if (NASTRAN || ASTROS) |
8716 | * <ul> |
8717 | * <li> <B>visualFlutter = False </B> </li> <br> |
8718 | * Turn on flutter visualization f06 output. |
8719 | * </ul> |
8720 | * \endif |
8721 | */ |
8722 | // keyWord = "visualFlutter"; |
8723 | // status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
8724 | // if (status == CAPS_SUCCESS) { |
8725 | // |
8726 | // status = string_toBoolean(keyValue, &feaProblem->feaAnalysis[i].visualFlutter); |
8727 | // if (keyValue != NULL) { |
8728 | // EG_free(keyValue); |
8729 | // keyValue = NULL; |
8730 | // } |
8731 | // if (status != CAPS_SUCCESS) return status; |
8732 | // } |
8733 | |
8734 | /*! \page feaAnalysis |
8735 | * |
8736 | * \if (NASTRAN) |
8737 | * <ul> |
8738 | * <li> <B>analysisResponse = "(no default)"</B> </li> <br> |
8739 | * Single or list of "DesignResponse Name"s defined in \ref feaDesignResponse to use for the analysis response spanning sets (e.g. "Name1" or ["Name1","Name2",...]. |
8740 | * </ul> |
8741 | * \endif |
8742 | */ |
8743 | keyWord = "analysisResponse"; |
8744 | status = search_jsonDictionary( analysisTuple[i].value, keyWord, &keyValue); |
8745 | if (status == CAPS_SUCCESS0) { |
8746 | |
8747 | status = string_toStringDynamicArray(keyValue, &numGroupName, &groupName); |
8748 | if (keyValue != NULL((void*)0)) { |
8749 | EG_free(keyValue); |
8750 | keyValue = NULL((void*)0); |
8751 | } |
8752 | |
8753 | if (status != CAPS_SUCCESS0) return status; |
8754 | |
8755 | feaProblem->feaAnalysis[i].numDesignResponse = 0; |
8756 | for (groupIndex = 0; groupIndex < numGroupName; groupIndex++) { |
8757 | |
8758 | for (attrIndex = 0; attrIndex < feaProblem->numDesignResponse; attrIndex++) { |
8759 | |
8760 | if (strcasecmp(feaProblem->feaDesignResponse[attrIndex].name, groupName[groupIndex]) == 0) { |
8761 | |
8762 | feaProblem->feaAnalysis[i].numDesignResponse += 1; |
8763 | |
8764 | if (feaProblem->feaAnalysis[i].numDesignResponse == 1) { |
8765 | |
8766 | feaProblem->feaAnalysis[i].designResponseSetID = (int *) EG_alloc(feaProblem->feaAnalysis[i].numDesignResponse *sizeof(int)); |
8767 | |
8768 | } else { |
8769 | |
8770 | feaProblem->feaAnalysis[i].designResponseSetID = (int *) EG_reall(feaProblem->feaAnalysis[i].designResponseSetID, |
8771 | feaProblem->feaAnalysis[i].numDesignResponse *sizeof(int)); |
8772 | } |
8773 | |
8774 | if (feaProblem->feaAnalysis[i].designResponseSetID == NULL((void*)0)) { |
8775 | status = string_freeArray(numGroupName, &groupName); |
8776 | if (status != CAPS_SUCCESS0) return status; |
8777 | groupName = NULL((void*)0); |
8778 | return EGADS_MALLOC-4; |
8779 | } |
8780 | |
8781 | feaProblem->feaAnalysis[i].designResponseSetID[feaProblem->feaAnalysis[i].numDesignResponse-1] = feaProblem->feaDesignResponse[attrIndex].responseID; |
8782 | break; |
8783 | } |
8784 | } |
8785 | |
8786 | if (feaProblem->feaAnalysis[i].numDesignResponse != groupIndex+1) { |
8787 | |
8788 | printf("\tWarning: Analysis design response name, %s, not found in feaDesignResponse structure\n", groupName[groupIndex]); |
8789 | |
8790 | } |
8791 | } |
8792 | |
8793 | status = string_freeArray(numGroupName, &groupName); |
8794 | if (status != CAPS_SUCCESS0) { |
8795 | if (tempString != NULL((void*)0)) EG_free(tempString); |
8796 | |
8797 | return status; |
8798 | } |
8799 | groupName = NULL((void*)0); |
8800 | } |
8801 | |
8802 | if (feaProblem->feaAnalysis[i].analysisType == AeroelasticFlutter) { |
8803 | // Setup the default flutter velocities if not specified |
8804 | status = fea_defaultFlutterVelocity(&feaProblem->feaAnalysis[i]); |
8805 | if (status != CAPS_SUCCESS0) return status; |
8806 | } |
8807 | |
8808 | } else { // Not JSONstring |
8809 | |
8810 | /*! \page feaAnalysis |
8811 | * \section keyStringAnalysis Single Value String |
8812 | * |
8813 | * If "Value" is a string, the string value may correspond to an entry in a predefined analysis lookup |
8814 | * table. NOT YET IMPLEMENTED!!!! |
8815 | * |
8816 | * |
8817 | */ |
8818 | |
8819 | // CALL analysis look up |
8820 | printf("\tError: Analysis tuple value is expected to be a JSON string\n"); |
8821 | //printf("\t%s", analysisTuple[i].value); |
8822 | return CAPS_BADVALUE-311; |
8823 | } |
8824 | } |
8825 | |
8826 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
8827 | |
8828 | printf("\tDone getting FEA analyses\n"); |
8829 | return CAPS_SUCCESS0; |
8830 | } |
8831 | |
8832 | // Get the design variables from a capsTuple |
8833 | int fea_getDesignVariable(void *aimInfo, |
8834 | /*@unused@*/ int requireGroup, |
8835 | int numDesignVariableTuple, |
8836 | capsTuple designVariableTuple[], |
8837 | int numDesignVariableRelationTuple, |
8838 | capsTuple designVariableRelationTuple[], |
8839 | mapAttrToIndexStruct *attrMap, |
8840 | feaProblemStruct *feaProblem) { |
8841 | |
8842 | /*! \page feaDesignVariable FEA Design Variables |
8843 | * Structure for the design variable tuple = ("DesignVariable Name", "Value"). |
8844 | * "DesignVariable Name" defines the reference name for the design variable being specified. |
8845 | * This string will be used in the FEA input directly. The "Value" must be a JSON String dictionary |
8846 | * (see Section \ref jsonStringDesignVariable). |
8847 | * \if NASTRAN |
8848 | * In Nastran the DesignVariable Name will be the LABEL used in the DESVAR input. |
8849 | * For this reason the user should keep the length of this input to a minimum number of characters, ideally 7 or less. |
8850 | * |
8851 | * - <c>DESVAR ID LABEL XINIT XLB XUB DELXV DDVAL</c> |
8852 | * \endif |
8853 | * |
8854 | */ |
8855 | int status; //Function return |
8856 | |
8857 | int i, j, k; // Indexing |
8858 | int found; |
8859 | |
8860 | char *keyValue = NULL((void*)0); |
8861 | char *keyWord = NULL((void*)0); |
8862 | |
8863 | int tempInteger = 0; |
8864 | int designVariableID = 0; |
8865 | |
8866 | char **groupName = NULL((void*)0); |
8867 | int numGroupName = 0; |
8868 | |
8869 | feaDesignVariableStruct *designVariable; |
8870 | feaDesignVariableRelationStruct *designVariableRelation; |
8871 | |
8872 | // Destroy our design variable structures coming in if aren't 0 and NULL already |
8873 | if (feaProblem->feaDesignVariable != NULL((void*)0)) { |
8874 | for (i = 0; i < feaProblem->numDesignVariable; i++) { |
8875 | status = destroy_feaDesignVariableStruct(&feaProblem->feaDesignVariable[i]); |
8876 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 8876 , __func__, 0); goto cleanup; }; |
8877 | } |
8878 | } |
8879 | AIM_FREE(feaProblem->feaDesignVariable){ EG_free(feaProblem->feaDesignVariable); feaProblem->feaDesignVariable = ((void*)0); }; |
8880 | feaProblem->feaDesignVariable = NULL((void*)0); |
8881 | feaProblem->numDesignVariable = 0; |
8882 | |
8883 | // Destroy our design variable relation structures coming in if aren't 0 and NULL already |
8884 | if (feaProblem->feaDesignVariableRelation != NULL((void*)0)) { |
8885 | for (i = 0; i < feaProblem->numDesignVariableRelation; i++) { |
8886 | status = destroy_feaDesignVariableRelationStruct(&feaProblem->feaDesignVariableRelation[i]); |
8887 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 8887 , __func__, 0); goto cleanup; }; |
8888 | } |
8889 | } |
8890 | AIM_FREE(feaProblem->feaDesignVariableRelation){ EG_free(feaProblem->feaDesignVariableRelation); feaProblem ->feaDesignVariableRelation = ((void*)0); }; |
8891 | feaProblem->feaDesignVariableRelation = NULL((void*)0); |
8892 | feaProblem->numDesignVariableRelation = 0; |
8893 | |
8894 | |
8895 | printf("\nGetting FEA design variables.......\n"); |
8896 | |
8897 | feaProblem->numDesignVariable = numDesignVariableTuple; |
8898 | |
8899 | printf("\tNumber of design variables - %d\n", feaProblem->numDesignVariable); |
8900 | |
8901 | if (feaProblem->numDesignVariable > 0) { |
8902 | AIM_ALLOC(feaProblem->feaDesignVariable,{ if (feaProblem->feaDesignVariable != ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 8903, __func__ , 1, "AIM_ALLOC: %s != NULL", "feaProblem->feaDesignVariable" ); goto cleanup; } size_t memorysize = feaProblem->numDesignVariable ; feaProblem->feaDesignVariable = (feaDesignVariableStruct *) EG_alloc(memorysize*sizeof(feaDesignVariableStruct)); if ( feaProblem->feaDesignVariable == ((void*)0)) { status = -4 ; aim_status(aimInfo, status, "feaUtils.c", 8903, __func__, 3 , "AIM_ALLOC: %s size %zu type %s", "feaProblem->feaDesignVariable" , memorysize, "feaDesignVariableStruct"); goto cleanup; } } |
8903 | feaProblem->numDesignVariable, feaDesignVariableStruct, aimInfo, status){ if (feaProblem->feaDesignVariable != ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 8903, __func__ , 1, "AIM_ALLOC: %s != NULL", "feaProblem->feaDesignVariable" ); goto cleanup; } size_t memorysize = feaProblem->numDesignVariable ; feaProblem->feaDesignVariable = (feaDesignVariableStruct *) EG_alloc(memorysize*sizeof(feaDesignVariableStruct)); if ( feaProblem->feaDesignVariable == ((void*)0)) { status = -4 ; aim_status(aimInfo, status, "feaUtils.c", 8903, __func__, 3 , "AIM_ALLOC: %s size %zu type %s", "feaProblem->feaDesignVariable" , memorysize, "feaDesignVariableStruct"); goto cleanup; } }; |
8904 | |
8905 | } else { |
8906 | AIM_ERROR(aimInfo, "Number of design variable values in input tuple is 0\n"){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 8906, __func__ , "Number of design variable values in input tuple is 0\n"); }; |
8907 | return CAPS_NOTFOUND-303; |
8908 | } |
8909 | |
8910 | for (i = 0; i < feaProblem->numDesignVariable; i++) { |
8911 | status = initiate_feaDesignVariableStruct(&feaProblem->feaDesignVariable[i]); |
8912 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 8912 , __func__, 0); goto cleanup; }; |
8913 | } |
8914 | |
8915 | for (i = 0; i < feaProblem->numDesignVariable; i++) { |
8916 | |
8917 | designVariable = &feaProblem->feaDesignVariable[i]; |
8918 | |
8919 | printf("\tDesign_Variable name - %s\n", designVariableTuple[i].name); |
8920 | |
8921 | AIM_STRDUP(designVariable->name, designVariableTuple[i].name, aimInfo, status){ if (designVariable->name != ((void*)0)) { status = -4; aim_status (aimInfo, status, "feaUtils.c", 8921, __func__, 1, "AIM_STRDUP: %s != NULL!" , "designVariable->name"); goto cleanup; } designVariable-> name = EG_strdup(designVariableTuple[i].name); if (designVariable ->name == ((void*)0)) { status = -4; aim_status(aimInfo, status , "feaUtils.c", 8921, __func__, 2, "AIM_STRDUP: %s %s", "designVariable->name" , designVariableTuple[i].name); goto cleanup; } }; |
8922 | |
8923 | // Do we have a json string? |
8924 | if (json_isDict(designVariableTuple[i].value)) { |
8925 | |
8926 | /*! \page feaDesignVariable |
8927 | * \section jsonStringDesignVariable JSON String Dictionary |
8928 | * |
8929 | * If "Value" is JSON string dictionary |
8930 | * \if (NASTRAN || ASTROS || MASSTRAN) |
8931 | * (eg. "Value" = {"initialValue": 5.0, "upperBound": 10.0}) |
8932 | * \endif |
8933 | * the following keywords ( = default values) may be used: |
8934 | * |
8935 | */ |
8936 | |
8937 | /*! \page feaDesignVariable |
8938 | * |
8939 | * \if (NASTRAN || ASTROS || MASSTRAN) |
8940 | * <ul> |
8941 | * <li> <B>initialValue = 0.0</B> </li> <br> |
8942 | * Initial value for the design variable. |
8943 | * </ul> |
8944 | * \endif |
8945 | * |
8946 | */ |
8947 | keyWord = "initialValue"; |
8948 | status = json_getDouble( |
8949 | designVariableTuple[i].value, keyWord, |
8950 | &designVariable->initialValue); |
8951 | |
8952 | if (status != CAPS_SUCCESS0) { |
8953 | designVariable->initialValue = 0.0; |
8954 | } |
8955 | |
8956 | /*! \page feaDesignVariable |
8957 | * |
8958 | * \if (NASTRAN || ASTROS) |
8959 | * <ul> |
8960 | * <li> <B>lowerBound = 0.0</B> </li> <br> |
8961 | * Lower bound for the design variable. |
8962 | * </ul> |
8963 | * \endif |
8964 | */ |
8965 | keyWord = "lowerBound"; |
8966 | status = json_getDouble( |
8967 | designVariableTuple[i].value, keyWord, |
8968 | &designVariable->lowerBound); |
8969 | |
8970 | if (status != CAPS_SUCCESS0) { |
8971 | designVariable->lowerBound = 0.0; |
8972 | } |
8973 | |
8974 | /*! \page feaDesignVariable |
8975 | * |
8976 | * \if (NASTRAN || ASTROS) |
8977 | * <ul> |
8978 | * <li> <B>upperBound = 0.0</B> </li> <br> |
8979 | * Upper bound for the design variable. |
8980 | * </ul> |
8981 | * \endif |
8982 | */ |
8983 | keyWord = "upperBound"; |
8984 | status = json_getDouble( |
8985 | designVariableTuple[i].value, keyWord, |
8986 | &designVariable->upperBound); |
8987 | |
8988 | if (status != CAPS_SUCCESS0) { |
8989 | designVariable->upperBound = 0.0; |
8990 | } |
8991 | |
8992 | /*! \page feaDesignVariable |
8993 | * |
8994 | * \if (NASTRAN || ASTROS) |
8995 | * <ul> |
8996 | * <li> <B>maxDelta = 0.0</B> </li> <br> |
8997 | * Move limit for the design variable. |
8998 | * </ul> |
8999 | * \endif |
9000 | */ |
9001 | keyWord = "maxDelta"; |
9002 | status = json_getDouble( |
9003 | designVariableTuple[i].value, keyWord, |
9004 | &designVariable->maxDelta); |
9005 | |
9006 | if (status != CAPS_SUCCESS0) { |
9007 | designVariable->maxDelta = 0.0; |
9008 | } |
9009 | |
9010 | /*! \page feaDesignVariable |
9011 | * |
9012 | * \if (NASTRAN || ASTROS) |
9013 | * <ul> |
9014 | * <li> <B>discreteValue = 0.0</B> </li> <br> |
9015 | * List of discrete values to use for the design variable (e.g. [0.0,1.0,1.5,3.0]. |
9016 | * </ul> |
9017 | * \endif |
9018 | */ |
9019 | keyWord = "discreteValue"; |
9020 | status = json_getDoubleDynamicArray( |
9021 | designVariableTuple[i].value, keyWord, |
9022 | &designVariable->numDiscreteValue, &designVariable->discreteValue); |
9023 | |
9024 | if (status != CAPS_SUCCESS0) { |
9025 | designVariable->numDiscreteValue = 0; |
9026 | designVariable->discreteValue = NULL((void*)0); |
9027 | } |
9028 | |
9029 | /*! \page feaDesignVariable |
9030 | * |
9031 | * \if NASTRAN |
9032 | * <ul> |
9033 | * <li> <B>independentVariable = "(no default)"</B> </li> <br> |
9034 | * Single or list of "DesignVariable Name"s (that is the Tuple name) used to create/designate a |
9035 | * dependent design variable. |
9036 | * - independentValue = variableWeight[1] + variableWeight[2] * SUM{independentVariableWeight[i] * independentVariable[i]} |
9037 | * </ul> |
9038 | * \endif |
9039 | */ |
9040 | |
9041 | keyWord = "independentVariable"; |
9042 | status = search_jsonDictionary( designVariableTuple[i].value, keyWord, &keyValue); |
9043 | if (status == CAPS_SUCCESS0) { |
9044 | |
9045 | status = string_toStringDynamicArray(keyValue, |
9046 | &designVariable->numIndependVariable, |
9047 | &designVariable->independVariable); |
9048 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
9049 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 9049 , __func__, 0); goto cleanup; }; |
9050 | |
9051 | } |
9052 | |
9053 | /*! \page feaDesignVariable |
9054 | * |
9055 | * \if NASTRAN |
9056 | * <ul> |
9057 | * <li> <B>independentVariableWeight = 1.0 or [1.0, 1.0, ...]</B> </li> <br> |
9058 | * Single or list of weighting constants with respect to the variables set for "independentVariable". |
9059 | * If the length of this list doesn't match the length |
9060 | * of the "independentVariable" list, the list is either truncated [ >length("independentVariable")] or expanded [ <length("independentVariable")] |
9061 | * in which case the <b>last weight is repeated</b>. |
9062 | * </ul> |
9063 | * \endif |
9064 | */ |
9065 | |
9066 | keyWord = "independentVariableWeight"; |
9067 | status = search_jsonDictionary( designVariableTuple[i].value, keyWord, &keyValue); |
9068 | if (status == CAPS_SUCCESS0) { |
9069 | |
9070 | status = string_toDoubleDynamicArray(keyValue, |
9071 | &tempInteger, |
9072 | &designVariable->independVariableWeight); |
9073 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
9074 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 9074 , __func__, 0); goto cleanup; }; |
9075 | |
9076 | // We have weights, but no variables |
9077 | if (designVariable->numIndependVariable == 0) { |
9078 | |
9079 | printf("\tWeighting constants have been provided, but no independent design variables were set!\n"); |
9080 | |
9081 | // Less weights than variables |
9082 | } else if( tempInteger < designVariable->numIndependVariable) { |
9083 | |
9084 | printf("\tThe number of weighting constants provided does not match the number of independent design variables. " |
9085 | "The last weight will be repeated %d times\n", designVariable->numIndependVariable - tempInteger); |
9086 | |
9087 | AIM_REALL(designVariable->independVariableWeight,{ size_t memorysize = designVariable->numIndependVariable; designVariable->independVariableWeight = (double *) EG_reall (designVariable->independVariableWeight, memorysize*sizeof (double)); if (designVariable->independVariableWeight == ( (void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c" , 9088, __func__, 3, "AIM_REALL: %s size %zu type %s", "designVariable->independVariableWeight" , memorysize, "double"); goto cleanup; } } |
9088 | designVariable->numIndependVariable, double, aimInfo, status){ size_t memorysize = designVariable->numIndependVariable; designVariable->independVariableWeight = (double *) EG_reall (designVariable->independVariableWeight, memorysize*sizeof (double)); if (designVariable->independVariableWeight == ( (void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c" , 9088, __func__, 3, "AIM_REALL: %s size %zu type %s", "designVariable->independVariableWeight" , memorysize, "double"); goto cleanup; } }; |
9089 | |
9090 | for (j = 0; j < designVariable->numIndependVariable - tempInteger; j++) { |
9091 | |
9092 | designVariable->independVariableWeight[j+tempInteger] = designVariable->independVariableWeight[tempInteger-1]; |
9093 | } |
9094 | |
9095 | // More weights than variables |
9096 | } else if (tempInteger > designVariable->numIndependVariable) { |
9097 | |
9098 | printf("\tThe number of weighting constants provided does not match the number of independent design variables. " |
9099 | "The last %d weights will be not be used\n", tempInteger -designVariable->numIndependVariable); |
9100 | |
9101 | AIM_REALL(designVariable->independVariableWeight,{ size_t memorysize = designVariable->numIndependVariable; designVariable->independVariableWeight = (double *) EG_reall (designVariable->independVariableWeight, memorysize*sizeof (double)); if (designVariable->independVariableWeight == ( (void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c" , 9102, __func__, 3, "AIM_REALL: %s size %zu type %s", "designVariable->independVariableWeight" , memorysize, "double"); goto cleanup; } } |
9102 | designVariable->numIndependVariable, double, aimInfo, status){ size_t memorysize = designVariable->numIndependVariable; designVariable->independVariableWeight = (double *) EG_reall (designVariable->independVariableWeight, memorysize*sizeof (double)); if (designVariable->independVariableWeight == ( (void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c" , 9102, __func__, 3, "AIM_REALL: %s size %zu type %s", "designVariable->independVariableWeight" , memorysize, "double"); goto cleanup; } }; |
9103 | } |
9104 | |
9105 | } else { // No weights provided - set default value of 1.0 |
9106 | |
9107 | if (designVariable->numIndependVariable != 0) { |
9108 | AIM_ALLOC(designVariable->independVariableWeight, designVariable->numIndependVariable, double, aimInfo, status){ if (designVariable->independVariableWeight != ((void*)0) ) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 9108 , __func__, 1, "AIM_ALLOC: %s != NULL", "designVariable->independVariableWeight" ); goto cleanup; } size_t memorysize = designVariable->numIndependVariable ; designVariable->independVariableWeight = (double *) EG_alloc (memorysize*sizeof(double)); if (designVariable->independVariableWeight == ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c" , 9108, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "designVariable->independVariableWeight" , memorysize, "double"); goto cleanup; } }; |
9109 | |
9110 | for (j = 0; j < designVariable->numIndependVariable; j++) { |
9111 | designVariable->independVariableWeight[j] = 1.0; |
9112 | } |
9113 | } |
9114 | } |
9115 | |
9116 | /*! \page feaDesignVariable |
9117 | * |
9118 | * \if NASTRAN |
9119 | * <ul> |
9120 | * <li> <B>variableWeight = [1.0, 1.0]</B> </li> <br> |
9121 | * Weighting constants for a dependent variable - used if "independentVariable"(s) have been provided. |
9122 | * </ul> |
9123 | * \endif |
9124 | */ |
9125 | keyWord = "variableWeight"; |
9126 | status = search_jsonDictionary( designVariableTuple[i].value, keyWord, &keyValue); |
9127 | if (status == CAPS_SUCCESS0) { |
9128 | |
9129 | status = string_toDoubleArray(keyValue, |
9130 | 2, |
9131 | designVariable->variableWeight); |
9132 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
9133 | |
9134 | if (status != CAPS_SUCCESS0) { |
9135 | AIM_ERROR(aimInfo, "Retrieving variableWeight - status %d\n", status){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 9135, __func__ , "Retrieving variableWeight - status %d\n", status); }; |
9136 | goto cleanup; |
9137 | } |
9138 | } else { |
9139 | designVariable->variableWeight[0] = 1.0; |
9140 | designVariable->variableWeight[1] = 1.0; |
9141 | } |
9142 | |
9143 | // check if design variable relation info also included in input |
9144 | keyWord = "fieldName"; |
9145 | status = search_jsonDictionary( designVariableTuple[i].value, keyWord, &keyValue); |
9146 | |
9147 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
9148 | |
9149 | if (status != CAPS_SUCCESS0) { |
9150 | keyWord = "fieldPosition"; |
9151 | status = search_jsonDictionary( designVariableTuple[i].value, keyWord, &keyValue); |
9152 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
9153 | } |
9154 | |
9155 | if (status == CAPS_SUCCESS0) { |
9156 | |
9157 | // // The main relation associated with this design variable, if defined in input |
9158 | // AIM_REALL(feaProblem->feaDesignVariableRelation, relationIndex+1, feaDesignVariableRelationStruct, aimInfo, status); |
9159 | // |
9160 | // designVariableRelation = &feaProblem->feaDesignVariableRelation[relationIndex++]; |
9161 | // |
9162 | // feaProblem->numDesignVariableRelation = relationIndex; |
9163 | // |
9164 | // status = initiate_feaDesignVariableRelationStruct(designVariableRelation); |
9165 | // AIM_STATUS(aimInfo, status); |
9166 | // |
9167 | // printf("\tWarning: the ability to provide design variable relation data " |
9168 | // "within Design_Variable input is deprecated and " |
9169 | // "will be removed in the future. Please use provide relation data " |
9170 | // "via \"Design_Variable_Relation\" instead.\n"); |
9171 | // |
9172 | // status = fea_getDesignVariableRelationEntry( &designVariableTuple[i], designVariableRelation, |
9173 | // attrMap, feaProblem, designVariable->name); |
9174 | // AIM_STATUS(aimInfo, status); |
9175 | // |
9176 | // designVariableRelation->relationID = relationIndex; |
9177 | |
9178 | AIM_ERROR(aimInfo, "The ability to provide design variable relation data "{ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 9180, __func__ , "The ability to provide design variable relation data " "within Design_Variable input is deprecated. Please provide relation data " "via \"Design_Variable_Relation\" instead.\n"); } |
9179 | "within Design_Variable input is deprecated. Please provide relation data "{ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 9180, __func__ , "The ability to provide design variable relation data " "within Design_Variable input is deprecated. Please provide relation data " "via \"Design_Variable_Relation\" instead.\n"); } |
9180 | "via \"Design_Variable_Relation\" instead.\n"){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 9180, __func__ , "The ability to provide design variable relation data " "within Design_Variable input is deprecated. Please provide relation data " "via \"Design_Variable_Relation\" instead.\n"); }; |
9181 | status = CAPS_BADVALUE-311; |
9182 | goto cleanup; |
9183 | } |
9184 | |
9185 | |
9186 | } else { |
9187 | |
9188 | AIM_ERROR(aimInfo, "Design_Variable tuple value is expected to be a JSON string\n"){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 9188, __func__ , "Design_Variable tuple value is expected to be a JSON string\n" ); }; |
9189 | status = CAPS_BADVALUE-311; |
9190 | goto cleanup; |
9191 | |
9192 | } |
9193 | } |
9194 | |
9195 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
9196 | |
9197 | // Order the design variable ID's such that Analysis and Geometry ID's are continuous. |
9198 | // This is required by the TACS AIM |
9199 | |
9200 | designVariableID = 1; |
9201 | for( i = 0; i < feaProblem->numDesignVariable; i++) { |
9202 | |
9203 | // only analysis design variables |
9204 | if (aim_getIndex(aimInfo, feaProblem->feaDesignVariable[i].name, GEOMETRYIN) <= 0) |
9205 | feaProblem->feaDesignVariable[i].designVariableID = designVariableID++; |
9206 | } |
9207 | for( i = 0; i < feaProblem->numDesignVariable; i++) { |
9208 | |
9209 | // only geometry design variables |
9210 | if (aim_getIndex(aimInfo, feaProblem->feaDesignVariable[i].name, GEOMETRYIN) > 0) |
9211 | feaProblem->feaDesignVariable[i].designVariableID = designVariableID++; |
9212 | } |
9213 | |
9214 | // Now that we are done going through all the tuples we need to populate/create the independVaraiableID array |
9215 | // if independentVariable was set for any of them. |
9216 | for (i = 0; i < feaProblem->numDesignVariable; i++) { |
9217 | |
9218 | designVariable = &feaProblem->feaDesignVariable[i]; |
9219 | |
9220 | if (designVariable->numIndependVariable != 0) { |
9221 | |
9222 | AIM_ALLOC(designVariable->independVariableID, designVariable->numIndependVariable, int, aimInfo, status){ if (designVariable->independVariableID != ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 9222, __func__ , 1, "AIM_ALLOC: %s != NULL", "designVariable->independVariableID" ); goto cleanup; } size_t memorysize = designVariable->numIndependVariable ; designVariable->independVariableID = (int *) EG_alloc(memorysize *sizeof(int)); if (designVariable->independVariableID == ( (void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c" , 9222, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "designVariable->independVariableID" , memorysize, "int"); goto cleanup; } }; |
9223 | |
9224 | // Loop through the independent variable names |
9225 | for (j = 0; j < designVariable->numIndependVariable; j++) { |
9226 | |
9227 | // Compare the independent variable names with design variable name |
9228 | found = (int) false0; |
9229 | for (k = 0; k < feaProblem->numDesignVariable; k++) { |
9230 | if (strcasecmp(designVariable->independVariable[j], feaProblem->feaDesignVariable[k].name) == 0) { |
9231 | found = (int) true1; |
9232 | break; |
9233 | } |
9234 | } |
9235 | |
9236 | // If NOT found |
9237 | if (found != (int) true1) { |
9238 | AIM_ERROR(aimInfo, "\tDesign variable name, \"%s\", not found when searching for independent design variables for "{ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 9240, __func__ , "\tDesign variable name, \"%s\", not found when searching for independent design variables for " "variable %s!!!\n", designVariable->independVariable[j], designVariable ->name); } |
9239 | "variable %s!!!\n", designVariable->independVariable[j],{ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 9240, __func__ , "\tDesign variable name, \"%s\", not found when searching for independent design variables for " "variable %s!!!\n", designVariable->independVariable[j], designVariable ->name); } |
9240 | designVariable->name){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 9240, __func__ , "\tDesign variable name, \"%s\", not found when searching for independent design variables for " "variable %s!!!\n", designVariable->independVariable[j], designVariable ->name); }; |
9241 | status = CAPS_NOTFOUND-303; |
9242 | goto cleanup; |
9243 | } |
9244 | |
9245 | designVariable->independVariableID[j] = feaProblem->feaDesignVariable[k].designVariableID; |
9246 | } |
9247 | } |
9248 | } |
9249 | |
9250 | if (designVariableRelationTuple != NULL((void*)0)) { |
9251 | |
9252 | AIM_ALLOC(feaProblem->feaDesignVariableRelation, numDesignVariableRelationTuple, feaDesignVariableRelationStruct, aimInfo, status){ if (feaProblem->feaDesignVariableRelation != ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 9252 , __func__, 1, "AIM_ALLOC: %s != NULL", "feaProblem->feaDesignVariableRelation" ); goto cleanup; } size_t memorysize = numDesignVariableRelationTuple ; feaProblem->feaDesignVariableRelation = (feaDesignVariableRelationStruct *) EG_alloc(memorysize*sizeof(feaDesignVariableRelationStruct )); if (feaProblem->feaDesignVariableRelation == ((void*)0 )) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 9252 , __func__, 3, "AIM_ALLOC: %s size %zu type %s", "feaProblem->feaDesignVariableRelation" , memorysize, "feaDesignVariableRelationStruct"); goto cleanup ; } }; |
9253 | feaProblem->numDesignVariableRelation = numDesignVariableRelationTuple; |
9254 | |
9255 | for (i = 0; i < numDesignVariableRelationTuple; i++) { |
9256 | status = initiate_feaDesignVariableRelationStruct(&feaProblem->feaDesignVariableRelation[i]); |
9257 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 9257 , __func__, 0); goto cleanup; }; |
9258 | } |
9259 | |
9260 | // Go through design variable relations defined via 'Design_Variable_Relation' |
9261 | for (i = 0; i < numDesignVariableRelationTuple; i++) { |
9262 | |
9263 | /*! \page feaDesignVariableRelation FEA DesignVariableRelation |
9264 | * Structure for the design variable tuple = ("DesignVariableRelation Name", "Value"). |
9265 | * "DesignVariableRelation Name" defines the reference name for the design variable being specified. |
9266 | * This string will be used in the FEA input directly. The "Value" must be a JSON String dictionary |
9267 | * (see Section \ref jsonStringDesignVariableRelation). |
9268 | * |
9269 | */ |
9270 | |
9271 | designVariableRelation = &feaProblem->feaDesignVariableRelation[i]; |
9272 | |
9273 | designVariableRelation->relationID = i+1; |
9274 | |
9275 | status = fea_getDesignVariableRelationEntry( |
9276 | aimInfo, &designVariableRelationTuple[i], designVariableRelation, |
9277 | attrMap, feaProblem, NULL((void*)0) |
9278 | ); |
9279 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 9279 , __func__, 0); goto cleanup; }; |
9280 | } |
9281 | |
9282 | } |
9283 | status = fea_linkDesignVariablesAndRelations(feaProblem); |
9284 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 9284 , __func__, 0); goto cleanup; }; |
9285 | |
9286 | printf("\tNumber of design variable relations - %d\n", feaProblem->numDesignVariableRelation); |
9287 | printf("\tDone getting FEA design variables\n"); |
9288 | status = CAPS_SUCCESS0; |
9289 | |
9290 | cleanup: |
9291 | |
9292 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
9293 | |
9294 | if (groupName != NULL((void*)0)) |
9295 | string_freeArray(numGroupName, &groupName); |
9296 | |
9297 | return status; |
9298 | } |
9299 | |
9300 | int fea_getDesignVariableRelationEntry(void *aimInfo, |
9301 | capsTuple *designVariableInput, |
9302 | /*@unused@*/ feaDesignVariableRelationStruct *designVariableRelation, |
9303 | /*@unused@*/ mapAttrToIndexStruct *attrMap, |
9304 | /*@unused@*/ feaProblemStruct *feaProblem, |
9305 | /*@unused@*/ char *forceGroupName) { |
9306 | |
9307 | |
9308 | int status; //Function return |
9309 | |
9310 | int i, j; // Indexing |
9311 | |
9312 | int numLinearCoeff; |
9313 | |
9314 | char *keyValue = NULL((void*)0); |
9315 | char *keyWord = NULL((void*)0); |
9316 | |
9317 | char **groupName = NULL((void*)0); |
9318 | int numGroupName = 0; |
9319 | |
9320 | feaMeshDataStruct *feaData = NULL((void*)0); |
9321 | |
9322 | int numMaterial; |
9323 | feaMaterialStruct **materialSet = NULL((void*)0), *material; |
9324 | |
9325 | int numProperty; |
9326 | feaPropertyStruct **propertySet = NULL((void*)0), *property; |
9327 | |
9328 | int numElement; |
9329 | meshElementStruct **elementSet = NULL((void*)0), *element; |
9330 | |
9331 | printf("\tDesign_Variable_Relation name - %s\n", designVariableInput->name); |
9332 | |
9333 | designVariableRelation->name = EG_strdup(designVariableInput->name); |
9334 | |
9335 | /*! \page feaDesignVariableRelation FEA Design Variable Relations |
9336 | * \section jsonStringDesignVariableRelation JSON String Dictionary |
9337 | * |
9338 | * If "Value" is JSON string dictionary |
9339 | * \if (NASTRAN || TACS || MASSTRAN) |
9340 | * (eg. "Value" = {"componentType": "Property", "componentName": "plate", "fieldName": "TM", "variableName": "MyDesVar"}) |
9341 | * \endif |
9342 | * \if (ASTROS) |
9343 | * (eg. "Value" = {"componentType": "Property", "componentName": "plate", "variableName": "MyDesVar"}) |
9344 | * \endif |
9345 | * the following keywords ( = default values) may be used: |
9346 | * |
9347 | */ |
9348 | if (!json_isDict(designVariableInput->value)) { |
9349 | AIM_ERROR(aimInfo,{ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 9350, __func__ , "'Design_Variable_Relation' tuple value must be a JSON dictionary" ); } |
9350 | "'Design_Variable_Relation' tuple value must be a JSON dictionary"){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 9350, __func__ , "'Design_Variable_Relation' tuple value must be a JSON dictionary" ); }; |
9351 | return CAPS_BADVALUE-311; |
9352 | } |
9353 | |
9354 | /*! \page feaDesignVariableRelation |
9355 | * \if (NASTRAN || TACS || MASSTRAN) |
9356 | * <ul> |
9357 | * <li> <B>componentType = "Property"</B> </li> <br> |
9358 | * The type of component for this design variable relation. Options: "Material", "Property", "Element". |
9359 | * </ul> |
9360 | * \endif |
9361 | * \if (ASTROS) |
9362 | * <ul> |
9363 | * <li> <B>componentType = "Property"</B> </li> <br> |
9364 | * The type of component for this design variable relation. Options: "Property". |
9365 | * </ul> |
9366 | * \endif |
9367 | * |
9368 | */ |
9369 | // Get component type for design variable relation |
9370 | keyWord = "componentType"; |
9371 | status = json_getString( |
9372 | designVariableInput->value, keyWord, &keyValue); |
9373 | |
9374 | // If "componentType" not found, check "variableType" for legacy purposes |
9375 | // Warn that "variableType" is deprecated and will be removed in the future! |
9376 | if (status != CAPS_SUCCESS0) { |
9377 | |
9378 | status = json_getString( |
9379 | designVariableInput->value, "variableType", &keyValue); |
9380 | |
9381 | if (status == CAPS_SUCCESS0) { |
9382 | printf("\tWarning: \"variableType\" is deprecated and " |
9383 | "will be removed in the future. Please use \"componentType\" " |
9384 | "instead.\n"); |
9385 | } |
9386 | } |
9387 | |
9388 | if (status == CAPS_SUCCESS0) { |
9389 | |
9390 | if (strcasecmp(keyValue, "Material") == 0) designVariableRelation->componentType = MaterialDesignVar; |
9391 | else if (strcasecmp(keyValue, "Property") == 0) designVariableRelation->componentType = PropertyDesignVar; |
9392 | else if (strcasecmp(keyValue, "Element") == 0) designVariableRelation->componentType = ElementDesignVar; |
9393 | else { |
9394 | |
9395 | printf("\tUnrecognized \"%s\" specified (%s) for Design_Variable_Relation tuple %s, defaulting to \"Property\"\n", keyWord, |
9396 | keyValue, |
9397 | designVariableInput->name); |
9398 | designVariableRelation->componentType = PropertyDesignVar; |
9399 | } |
9400 | |
9401 | } |
9402 | else { |
9403 | printf("\tNo \"%s\" specified for Design_Variable_Relation tuple %s, defaulting to \"Property\"\n", keyWord, |
9404 | designVariableInput->name); |
9405 | |
9406 | designVariableRelation->componentType = PropertyDesignVar; |
9407 | } |
9408 | |
9409 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
9410 | |
9411 | /*! \page feaDesignVariableRelation |
9412 | * |
9413 | * \if (NASTRAN || TACS || MASSTRAN) |
9414 | * <ul> |
9415 | * <li> <B>componentName = "(no default)"</B> </li> <br> |
9416 | * Single or list of FEA Property(ies), or FEA Material name(s) linked |
9417 | * to the design variable relation (e.g. "Name1" or ["Name1","Name2",...]. |
9418 | * - For <c>componentType</c> Property a \ref feaProperty name (or names) is given. |
9419 | * - For <c>componentType</c> Material a \ref feaMaterial name (or names) is given. |
9420 | * \if (NASTRAN || TACS) |
9421 | * - For <c>componentType</c> Element a <c>capsGroup</c> Name (or names) is given. |
9422 | * \endif |
9423 | * </ul> |
9424 | * \endif |
9425 | * \if (ASTROS) |
9426 | * <ul> |
9427 | * <li> <B>componentName = "(no default)"</B> </li> <br> |
9428 | * Single FEA Property linked to the design variable (e.g. "Name1"). |
9429 | * - For <c>componentType</c> Property a \ref feaProperty name (or names) is given. |
9430 | * </ul> |
9431 | * \endif |
9432 | * |
9433 | */ |
9434 | keyWord = "componentName"; |
9435 | status = json_getStringDynamicArray( |
9436 | designVariableInput->value, keyWord, |
9437 | &numGroupName, &groupName); |
9438 | |
9439 | if (status != CAPS_SUCCESS0) { |
9440 | // required |
9441 | AIM_ERROR(aimInfo, "No \"%s\" specified for Design_Variable tuple %s",{ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 9442, __func__ , "No \"%s\" specified for Design_Variable tuple %s", keyWord , designVariableInput->name); } |
9442 | keyWord, designVariableInput->name){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 9442, __func__ , "No \"%s\" specified for Design_Variable tuple %s", keyWord , designVariableInput->name); }; |
9443 | goto cleanup; |
9444 | } |
9445 | |
9446 | // collect materials associated with groupName |
9447 | status = fea_findMaterialsByNames(feaProblem, numGroupName, groupName, &numMaterial, &materialSet); |
9448 | |
9449 | if (status == CAPS_SUCCESS0) { |
9450 | |
9451 | AIM_ALLOC(designVariableRelation->materialSetID, numMaterial, int, aimInfo, status){ if (designVariableRelation->materialSetID != ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 9451 , __func__, 1, "AIM_ALLOC: %s != NULL", "designVariableRelation->materialSetID" ); goto cleanup; } size_t memorysize = numMaterial; designVariableRelation ->materialSetID = (int *) EG_alloc(memorysize*sizeof(int)) ; if (designVariableRelation->materialSetID == ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 9451 , __func__, 3, "AIM_ALLOC: %s size %zu type %s", "designVariableRelation->materialSetID" , memorysize, "int"); goto cleanup; } }; |
9452 | AIM_ALLOC(designVariableRelation->materialSetType, numMaterial, int, aimInfo, status){ if (designVariableRelation->materialSetType != ((void*)0 )) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 9452 , __func__, 1, "AIM_ALLOC: %s != NULL", "designVariableRelation->materialSetType" ); goto cleanup; } size_t memorysize = numMaterial; designVariableRelation ->materialSetType = (int *) EG_alloc(memorysize*sizeof(int )); if (designVariableRelation->materialSetType == ((void* )0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 9452, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "designVariableRelation->materialSetType" , memorysize, "int"); goto cleanup; } }; |
9453 | designVariableRelation->numMaterialID = numMaterial; |
9454 | |
9455 | for (j = 0; j < numMaterial; j++) { |
9456 | |
9457 | material = materialSet[j]; |
9458 | designVariableRelation->materialSetID[j] = material->materialID; |
9459 | designVariableRelation->materialSetType[j] = material->materialType; |
9460 | |
9461 | } |
9462 | } |
9463 | |
9464 | // collect properties associated with groupName |
9465 | status = fea_findPropertiesByNames(feaProblem, numGroupName, groupName, |
9466 | &numProperty, &propertySet); |
9467 | |
9468 | if (status == CAPS_SUCCESS0) { |
9469 | |
9470 | AIM_ALLOC(designVariableRelation->propertySetID, numProperty, int, aimInfo, status){ if (designVariableRelation->propertySetID != ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 9470 , __func__, 1, "AIM_ALLOC: %s != NULL", "designVariableRelation->propertySetID" ); goto cleanup; } size_t memorysize = numProperty; designVariableRelation ->propertySetID = (int *) EG_alloc(memorysize*sizeof(int)) ; if (designVariableRelation->propertySetID == ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 9470 , __func__, 3, "AIM_ALLOC: %s size %zu type %s", "designVariableRelation->propertySetID" , memorysize, "int"); goto cleanup; } }; |
9471 | AIM_ALLOC(designVariableRelation->propertySetType, numProperty, int, aimInfo, status){ if (designVariableRelation->propertySetType != ((void*)0 )) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 9471 , __func__, 1, "AIM_ALLOC: %s != NULL", "designVariableRelation->propertySetType" ); goto cleanup; } size_t memorysize = numProperty; designVariableRelation ->propertySetType = (int *) EG_alloc(memorysize*sizeof(int )); if (designVariableRelation->propertySetType == ((void* )0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 9471, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "designVariableRelation->propertySetType" , memorysize, "int"); goto cleanup; } }; |
9472 | designVariableRelation->numPropertyID = numProperty; |
9473 | |
9474 | for (j = 0; j < numProperty; j++) { |
9475 | |
9476 | property = propertySet[j]; |
9477 | designVariableRelation->propertySetID[j] = property->propertyID; |
9478 | designVariableRelation->propertySetType[j] = property->propertyType; |
9479 | |
9480 | } |
9481 | } |
9482 | |
9483 | // collect elements associated with groupName |
9484 | status = mesh_findGroupElements( |
9485 | &feaProblem->feaMesh, attrMap, numGroupName, groupName, &numElement, &elementSet); |
9486 | |
9487 | if (status == CAPS_SUCCESS0) { |
9488 | |
9489 | AIM_ALLOC(designVariableRelation->elementSetID, numElement, int, aimInfo, status){ if (designVariableRelation->elementSetID != ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 9489, __func__, 1, "AIM_ALLOC: %s != NULL", "designVariableRelation->elementSetID" ); goto cleanup; } size_t memorysize = numElement; designVariableRelation ->elementSetID = (int *) EG_alloc(memorysize*sizeof(int)); if (designVariableRelation->elementSetID == ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 9489, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "designVariableRelation->elementSetID" , memorysize, "int"); goto cleanup; } }; |
9490 | AIM_ALLOC(designVariableRelation->elementSetType, numElement, int, aimInfo, status){ if (designVariableRelation->elementSetType != ((void*)0) ) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 9490 , __func__, 1, "AIM_ALLOC: %s != NULL", "designVariableRelation->elementSetType" ); goto cleanup; } size_t memorysize = numElement; designVariableRelation ->elementSetType = (int *) EG_alloc(memorysize*sizeof(int) ); if (designVariableRelation->elementSetType == ((void*)0 )) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 9490 , __func__, 3, "AIM_ALLOC: %s size %zu type %s", "designVariableRelation->elementSetType" , memorysize, "int"); goto cleanup; } }; |
9491 | AIM_ALLOC(designVariableRelation->elementSetSubType, numElement, int, aimInfo, status){ if (designVariableRelation->elementSetSubType != ((void* )0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 9491, __func__, 1, "AIM_ALLOC: %s != NULL", "designVariableRelation->elementSetSubType" ); goto cleanup; } size_t memorysize = numElement; designVariableRelation ->elementSetSubType = (int *) EG_alloc(memorysize*sizeof(int )); if (designVariableRelation->elementSetSubType == ((void *)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c" , 9491, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "designVariableRelation->elementSetSubType" , memorysize, "int"); goto cleanup; } }; |
9492 | designVariableRelation->numElementID = numElement; |
9493 | |
9494 | for (j = 0; j < numElement; j++) { |
9495 | |
9496 | element = elementSet[j]; |
9497 | designVariableRelation->elementSetID[j] = element->elementID; |
9498 | designVariableRelation->elementSetType[j] = element->elementType; |
9499 | feaData = (feaMeshDataStruct *) element->analysisData; |
9500 | designVariableRelation->elementSetSubType[j] = feaData->elementSubType; |
9501 | |
9502 | } |
9503 | } |
9504 | |
9505 | if (groupName != NULL((void*)0)) |
9506 | string_freeArray(numGroupName, &groupName); |
9507 | numGroupName = 0; |
9508 | groupName = NULL((void*)0); |
9509 | |
9510 | AIM_FREE(materialSet){ EG_free(materialSet); materialSet = ((void*)0); }; |
9511 | AIM_FREE(propertySet){ EG_free(propertySet); propertySet = ((void*)0); }; |
9512 | AIM_FREE(elementSet){ EG_free(elementSet); elementSet = ((void*)0); }; |
9513 | |
9514 | /*! \page feaDesignVariableRelation |
9515 | * |
9516 | * \if (NASTRAN || TACS || MASSTRAN) |
9517 | * <ul> |
9518 | * <li> <B>variableName = "(no default)"</B> </li> <br> |
9519 | * Single or list of names of design variables linked to this relation |
9520 | * </ul> |
9521 | * \endif |
9522 | * \if (ASTROS) |
9523 | * <ul> |
9524 | * <li> <B>variableName = "(no default)"</B> </li> <br> |
9525 | * Name of design variable linked to this relation |
9526 | * </ul> |
9527 | * \endif |
9528 | */ |
9529 | keyWord = "variableName"; |
9530 | status = json_getStringDynamicArray( |
9531 | designVariableInput->value, keyWord, |
9532 | &designVariableRelation->numDesignVariable, &designVariableRelation->designVariableNameSet); |
9533 | if (status != CAPS_SUCCESS0) { |
9534 | // required |
9535 | AIM_ERROR(aimInfo, "No \"%s\" specified for Design_Variable_Relation tuple %s",{ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 9536, __func__ , "No \"%s\" specified for Design_Variable_Relation tuple %s" , keyWord, designVariableInput->name); } |
9536 | keyWord, designVariableInput->name){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 9536, __func__ , "No \"%s\" specified for Design_Variable_Relation tuple %s" , keyWord, designVariableInput->name); }; |
9537 | goto cleanup; |
9538 | } |
9539 | |
9540 | /*! \page feaDesignVariableRelation |
9541 | * |
9542 | * \if (NASTRAN || TACS || MASSTRAN) |
9543 | * <ul> |
9544 | * <li> <B>fieldName = "(no default)"</B> </li> <br> |
9545 | * Fieldname of variable relation (e.g. "E" for Young's Modulus). Design Variable Relations can be defined as three types based on the <c>variableType</c> value. |
9546 | * These are Material, Property, or Element. This means that an aspect of a material, property, or element input can change in the optimization problem. This input |
9547 | * specifies what aspect of the Material, Property, or Element is changing. |
9548 | * \if (MASSTRAN) |
9549 | * -# <b> Material Types</b> Selected based on the material type (see \ref feaMaterial, materialType) referenced in the <c>componentName</c> above. |
9550 | * - <c> materialType = "Isotropic" </c> |
9551 | * - "density" |
9552 | * -# <b> Property Types</b> (see \ref feaProperty) |
9553 | * - <c>propertyType = "ConcentratedMass"</c> |
9554 | * - "mass", |
9555 | * - "massOffset1", "massOffset2", "massOffset2" |
9556 | * - "Ixx", "Iyy", "Izz", "Ixy", "Ixz", "Iyz" |
9557 | * - <c>propertyType = "Shell"</c> |
9558 | * - "membraneThickness", "massPerArea" |
9559 | * \else |
9560 | * -# <b> Material Types</b> Selected based on the material type (see \ref feaMaterial, materialType) referenced in the <c>componentName</c> above. |
9561 | * - <c><b> MAT1</b>, materialType = "Isotropic" </c> |
9562 | * - "E", "G", "NU", "RHO", "A" |
9563 | * - <c><b> MAT2</b>, materialType = "Anisothotropic" </c> |
9564 | * - "G11", "G12", "G13", "G22", "G23", "G33", "RHO", "A1", "A2", "A3" |
9565 | * - <c><b> MAT8</b>, materialType = "Orthotropic" </c> |
9566 | * - "E1", "E2", "NU12", "G12", "G1Z", "G2Z", "RHO", "A1", "A2" |
9567 | * - <c><b> MAT9</b>, materialType = "Anisotropic" </c> |
9568 | * - "G11", "G12", "G13", "G14", "G15", "G16" |
9569 | * - "G22", "G23", "G24", "G25", "G26" |
9570 | * - "G33", "G34", "G35", "G36" |
9571 | * - "G44", "G45", "G46" |
9572 | * - "G55", "G56", "G66" |
9573 | * - "RHO", "A1", "A2", "A3", "A4", "A5", "A6" |
9574 | * -# <b> Property Types</b> (see \ref feaProperty) |
9575 | * - <c><b> PROD</b> </c> <c>propertyType = "Rod"</c> |
9576 | * - "A", "J" |
9577 | * - <c><b> PBAR</b> </c> <c>propertyType = "Bar"</c> |
9578 | * - "A", "I1", "I2", "J" |
9579 | * - <c><b> PSHELL</b> </c> <c>propertyType = "Shell"</c> |
9580 | * - "T" |
9581 | * - <c><b> PCOMP</b> </c> <c>propertyType = "Composite"</c> |
9582 | * - "T1", "THETA1", "T2", "THETA2", ... "Ti", "THETAi" |
9583 | * - <c><b> PSOLID</b> </c> <c>propertyType = "Solid"</c> |
9584 | * - not supported |
9585 | * -# <b> Element Types</b> |
9586 | * - <c><b> CTRIA3, CQUAD4</b> </c> <c>propertyType = "Shell"</c> |
9587 | * - "ZOFFS" |
9588 | * \endif |
9589 | * </ul> |
9590 | * \endif |
9591 | */ |
9592 | keyWord = "fieldName"; |
9593 | status = json_getString( |
9594 | designVariableInput->value, keyWord, |
9595 | &designVariableRelation->fieldName); |
9596 | if (status != CAPS_SUCCESS0) { |
9597 | // optional |
9598 | } |
9599 | |
9600 | /*! \page feaDesignVariableRelation |
9601 | * |
9602 | * \if (NASTRAN || TACS) |
9603 | * <ul> |
9604 | * <li> <B>fieldPosition = 0</B> </li> <br> |
9605 | * This input is ignored if not defined. The user may use this field instead of the <c>fieldName</c> input defined above to |
9606 | * relate design variables and property, material, or elements. This requires knowledge of Nastran bulk data input format for material, |
9607 | * property, and element input cards. |
9608 | * </ul> |
9609 | * \endif |
9610 | */ |
9611 | |
9612 | keyWord = "fieldPosition"; |
9613 | status = json_getInteger( |
9614 | designVariableInput->value, keyWord, |
9615 | &designVariableRelation->fieldPosition); |
9616 | if (status != CAPS_SUCCESS0) { |
9617 | // optional |
9618 | } |
9619 | |
9620 | /*! \page feaDesignVariableRelation |
9621 | * |
9622 | * \if (NASTRAN || TACS || ASTROS || MASSTRAN) |
9623 | * <ul> |
9624 | * <li> <B>constantCoeff = 0.0</B> </li> <br> |
9625 | * Constant term of relation. |
9626 | * </ul> |
9627 | * \endif |
9628 | */ |
9629 | keyWord = "constantCoeff"; |
9630 | status = json_getDouble( |
9631 | designVariableInput->value, keyWord, |
9632 | &designVariableRelation->constantRelationCoeff); |
9633 | if (status != CAPS_SUCCESS0) { |
9634 | // default |
9635 | designVariableRelation->constantRelationCoeff = 0.0; |
9636 | } |
9637 | |
9638 | /*! \page feaDesignVariableRelation |
9639 | * |
9640 | * \if (NASTRAN || TACS || ASTROS || MASSTRAN) |
9641 | * <ul> |
9642 | * <li> <B>linearCoeff = 1.0</B> </li> <br> |
9643 | * Single or list of coefficients of linear relation. Must be same length as <c>variableName</c>. |
9644 | * </ul> |
9645 | * \endif |
9646 | */ |
9647 | keyWord = "linearCoeff"; |
9648 | status = json_getDoubleDynamicArray( |
9649 | designVariableInput->value, keyWord, |
9650 | &numLinearCoeff, &designVariableRelation->linearRelationCoeff); |
9651 | |
9652 | if (status != CAPS_SUCCESS0) { |
9653 | // default |
9654 | numLinearCoeff = designVariableRelation->numDesignVariable; |
9655 | designVariableRelation->linearRelationCoeff = EG_alloc(numLinearCoeff * sizeof(double)); |
9656 | if (designVariableRelation->linearRelationCoeff == NULL((void*)0)) { |
9657 | status = EGADS_MALLOC-4; |
9658 | goto cleanup; |
9659 | } |
9660 | |
9661 | for (i = 0; i < numLinearCoeff; i++) { |
9662 | designVariableRelation->linearRelationCoeff[i] = 1.0; |
9663 | } |
9664 | } |
9665 | |
9666 | if (numLinearCoeff != designVariableRelation->numDesignVariable) { |
9667 | AIM_ERROR(aimInfo, "Number of \"linearCoeff\" values (%d) does not match"{ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 9669, __func__ , "Number of \"linearCoeff\" values (%d) does not match" " number of \"variableName\" values (%d)" , numLinearCoeff, designVariableRelation->numDesignVariable ); } |
9668 | " number of \"variableName\" values (%d)",{ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 9669, __func__ , "Number of \"linearCoeff\" values (%d) does not match" " number of \"variableName\" values (%d)" , numLinearCoeff, designVariableRelation->numDesignVariable ); } |
9669 | numLinearCoeff, designVariableRelation->numDesignVariable){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 9669, __func__ , "Number of \"linearCoeff\" values (%d) does not match" " number of \"variableName\" values (%d)" , numLinearCoeff, designVariableRelation->numDesignVariable ); }; |
9670 | status = CAPS_BADVALUE-311; |
9671 | goto cleanup; |
9672 | } |
9673 | |
9674 | status = CAPS_SUCCESS0; |
9675 | |
9676 | cleanup: |
9677 | |
9678 | AIM_FREE(keyValue){ EG_free(keyValue); keyValue = ((void*)0); }; |
9679 | |
9680 | return status; |
9681 | } |
9682 | |
9683 | // Get the design constraints from a capsTuple |
9684 | int fea_getDesignConstraint(int numDesignConstraintTuple, |
9685 | capsTuple designConstraintTuple[], |
9686 | feaProblemStruct *feaProblem) { |
9687 | |
9688 | /*! \page feaDesignConstraint FEA Design Constraints |
9689 | * Structure for the design constraint tuple = (`DesignConstraint Name', `Value'). |
9690 | * 'DesignConstraint Name' defines the reference name for the design constraint being specified. |
9691 | * The "Value" must be a JSON String dictionary (see Section \ref jsonStringDesignConstraint). |
9692 | */ |
9693 | |
9694 | int status; //Function return |
9695 | |
9696 | int i, groupIndex, attrIndex; // Indexing |
9697 | |
9698 | char *keyValue = NULL((void*)0); |
9699 | char *keyWord = NULL((void*)0); |
9700 | |
9701 | char *tempString = NULL((void*)0); |
9702 | |
9703 | char **groupName = NULL((void*)0); |
9704 | int numGroupName = 0; |
9705 | |
9706 | // Destroy our design constraints structures coming in if aren't 0 and NULL already |
9707 | if (feaProblem->feaDesignConstraint != NULL((void*)0)) { |
9708 | for (i = 0; i < feaProblem->numDesignConstraint; i++) { |
9709 | status = destroy_feaDesignConstraintStruct(&feaProblem->feaDesignConstraint[i]); |
9710 | if (status != CAPS_SUCCESS0) return status; |
9711 | } |
9712 | } |
9713 | if (feaProblem->feaDesignConstraint != NULL((void*)0)) EG_free(feaProblem->feaDesignConstraint); |
9714 | feaProblem->feaDesignConstraint = NULL((void*)0); |
9715 | feaProblem->numDesignConstraint = 0; |
9716 | |
9717 | printf("\nGetting FEA design constraints.......\n"); |
9718 | |
9719 | feaProblem->numDesignConstraint = numDesignConstraintTuple; |
9720 | |
9721 | printf("\tNumber of design constraints - %d\n", feaProblem->numDesignConstraint); |
9722 | |
9723 | if (feaProblem->numDesignConstraint > 0) { |
9724 | feaProblem->feaDesignConstraint = (feaDesignConstraintStruct *) EG_alloc(feaProblem->numDesignConstraint * sizeof(feaDesignConstraintStruct)); |
9725 | |
9726 | if (feaProblem->feaDesignConstraint == NULL((void*)0)) return EGADS_MALLOC-4; |
9727 | |
9728 | } else { |
9729 | printf("\tNumber of design constraint values in input tuple is 0\n"); |
9730 | return CAPS_NOTFOUND-303; |
9731 | } |
9732 | |
9733 | for (i = 0; i < feaProblem->numDesignConstraint; i++) { |
9734 | status = initiate_feaDesignConstraintStruct(&feaProblem->feaDesignConstraint[i]); |
9735 | if (status != CAPS_SUCCESS0) return status; |
9736 | } |
9737 | |
9738 | for (i = 0; i < feaProblem->numDesignConstraint; i++) { |
9739 | |
9740 | printf("\tDesign_Constraint name - %s\n", designConstraintTuple[i].name); |
9741 | |
9742 | feaProblem->feaDesignConstraint[i].name = (char *) EG_alloc(((strlen(designConstraintTuple[i].name)) + 1)*sizeof(char)); |
9743 | if (feaProblem->feaDesignConstraint[i].name == NULL((void*)0)) return EGADS_MALLOC-4; |
9744 | |
9745 | memcpy(feaProblem->feaDesignConstraint[i].name, designConstraintTuple[i].name, strlen(designConstraintTuple[i].name)*sizeof(char)); |
9746 | feaProblem->feaDesignConstraint[i].name[strlen(designConstraintTuple[i].name)] = '\0'; |
9747 | |
9748 | feaProblem->feaDesignConstraint[i].designConstraintID = i + 1; |
9749 | |
9750 | // Do we have a json string? |
9751 | if (strncmp(designConstraintTuple[i].value, "{", 1) == 0) { |
9752 | //printf("JSON String - %s\n", designConstraintTuple[i].value); |
9753 | |
9754 | /*! \page feaDesignConstraint |
9755 | * \section jsonStringDesignConstraint JSON String Dictionary |
9756 | * |
9757 | * If "Value" is JSON string dictionary |
9758 | * \if (NASTRAN || ASTROS) |
9759 | * (eg. "Value" = {"groupName": "plate", "upperBound": 10.0}) |
9760 | * \endif |
9761 | * the following keywords ( = default values) may be used: |
9762 | * |
9763 | * \if (NASTRAN || ASTROS) |
9764 | * <ul> |
9765 | * <li> <B>groupName = "(no default)"</B> </li> <br> |
9766 | * Single or list of <c>capsGroup</c> name(s) |
9767 | * to the design variable (e.g. "Name1" or ["Name1","Name2",...].The property (see \ref feaProperty) also |
9768 | * assigned to the same <c>capsGroup</c> will be automatically related to this constraint entry. |
9769 | * </ul> |
9770 | * \endif |
9771 | * |
9772 | */ |
9773 | |
9774 | // Get material/properties that the design constraint should be applied to |
9775 | keyWord = "groupName"; |
9776 | status = search_jsonDictionary( designConstraintTuple[i].value, keyWord, &keyValue); |
9777 | if (status == CAPS_SUCCESS0) { |
9778 | |
9779 | status = string_toStringDynamicArray(keyValue, &numGroupName, &groupName); |
9780 | if (keyValue != NULL((void*)0)) { |
9781 | EG_free(keyValue); |
9782 | keyValue = NULL((void*)0); |
9783 | } |
9784 | |
9785 | if (status != CAPS_SUCCESS0) return status; |
9786 | |
9787 | feaProblem->feaDesignConstraint[i].numPropertyID = 0; |
9788 | for (groupIndex = 0; groupIndex < numGroupName; groupIndex++) { |
9789 | |
9790 | for (attrIndex = 0; attrIndex < feaProblem->numProperty; attrIndex++) { |
9791 | |
9792 | if (strcasecmp(feaProblem->feaProperty[attrIndex].name, groupName[groupIndex]) == 0) { |
9793 | |
9794 | feaProblem->feaDesignConstraint[i].numPropertyID += 1; |
9795 | |
9796 | if (feaProblem->feaDesignConstraint[i].numPropertyID == 1) { |
9797 | |
9798 | feaProblem->feaDesignConstraint[i].propertySetID = (int *) EG_alloc(feaProblem->feaDesignConstraint[i].numPropertyID *sizeof(int)); |
9799 | feaProblem->feaDesignConstraint[i].propertySetType = (int *) EG_alloc(feaProblem->feaDesignConstraint[i].numPropertyID *sizeof(int)); |
9800 | |
9801 | } else { |
9802 | |
9803 | feaProblem->feaDesignConstraint[i].propertySetID = (int *) EG_reall(feaProblem->feaDesignConstraint[i].propertySetID, |
9804 | feaProblem->feaDesignConstraint[i].numPropertyID *sizeof(int)); |
9805 | feaProblem->feaDesignConstraint[i].propertySetType = (int *) EG_reall(feaProblem->feaDesignConstraint[i].propertySetType, |
9806 | feaProblem->feaDesignConstraint[i].numPropertyID *sizeof(int)); |
9807 | |
9808 | } |
9809 | |
9810 | if (feaProblem->feaDesignConstraint[i].propertySetID == NULL((void*)0) || |
9811 | feaProblem->feaDesignConstraint[i].propertySetType == NULL((void*)0) ) { |
9812 | |
9813 | status = string_freeArray(numGroupName, &groupName); |
9814 | if (status != CAPS_SUCCESS0) return status; |
9815 | groupName = NULL((void*)0); |
9816 | return EGADS_MALLOC-4; |
9817 | } |
9818 | |
9819 | feaProblem->feaDesignConstraint[i].propertySetID[feaProblem->feaDesignConstraint[i].numPropertyID-1] = feaProblem->feaProperty[attrIndex].propertyID; |
9820 | feaProblem->feaDesignConstraint[i].propertySetType[feaProblem->feaDesignConstraint[i].numPropertyID-1] = feaProblem->feaProperty[attrIndex].propertyType; |
9821 | |
9822 | break; |
9823 | } |
9824 | } |
9825 | |
9826 | if (feaProblem->feaDesignConstraint[i].numPropertyID != groupIndex+1) { |
9827 | |
9828 | printf("\tWarning: DesignConstraint property name, %s, not found in feaProperty structure\n", groupName[groupIndex]); |
9829 | |
9830 | } |
9831 | } |
9832 | |
9833 | status = string_freeArray(numGroupName, &groupName); |
9834 | if (status != CAPS_SUCCESS0) return status; |
9835 | groupName = NULL((void*)0); |
9836 | } |
9837 | |
9838 | //Fill up designConstraint properties |
9839 | /*! \page feaDesignConstraint |
9840 | * |
9841 | * \if (NASTRAN || ASTROS) |
9842 | * <ul> |
9843 | * <li> <B> constraintType = "Property" </B> </li> <br> |
9844 | * The type of design constraint. Options: "Property", "Flutter" |
9845 | * </ul> |
9846 | * \endif |
9847 | */ |
9848 | keyWord = "constraintType"; |
9849 | status = json_getString( |
9850 | designConstraintTuple[i].value, keyWord, &keyValue); |
9851 | if (status == CAPS_SUCCESS0) { |
9852 | if (strcasecmp(keyValue, "Property") == 0) |
9853 | feaProblem->feaDesignConstraint[i].designConstraintType = PropertyDesignCon; |
9854 | else if (strcasecmp(keyValue, "Flutter") == 0) |
9855 | feaProblem->feaDesignConstraint[i].designConstraintType = FlutterDesignCon; |
9856 | else { |
9857 | PRINT_WARNING("Unknown constraintType %s... defaulting to Property.", keyValue)fprintf(stderr, "[ WARNING ] " "Unknown constraintType %s... defaulting to Property." "\n", keyValue);; |
9858 | feaProblem->feaDesignConstraint[i].designConstraintType = PropertyDesignCon; |
9859 | } |
9860 | } |
9861 | else { |
9862 | feaProblem->feaDesignConstraint[i].designConstraintType = PropertyDesignCon; |
9863 | } |
9864 | |
9865 | if (keyValue != NULL((void*)0)) EG_free(keyValue); |
9866 | keyValue = NULL((void*)0); |
9867 | |
9868 | /*! \page feaDesignConstraint |
9869 | * |
9870 | * \if (NASTRAN || ASTROS) |
9871 | * <ul> |
9872 | * <li> <B>lowerBound = 0.0</B> </li> <br> |
9873 | * Lower bound for the design constraint. |
9874 | * </ul> |
9875 | * \endif |
9876 | * |
9877 | */ |
9878 | keyWord = "lowerBound"; |
9879 | status = search_jsonDictionary( designConstraintTuple[i].value, keyWord, &keyValue); |
9880 | if (status == CAPS_SUCCESS0) { |
9881 | |
9882 | status = string_toDouble(keyValue, &feaProblem->feaDesignConstraint[i].lowerBound); |
9883 | if (keyValue != NULL((void*)0)) { |
9884 | EG_free(keyValue); |
9885 | keyValue = NULL((void*)0); |
9886 | } |
9887 | if (status != CAPS_SUCCESS0) return status; |
9888 | } |
9889 | |
9890 | /*! \page feaDesignConstraint |
9891 | * |
9892 | * \if (NASTRAN || ASTROS) |
9893 | * <ul> |
9894 | * <li> <B>upperBound = 0.0</B> </li> <br> |
9895 | * Upper bound for the design constraint. |
9896 | * </ul> |
9897 | * \endif |
9898 | * |
9899 | */ |
9900 | keyWord = "upperBound"; |
9901 | status = search_jsonDictionary( designConstraintTuple[i].value, keyWord, &keyValue); |
9902 | if (status == CAPS_SUCCESS0) { |
9903 | |
9904 | status = string_toDouble(keyValue, &feaProblem->feaDesignConstraint[i].upperBound); |
9905 | if (keyValue != NULL((void*)0)) { |
9906 | EG_free(keyValue); |
9907 | keyValue = NULL((void*)0); |
9908 | } |
9909 | if (status != CAPS_SUCCESS0) return status; |
9910 | } |
9911 | |
9912 | /*! \page feaDesignConstraint |
9913 | * |
9914 | * \if (NASTRAN || ASTROS) |
9915 | * <ul> |
9916 | * <li> <B>responseType = "(no default)"</B> </li> <br> |
9917 | * Response type options for DRESP1 Entry (see Nastran manual). |
9918 | * - Implemented Options |
9919 | * -# <c>STRESS</c>, for <c>propertyType = "Rod" or "Shell"</c> (see \ref feaProperty) |
9920 | * -# <c>CFAILURE</c>, for <c>propertyType = "Composite"</c> (see \ref feaProperty) |
9921 | * </ul> |
9922 | * \endif |
9923 | * |
9924 | */ |
9925 | keyWord = "responseType"; |
9926 | status = search_jsonDictionary( designConstraintTuple[i].value, keyWord, &keyValue); |
9927 | if (status == CAPS_SUCCESS0) { |
9928 | |
9929 | tempString = string_removeQuotation(keyValue); |
9930 | |
9931 | feaProblem->feaDesignConstraint[i].responseType = EG_alloc((strlen(tempString) + 1)*sizeof(char)); |
9932 | if(feaProblem->feaDesignConstraint[i].responseType == NULL((void*)0)) { |
9933 | if (tempString != NULL((void*)0)) EG_free(tempString); |
9934 | |
9935 | return EGADS_MALLOC-4; |
9936 | } |
9937 | |
9938 | memcpy(feaProblem->feaDesignConstraint[i].responseType, tempString, strlen(tempString)*sizeof(char)); |
9939 | feaProblem->feaDesignConstraint[i].responseType[strlen(tempString)] = '\0'; |
9940 | |
9941 | if (keyValue != NULL((void*)0)) { |
9942 | EG_free(keyValue); |
9943 | keyValue = NULL((void*)0); |
9944 | } |
9945 | |
9946 | if (tempString != NULL((void*)0)) { |
9947 | EG_free(tempString); |
9948 | tempString = NULL((void*)0); |
9949 | } |
9950 | } |
9951 | |
9952 | /*! \page feaDesignConstraint |
9953 | * |
9954 | * \if (NASTRAN || ASTROS) |
9955 | * <ul> |
9956 | * <li> <B>fieldName = "(no default)"</B> </li> <br> |
9957 | * For constraints, this field is only used currently when applying constraints to composites. This field is used to identify |
9958 | * the specific lamina in a stacking sequence that a constraint is being applied too. Note if the user has design variables |
9959 | * for both THEATA1 and T1 it is likely that only a single constraint on the first lamina is required. For this reason, the user |
9960 | * can simply enter LAMINA1 in addition to the possible entries defined in the \ref feaDesignVariable section. |
9961 | * Additionally, the <c>fieldPosition</c> integer entry below can be used. In this case <c>"LAMINA1" = 1</c>. |
9962 | * |
9963 | * * -# <b> Property Types</b> (see \ref feaProperty) |
9964 | * - <c><b> PCOMP</b> </c> <c>propertyType = "Composite"</c> |
9965 | * - "T1", "THETA1", "T2", "THETA2", ... "Ti", "THETAi" |
9966 | * - "LAMINA1", "LAMINA2", ... "LAMINAi" |
9967 | * |
9968 | * </ul> |
9969 | * \endif |
9970 | */ |
9971 | |
9972 | keyWord = "fieldName"; |
9973 | status = search_jsonDictionary( designConstraintTuple[i].value, keyWord, &keyValue); |
9974 | if (status == CAPS_SUCCESS0) { |
9975 | |
9976 | tempString = string_removeQuotation(keyValue); |
9977 | |
9978 | feaProblem->feaDesignConstraint[i].fieldName = EG_alloc((strlen(tempString) + 1)*sizeof(char)); |
9979 | if(feaProblem->feaDesignConstraint[i].fieldName == NULL((void*)0)) { |
9980 | if (tempString != NULL((void*)0)) EG_free(tempString); |
9981 | |
9982 | return EGADS_MALLOC-4; |
9983 | } |
9984 | |
9985 | memcpy(feaProblem->feaDesignConstraint[i].fieldName, tempString, strlen(tempString)*sizeof(char)); |
9986 | feaProblem->feaDesignConstraint[i].fieldName[strlen(tempString)] = '\0'; |
9987 | |
9988 | if (keyValue != NULL((void*)0)) { |
9989 | EG_free(keyValue); |
9990 | keyValue = NULL((void*)0); |
9991 | } |
9992 | |
9993 | if (tempString != NULL((void*)0)) { |
9994 | EG_free(tempString); |
9995 | tempString = NULL((void*)0); |
9996 | } |
9997 | } |
9998 | |
9999 | /*! \page feaDesignConstraint |
10000 | * |
10001 | * \if (NASTRAN || ASTROS) |
10002 | * <ul> |
10003 | * <li> <B>fieldPosition = 0</B> </li> <br> |
10004 | * This input is ignored if not defined. The user may use this field instead of the <c>fieldName</c> input defined above to |
10005 | * identify a specific lamina in a composite stacking sequence where a constraint is applied. Please read the <c>fieldName</c> |
10006 | * information above for more information. |
10007 | * </ul> |
10008 | * \endif |
10009 | */ |
10010 | |
10011 | keyWord = "fieldPosition"; |
10012 | status = search_jsonDictionary( designConstraintTuple[i].value, keyWord, &keyValue); |
10013 | if (status == CAPS_SUCCESS0) { |
10014 | |
10015 | status = string_toInteger(keyValue, &feaProblem->feaDesignConstraint[i].fieldPosition); |
10016 | if (keyValue != NULL((void*)0)) { |
10017 | EG_free(keyValue); |
10018 | keyValue = NULL((void*)0); |
10019 | } |
10020 | if (status != CAPS_SUCCESS0) return status; |
10021 | } |
10022 | |
10023 | /*! \page feaDesignConstraint |
10024 | * |
10025 | * \if ASTROS |
10026 | * <ul> |
10027 | * <li> <B>velocityType = "TRUE" </B> </li> <br> |
10028 | * The nature of the velocity values defined with "velocity" keyword. Can be either "TRUE" for true velocity |
10029 | * or "EQUIV" for equivalent air speed. |
10030 | * </ul> |
10031 | * \endif |
10032 | */ |
10033 | keyWord = "velocityType"; |
10034 | status = json_getString( |
10035 | designConstraintTuple[i].value, keyWord, |
10036 | &feaProblem->feaDesignConstraint[i].velocityType); |
10037 | if (status != CAPS_SUCCESS0) { |
10038 | feaProblem->feaDesignConstraint[i].velocityType = EG_strdup("TRUE"); |
10039 | } |
10040 | |
10041 | /*! \page feaDesignConstraint |
10042 | * |
10043 | * \if ASTROS |
10044 | * <ul> |
10045 | * <li> <B>scalingFactor = 0.10 </B> </li> <br> |
10046 | * The constraint scaling factor. |
10047 | * </ul> |
10048 | * \endif |
10049 | */ |
10050 | keyWord = "scalingFactor"; |
10051 | status = json_getDouble( |
10052 | designConstraintTuple[i].value, keyWord, |
10053 | &feaProblem->feaDesignConstraint[i].scalingFactor); |
10054 | if (status != CAPS_SUCCESS0) { |
10055 | feaProblem->feaDesignConstraint[i].scalingFactor = 0.10; |
10056 | } |
10057 | |
10058 | /*! \page feaDesignConstraint |
10059 | * |
10060 | * \if ASTROS |
10061 | * <ul> |
10062 | * <li> <B>velocity = (No Default) </B> </li> <br> |
10063 | * The velocity values for flutter constraint. |
10064 | * Must be an array with equal length to defined "damping" values. |
10065 | * </ul> |
10066 | * \endif |
10067 | */ |
10068 | keyWord = "velocity"; |
10069 | status = json_getDoubleDynamicArray( |
10070 | designConstraintTuple[i].value, keyWord, |
10071 | &feaProblem->feaDesignConstraint[i].numVelocity, |
10072 | &feaProblem->feaDesignConstraint[i].velocity); |
10073 | if (status != CAPS_SUCCESS0) { |
10074 | // only required if constraintType == FlutterCon |
10075 | } |
10076 | |
10077 | /*! \page feaDesignConstraint |
10078 | * |
10079 | * \if ASTROS |
10080 | * <ul> |
10081 | * <li> <B>damping = (No Default) </B> </li> <br> |
10082 | * The damping values for flutter constraint. |
10083 | * Must be an array with equal length to defined "velocity" values. |
10084 | * </ul> |
10085 | * \endif |
10086 | */ |
10087 | keyWord = "damping"; |
10088 | status = json_getDoubleDynamicArray( |
10089 | designConstraintTuple[i].value, keyWord, |
10090 | &feaProblem->feaDesignConstraint[i].numDamping, |
10091 | &feaProblem->feaDesignConstraint[i].damping); |
10092 | if (status != CAPS_SUCCESS0) { |
10093 | // only required if constraintType == FlutterCon |
10094 | } |
10095 | |
10096 | } else { |
10097 | |
10098 | printf("\tError: Design_Constraint tuple value is expected to be a JSON string\n"); |
10099 | return CAPS_BADVALUE-311; |
10100 | // CALL designConstraint look up |
10101 | |
10102 | } |
10103 | } |
10104 | |
10105 | if (keyValue != NULL((void*)0)) { |
10106 | EG_free(keyValue); |
10107 | keyValue = NULL((void*)0); |
10108 | } |
10109 | |
10110 | printf("Done getting FEA design constraints\n"); |
10111 | return CAPS_SUCCESS0; |
10112 | } |
10113 | |
10114 | // Get the design constraints from a capsTuple |
10115 | int fea_getOptimizationControl(char *optimizationControlInput, |
10116 | feaProblemStruct *feaProblem) { |
10117 | |
10118 | /*! \page feaOptimizationControl FEA Optimization Control |
10119 | * Structure for the optimization control dictionary = `Value'. |
10120 | * The "Value" must be a JSON String dictionary (see Section \ref jsonStringDesignConstraint). |
10121 | */ |
10122 | |
10123 | int status; //Function return |
10124 | |
10125 | char *keyValue = NULL((void*)0); |
10126 | char *keyWord = NULL((void*)0); |
10127 | |
10128 | // Destroy our optimization control structures coming in if aren't 0 and NULL already |
10129 | status = destroy_feaOptimzationControlStruct(&feaProblem->feaOptimizationControl); |
10130 | if (status != CAPS_SUCCESS0) return status; |
10131 | |
10132 | printf("\nGetting FEA optimization control.......\n"); |
10133 | |
10134 | status = initiate_feaOptimizationControlStruct(&feaProblem->feaOptimizationControl); |
10135 | if (status != CAPS_SUCCESS0) return status; |
10136 | |
10137 | if (optimizationControlInput == NULL((void*)0)) { |
10138 | optimizationControlInput = "{}"; |
10139 | } |
10140 | |
10141 | // Do we have a json string? |
10142 | if (strncmp(optimizationControlInput, "{", 1) == 0) { |
10143 | |
10144 | /*! \page feaOptimizationControl |
10145 | * |
10146 | * \if NASTRAN |
10147 | * <ul> |
10148 | * <li> <B>fullyStressedDesign = 0</B> </li> <br> |
10149 | * Number of iterations with fully stressed design. |
10150 | * </ul> |
10151 | * \endif |
10152 | * |
10153 | */ |
10154 | keyWord = "fullyStressedDesign"; |
10155 | status = json_getInteger( |
10156 | optimizationControlInput, keyWord, |
10157 | &feaProblem->feaOptimizationControl.fullyStressedDesign); |
10158 | |
10159 | // Set default value if value is not in JSON |
10160 | if (status != CAPS_SUCCESS0) { |
10161 | feaProblem->feaOptimizationControl.fullyStressedDesign = 0; |
10162 | } |
10163 | |
10164 | /*! \page feaOptimizationControl |
10165 | * |
10166 | * \if NASTRAN |
10167 | * <ul> |
10168 | * <li> <B>mathProgramming = 30</B> </li> <br> |
10169 | * Number of iterations for math programming methods. |
10170 | * </ul> |
10171 | * \endif |
10172 | * |
10173 | */ |
10174 | keyWord = "mathProgramming"; |
10175 | status = json_getInteger( |
10176 | optimizationControlInput, keyWord, |
10177 | &feaProblem->feaOptimizationControl.mathProgramming); |
10178 | |
10179 | // Set default value if value is not in JSON |
10180 | if (status != CAPS_SUCCESS0) { |
10181 | feaProblem->feaOptimizationControl.mathProgramming = 30; |
10182 | } |
10183 | |
10184 | /*! \page feaOptimizationControl |
10185 | * |
10186 | * \if NASTRAN |
10187 | * <ul> |
10188 | * <li> <B>maxIter = 30</B> </li> <br> |
10189 | * Maximum number of optimization iterations. |
10190 | * </ul> |
10191 | * \endif |
10192 | * |
10193 | */ |
10194 | keyWord = "maxIter"; |
10195 | status = json_getInteger( |
10196 | optimizationControlInput, keyWord, |
10197 | &feaProblem->feaOptimizationControl.maxIter); |
10198 | |
10199 | // Set default value if value is not in JSON |
10200 | if (status != CAPS_SUCCESS0) { |
10201 | feaProblem->feaOptimizationControl.maxIter = 30; |
10202 | } |
10203 | |
10204 | /*! \page feaOptimizationControl |
10205 | * |
10206 | * \if NASTRAN |
10207 | * <ul> |
10208 | * <li> <B>constraintRetention = 1.5</B> </li> <br> |
10209 | * Constraint retention factor. |
10210 | * Will be at least 1.5 times the number of design variables |
10211 | * </ul> |
10212 | * \endif |
10213 | * |
10214 | */ |
10215 | keyWord = "constraintRetention"; |
10216 | status = json_getDouble( |
10217 | optimizationControlInput, keyWord, |
10218 | &feaProblem->feaOptimizationControl.constraintRetention); |
10219 | |
10220 | // Set default value if value is not in JSON |
10221 | if (status != CAPS_SUCCESS0) { |
10222 | feaProblem->feaOptimizationControl.constraintRetention = 1.5; |
10223 | } |
10224 | |
10225 | /*! \page feaOptimizationControl |
10226 | * |
10227 | * \if NASTRAN |
10228 | * <ul> |
10229 | * <li> <B>eps = 1.0</B> </li> <br> |
10230 | * Constraint retention parameter in which all constraints having a |
10231 | * value greater than "eps" will be considered active. |
10232 | * |
10233 | * </ul> |
10234 | * \endif |
10235 | * |
10236 | */ |
10237 | keyWord = "eps"; |
10238 | status = json_getDouble( |
10239 | optimizationControlInput, keyWord, |
10240 | &feaProblem->feaOptimizationControl.eps); |
10241 | |
10242 | // Set default value if value is not in JSON |
10243 | if (status != CAPS_SUCCESS0) { |
10244 | feaProblem->feaOptimizationControl.eps = 1.0; |
10245 | } |
10246 | |
10247 | /*! \page feaOptimizationControl |
10248 | * |
10249 | * \if NASTRAN |
10250 | * <ul> |
10251 | * <li> <B>moveLimit = 1.0</B> </li> <br> |
10252 | * Move limit bound. |
10253 | * </ul> |
10254 | * \endif |
10255 | * |
10256 | */ |
10257 | keyWord = "moveLimit"; |
10258 | status = json_getDouble( |
10259 | optimizationControlInput, keyWord, |
10260 | &feaProblem->feaOptimizationControl.moveLimit); |
10261 | |
10262 | // Set default value if value is not in JSON |
10263 | if (status != CAPS_SUCCESS0) { |
10264 | feaProblem->feaOptimizationControl.moveLimit = 1.5; |
10265 | } |
10266 | |
10267 | } else { |
10268 | |
10269 | printf("\tError: OptimizationControl tuple value is expected to be a JSON string\n"); |
10270 | return CAPS_BADVALUE-311; |
10271 | |
10272 | } |
10273 | |
10274 | if (keyValue != NULL((void*)0)) { |
10275 | EG_free(keyValue); |
10276 | keyValue = NULL((void*)0); |
10277 | } |
10278 | |
10279 | printf("Done getting FEA Optimization Control\n"); |
10280 | return CAPS_SUCCESS0; |
10281 | } |
10282 | |
10283 | // Get the coordinate system information from the bodies and an attribute map (of CoordSystem) |
10284 | int fea_getCoordSystem(int numBody, |
10285 | ego bodies[], |
10286 | mapAttrToIndexStruct coordSystemMap, |
10287 | int *numCoordSystem, |
10288 | feaCoordSystemStruct *feaCoordSystem[]) { |
10289 | |
10290 | int status; // Function return |
10291 | |
10292 | int i, body, face, edge, node; // Indexing |
10293 | |
10294 | int numFace = 0, numEdge = 0, numNode = 0; // Number of egos |
10295 | ego *faces = NULL((void*)0), *edges = NULL((void*)0), *nodes = NULL((void*)0); // Geometry |
10296 | |
10297 | int atype, alen; // EGADS return variables |
10298 | const int *ints; |
10299 | const double *reals; |
10300 | const char *string; |
10301 | |
10302 | int found = (int) false0; |
10303 | |
10304 | // Destroy our CoordSystem structures coming in if aren't 0 and NULL already |
10305 | if (*feaCoordSystem != NULL((void*)0)) { |
10306 | for (i = 0; i < *numCoordSystem; i++) { |
10307 | status = destroy_feaCoordSystemStruct(&(*feaCoordSystem)[i]); |
10308 | if (status != CAPS_SUCCESS0) return status; |
10309 | } |
10310 | } |
10311 | if (*feaCoordSystem != NULL((void*)0)) EG_free(*feaCoordSystem); |
10312 | *feaCoordSystem = NULL((void*)0); |
10313 | *numCoordSystem = 0; |
10314 | |
10315 | printf("\nGetting FEA coordinate systems.......\n"); |
10316 | |
10317 | *numCoordSystem = coordSystemMap.numAttribute; |
10318 | printf("\tNumber of coordinate systems - %d\n", *numCoordSystem); |
10319 | |
10320 | if (*numCoordSystem > 0) { |
10321 | *feaCoordSystem = (feaCoordSystemStruct *) EG_alloc((*numCoordSystem)*sizeof(feaCoordSystemStruct)); |
10322 | if (*feaCoordSystem == NULL((void*)0)) return EGADS_MALLOC-4; |
10323 | |
10324 | } else { |
10325 | printf("\tNo coordinate systems found - defaulting to global\n"); |
10326 | return CAPS_SUCCESS0; |
10327 | } |
10328 | |
10329 | for (i = 0; i < *numCoordSystem; i++) { |
10330 | status = initiate_feaCoordSystemStruct(&(*feaCoordSystem)[i]); |
10331 | if (status != CAPS_SUCCESS0) return status; |
10332 | } |
10333 | |
10334 | for (i = 0; i < *numCoordSystem; i++) { |
10335 | |
10336 | if (faces != NULL((void*)0)) EG_free(faces); |
10337 | if (edges != NULL((void*)0)) EG_free(edges); |
10338 | if (nodes != NULL((void*)0)) EG_free(nodes); |
10339 | |
10340 | faces = NULL((void*)0); |
10341 | edges = NULL((void*)0); |
10342 | nodes = NULL((void*)0); |
10343 | |
10344 | printf("\tCoordinate system name - %s\n", coordSystemMap.attributeName[i]); |
10345 | |
10346 | (*feaCoordSystem)[i].name = EG_strdup(coordSystemMap.attributeName[i]); |
10347 | if ((*feaCoordSystem)[i].name == NULL((void*)0)) { status = EGADS_MALLOC-4; goto cleanup; } |
10348 | |
10349 | (*feaCoordSystem)[i].coordSystemID = coordSystemMap.attributeIndex[i]; |
10350 | |
10351 | (*feaCoordSystem)[i].refCoordSystemID = 0; |
10352 | |
10353 | (*feaCoordSystem)[i].coordSystemType = RectangularCoordSystem; |
10354 | |
10355 | found = (int) false0; |
10356 | |
10357 | // Search through bodies |
10358 | for (body = 0; body < numBody; body++) { |
10359 | |
10360 | // Look at the body level |
10361 | status = EG_attributeRet(bodies[body], (*feaCoordSystem)[i].name, &atype, &alen, &ints, &reals, &string); |
10362 | if (status != EGADS_SUCCESS0 && |
10363 | status != EGADS_NOTFOUND-1) goto cleanup; |
10364 | |
10365 | if (atype == ATTRCSYS12) { |
10366 | |
10367 | // Save the origin |
10368 | (*feaCoordSystem)[i].origin[0] = reals[alen+0]; |
10369 | (*feaCoordSystem)[i].origin[1] = reals[alen+1]; |
10370 | (*feaCoordSystem)[i].origin[2] = reals[alen+2]; |
10371 | |
10372 | (*feaCoordSystem)[i].normal1[0] = reals[alen+3]; |
10373 | (*feaCoordSystem)[i].normal1[1] = reals[alen+4]; |
10374 | (*feaCoordSystem)[i].normal1[2] = reals[alen+5]; |
10375 | |
10376 | (*feaCoordSystem)[i].normal2[0] = reals[alen+6]; |
10377 | (*feaCoordSystem)[i].normal2[1] = reals[alen+7]; |
10378 | (*feaCoordSystem)[i].normal2[2] = reals[alen+8]; |
10379 | |
10380 | (*feaCoordSystem)[i].normal3[0] = reals[alen+9]; |
10381 | (*feaCoordSystem)[i].normal3[1] = reals[alen+10]; |
10382 | (*feaCoordSystem)[i].normal3[2] = reals[alen+11]; |
10383 | |
10384 | found = (int) true1; |
10385 | } |
10386 | |
10387 | if (found == (int) true1) break; |
10388 | |
10389 | // Determine the number of faces, edges, and nodes |
10390 | status = EG_getBodyTopos(bodies[body], NULL((void*)0), FACE23, &numFace, &faces); |
10391 | if (status != EGADS_SUCCESS0) goto cleanup; |
10392 | |
10393 | status = EG_getBodyTopos(bodies[body], NULL((void*)0), EDGE21, &numEdge, &edges); |
10394 | if (status != EGADS_SUCCESS0) goto cleanup; |
10395 | |
10396 | status = EG_getBodyTopos(bodies[body], NULL((void*)0), NODE20, &numNode, &nodes); |
10397 | if (status != EGADS_SUCCESS0) goto cleanup; |
10398 | |
10399 | // Loop through faces |
10400 | for (face = 0; face < numFace; face++) { |
10401 | |
10402 | status = EG_attributeRet(faces[face], (const char *) (*feaCoordSystem)[i].name, &atype, &alen, &ints, &reals, &string); |
10403 | |
10404 | if (status == EGADS_NOTFOUND-1) continue; |
10405 | if (status != EGADS_SUCCESS0) goto cleanup; |
10406 | |
10407 | if (atype == ATTRCSYS12) { |
10408 | |
10409 | // Save the origin |
10410 | (*feaCoordSystem)[i].origin[0] = reals[alen+0]; |
10411 | (*feaCoordSystem)[i].origin[1] = reals[alen+1]; |
10412 | (*feaCoordSystem)[i].origin[2] = reals[alen+2]; |
10413 | |
10414 | (*feaCoordSystem)[i].normal1[0] = reals[alen+3]; |
10415 | (*feaCoordSystem)[i].normal1[1] = reals[alen+4]; |
10416 | (*feaCoordSystem)[i].normal1[2] = reals[alen+5]; |
10417 | |
10418 | (*feaCoordSystem)[i].normal2[0] = reals[alen+6]; |
10419 | (*feaCoordSystem)[i].normal2[1] = reals[alen+7]; |
10420 | (*feaCoordSystem)[i].normal2[2] = reals[alen+8]; |
10421 | |
10422 | (*feaCoordSystem)[i].normal3[0] = reals[alen+9]; |
10423 | (*feaCoordSystem)[i].normal3[1] = reals[alen+10]; |
10424 | (*feaCoordSystem)[i].normal3[2] = reals[alen+11]; |
10425 | |
10426 | found = (int) true1; |
10427 | |
10428 | break; |
10429 | } |
10430 | } // End face loop |
10431 | |
10432 | if (found == (int) true1) break; |
10433 | |
10434 | // Loop through edges |
10435 | for (edge = 0; edge < numEdge; edge++) { |
10436 | |
10437 | status = EG_attributeRet(edges[edge], (*feaCoordSystem)[i].name, &atype, &alen, &ints, &reals, &string); |
10438 | |
10439 | if (status == EGADS_NOTFOUND-1) continue; |
10440 | if (status != EGADS_SUCCESS0) goto cleanup; |
10441 | |
10442 | if (atype == ATTRCSYS12) { |
10443 | |
10444 | // Save the origin |
10445 | (*feaCoordSystem)[i].origin[0] = reals[alen+0]; |
10446 | (*feaCoordSystem)[i].origin[1] = reals[alen+1]; |
10447 | (*feaCoordSystem)[i].origin[2] = reals[alen+2]; |
10448 | |
10449 | (*feaCoordSystem)[i].normal1[0] = reals[alen+3]; |
10450 | (*feaCoordSystem)[i].normal1[1] = reals[alen+4]; |
10451 | (*feaCoordSystem)[i].normal1[2] = reals[alen+5]; |
10452 | |
10453 | (*feaCoordSystem)[i].normal2[0] = reals[alen+6]; |
10454 | (*feaCoordSystem)[i].normal2[1] = reals[alen+7]; |
10455 | (*feaCoordSystem)[i].normal2[2] = reals[alen+8]; |
10456 | |
10457 | (*feaCoordSystem)[i].normal3[0] = reals[alen+9]; |
10458 | (*feaCoordSystem)[i].normal3[1] = reals[alen+10]; |
10459 | (*feaCoordSystem)[i].normal3[2] = reals[alen+11]; |
10460 | |
10461 | found = (int) true1; |
10462 | |
10463 | break; |
10464 | } |
10465 | |
10466 | } // End edge loop |
10467 | |
10468 | if (found == (int) true1) break; |
10469 | |
10470 | // Loop through nodes |
10471 | for (node = 0; node < numNode; node++) { |
10472 | |
10473 | status = EG_attributeRet(nodes[node], (*feaCoordSystem)[i].name, &atype, &alen, &ints, &reals, &string); |
10474 | |
10475 | if (status == EGADS_NOTFOUND-1) continue; |
10476 | if (status != EGADS_SUCCESS0) goto cleanup; |
10477 | |
10478 | if (atype == ATTRCSYS12) { |
10479 | |
10480 | // Save the origin |
10481 | (*feaCoordSystem)[i].origin[0] = reals[alen+0]; |
10482 | (*feaCoordSystem)[i].origin[1] = reals[alen+1]; |
10483 | (*feaCoordSystem)[i].origin[2] = reals[alen+2]; |
10484 | |
10485 | (*feaCoordSystem)[i].normal1[0] = reals[alen+3]; |
10486 | (*feaCoordSystem)[i].normal1[1] = reals[alen+4]; |
10487 | (*feaCoordSystem)[i].normal1[2] = reals[alen+5]; |
10488 | |
10489 | (*feaCoordSystem)[i].normal2[0] = reals[alen+6]; |
10490 | (*feaCoordSystem)[i].normal2[1] = reals[alen+7]; |
10491 | (*feaCoordSystem)[i].normal2[2] = reals[alen+8]; |
10492 | |
10493 | (*feaCoordSystem)[i].normal3[0] = reals[alen+9]; |
10494 | (*feaCoordSystem)[i].normal3[1] = reals[alen+10]; |
10495 | (*feaCoordSystem)[i].normal3[2] = reals[alen+11]; |
10496 | |
10497 | found = (int) true1; |
10498 | |
10499 | break; |
10500 | } |
10501 | } // End node loop |
10502 | |
10503 | EG_free(faces); faces = NULL((void*)0); |
10504 | EG_free(edges); edges = NULL((void*)0); |
10505 | EG_free(nodes); nodes = NULL((void*)0); |
10506 | |
10507 | if (found == (int) true1) break; |
10508 | |
10509 | } // End body loop |
10510 | } |
10511 | |
10512 | status = CAPS_SUCCESS0; |
10513 | |
10514 | cleanup: |
10515 | |
10516 | if (status != CAPS_SUCCESS0) printf("\tError in fea_getCoordSystem = %d\n", status); |
10517 | |
10518 | EG_free(faces); |
10519 | EG_free(edges); |
10520 | EG_free(nodes); |
10521 | |
10522 | return status; |
10523 | } |
10524 | |
10525 | // Get the design equations from a capsTuple |
10526 | int fea_getDesignEquation(int numEquationTuple, |
10527 | capsTuple equationTuple[], |
10528 | feaProblemStruct *feaProblem) { |
10529 | |
10530 | /*! \page feaDesignEquation FEA Design Equations |
10531 | * Structure for the design equation tuple = ("DesignEquation Name", ["Value1", ... , "ValueN"]). |
10532 | * "DesignEquation Name" defines the reference name for the design equation being specified. |
10533 | * This string will be used in the FEA input directly. The values "Value1", ... , "ValueN" are a |
10534 | * list of strings containing the equation defintions. |
10535 | * (see Section \ref tupleValueDesignEquation). |
10536 | * |
10537 | */ |
10538 | int i, status; |
10539 | |
10540 | feaDesignEquationStruct *equation; |
10541 | |
10542 | // Ensure we are starting with no equations |
10543 | if (feaProblem->feaEquation != NULL((void*)0)) { |
10544 | for (i = 0; i < feaProblem->numEquation; i++) { |
10545 | status = destroy_feaDesignEquationStruct(&feaProblem->feaEquation[i]); |
10546 | if (status != CAPS_SUCCESS0) return status; |
10547 | } |
10548 | EG_free(feaProblem->feaEquation); |
10549 | } |
10550 | feaProblem->numEquation = 0; |
10551 | feaProblem->feaEquation = NULL((void*)0); |
10552 | |
10553 | printf("\nGetting Equations.......\n"); |
10554 | |
10555 | feaProblem->numEquation = numEquationTuple; |
10556 | printf("\tNumber of Equations - %d\n", feaProblem->numEquation); |
10557 | |
10558 | if (feaProblem->numEquation > 0) { |
10559 | |
10560 | feaProblem->feaEquation = EG_alloc( |
10561 | feaProblem->numEquation * sizeof(feaDesignEquationStruct)); |
10562 | if (feaProblem->feaEquation == NULL((void*)0)) { |
10563 | return EGADS_MALLOC-4; |
10564 | } |
10565 | |
10566 | } else { |
10567 | printf("\tNumber of equations in Analysis tuple is %d\n", |
10568 | feaProblem->numEquation); |
10569 | return CAPS_NOTFOUND-303; |
10570 | } |
10571 | |
10572 | // for each analysis equation tuple |
10573 | for (i = 0; i < feaProblem->numEquation; i++) { |
10574 | |
10575 | printf("\tDesign_Equation name - %s\n", equationTuple[i].name); |
10576 | |
10577 | equation = &feaProblem->feaEquation[i]; |
10578 | |
10579 | // initiate equation structure |
10580 | status = initiate_feaDesignEquationStruct(equation); |
10581 | if (status != CAPS_SUCCESS0) return status; |
10582 | |
10583 | // set name |
10584 | equation->name = EG_strdup(equationTuple[i].name); |
10585 | |
10586 | // set equation ID |
10587 | equation->equationID = i+1; |
10588 | |
10589 | /*! \page feaDesignEquation |
10590 | * \section tupleValueDesignEquation List of equation strings |
10591 | * |
10592 | * Each design equation tuple value is a list of strings containing the equation definitions |
10593 | * \if NASTRAN |
10594 | * (eg. ["dispsum3(s1,s2,s3)=sum(s1,s2,s3)"] |
10595 | * \endif |
10596 | * |
10597 | */ |
10598 | // set the equation array |
10599 | status = string_toStringDynamicArray( |
10600 | equationTuple[i].value, |
10601 | &equation->equationArraySize, |
10602 | &equation->equationArray); |
10603 | |
10604 | if (status != CAPS_SUCCESS0) return status; |
10605 | } |
10606 | |
10607 | return CAPS_SUCCESS0; |
10608 | } |
10609 | |
10610 | // Get the design table constants from a capsTuple |
10611 | int fea_getDesignTable(int numConstantTuple, |
10612 | capsTuple constantTuple[], |
10613 | feaProblemStruct *feaProblem) { |
10614 | |
10615 | |
10616 | /*! \page feaDesignTable FEA Table Constants |
10617 | * Structure for the table constant tuple = ("TableConstant Name", "Value"). |
10618 | * "TableConstant Name" defines the reference name for the table constant being specified. |
10619 | * This string will be used in the FEA input directly. The "Value" is the value of the |
10620 | * table constant. |
10621 | * \if NASTRAN |
10622 | * In Nastran the TableConstant Name will be the LABLi used in the DTABLE input. |
10623 | * For this reason the user should keep the length of this input to a minimum number of characters, ideally 7 or less. |
10624 | * |
10625 | * - <c>DTABLE LABL1 VALU1 LABL2 VALU2 LABL3 VALU3 -etc- </c> |
10626 | * \endif |
10627 | * |
10628 | */ |
10629 | int i, status; |
10630 | |
10631 | feaDesignTableStruct *table = &feaProblem->feaDesignTable; |
10632 | |
10633 | // Ensure we are starting with no constants |
10634 | status = destroy_feaDesignTableStruct(table); |
10635 | if (status != CAPS_SUCCESS0) return status; |
10636 | |
10637 | printf("\nGetting Design Table Constants.......\n"); |
10638 | |
10639 | table->numConstant = numConstantTuple; |
10640 | printf("\tNumber of Design Table Constants - %d\n", table->numConstant); |
10641 | |
10642 | if (table->numConstant > 0) { |
10643 | |
10644 | table->constantLabel = EG_alloc(table->numConstant * sizeof(char *)); |
10645 | if (table->constantLabel == NULL((void*)0)) { |
10646 | return EGADS_MALLOC-4; |
10647 | } |
10648 | |
10649 | table->constantValue = EG_alloc(table->numConstant * sizeof(double)); |
10650 | if (table->constantValue == NULL((void*)0)) { |
10651 | return EGADS_MALLOC-4; |
10652 | } |
10653 | |
10654 | } else { |
10655 | printf("\tNumber of design table constants in Analysis tuple is %d\n", |
10656 | table->numConstant); |
10657 | return CAPS_NOTFOUND-303; |
10658 | } |
10659 | |
10660 | // for each analysis table constant tuple |
10661 | for (i = 0; i < table->numConstant; i++) { |
10662 | |
10663 | printf("\tDesign_Table - %s: %s\n", |
10664 | constantTuple[i].name, constantTuple[i].value); |
10665 | |
10666 | // set constant label |
10667 | // TODO: ensure label <= 8 chars |
10668 | table->constantLabel[i] = EG_strdup(constantTuple[i].name); |
10669 | |
10670 | // set constant value |
10671 | status = string_toDouble(constantTuple[i].value, &table->constantValue[i]); |
10672 | if (status != CAPS_SUCCESS0) return status; |
10673 | } |
10674 | |
10675 | return CAPS_SUCCESS0; |
10676 | } |
10677 | |
10678 | // Function used by fea_getDesignResponse to determine which nodes are in response group |
10679 | static int _matchResponseNode(meshNodeStruct *node, void *responseIndex) { |
10680 | |
10681 | feaMeshDataStruct *feaData; |
10682 | |
10683 | if (node->analysisType == MeshStructure) { |
10684 | |
10685 | feaData = (feaMeshDataStruct *) node->analysisData; |
10686 | |
10687 | if (feaData->responseIndex == *((int *) responseIndex)) { |
10688 | return (int) true1; |
10689 | } |
10690 | } |
10691 | return (int) false0; |
10692 | } |
10693 | |
10694 | int fea_getDesignResponse(/*@unused@*/ void *aimInfo, |
10695 | int numDesignResponseTuple, |
10696 | capsTuple designResponseTuple[], |
10697 | mapAttrToIndexStruct *responseMap, |
10698 | feaProblemStruct *feaProblem) { |
10699 | |
10700 | /*! \page feaDesignResponse FEA Design Responses |
10701 | * Structure for the design response tuple = ("DesignResponse Name", "Value"). |
10702 | * "DesignResponse Name" defines the reference name for the design response being specified. |
10703 | * This string will be used in the FEA input directly. The "Value" must be a JSON String dictionary |
10704 | * (see Section \ref jsonStringDesignResponse). |
10705 | * \if NASTRAN |
10706 | * In Nastran the DesignResponse Name will be the LABEL used in the DRESP1 input. |
10707 | * For this reason the user should keep the length of this input to a minimum number of characters, ideally 7 or less. |
10708 | * |
10709 | * - <c>DRESP1 ID LABEL RTYPE PTYPE REGION ATTA ATTB ATT1\n ATT2 -etc-</c> |
10710 | * \endif |
10711 | * |
10712 | */ |
10713 | int i, status; |
10714 | |
10715 | int attrIndex; |
10716 | |
10717 | char *keyword; |
10718 | char *groupName = NULL((void*)0); |
10719 | |
10720 | int numNode; |
10721 | meshNodeStruct **nodeSet = NULL((void*)0); |
10722 | |
10723 | feaDesignResponseStruct *response; |
10724 | |
10725 | // Ensure we are starting with no design responses |
10726 | if (feaProblem->feaDesignResponse != NULL((void*)0)) { |
10727 | for (i = 0; i < feaProblem->numDesignResponse; i++) { |
10728 | status = destroy_feaDesignResponseStruct(&feaProblem->feaDesignResponse[i]); |
10729 | if (status != CAPS_SUCCESS0) return status; |
10730 | } |
10731 | EG_free(feaProblem->feaDesignResponse); |
10732 | } |
10733 | feaProblem->numDesignResponse = 0; |
10734 | feaProblem->feaDesignResponse = NULL((void*)0); |
10735 | |
10736 | printf("\nGetting Design Responses.......\n"); |
10737 | |
10738 | feaProblem->numDesignResponse = numDesignResponseTuple; |
10739 | printf("\tNumber of Design Responses - %d\n", feaProblem->numDesignResponse); |
10740 | |
10741 | if (feaProblem->numDesignResponse > 0) { |
10742 | |
10743 | feaProblem->feaDesignResponse = EG_alloc( |
10744 | feaProblem->numDesignResponse * sizeof(feaDesignResponseStruct)); |
10745 | if (feaProblem->feaDesignResponse == NULL((void*)0)) { |
10746 | return EGADS_MALLOC-4; |
10747 | } |
10748 | |
10749 | } else { |
10750 | printf("\tNumber of design responses in Analysis tuple is %d\n", |
10751 | feaProblem->numDesignResponse); |
10752 | return CAPS_NOTFOUND-303; |
10753 | } |
10754 | |
10755 | // for each analysis design response tuple |
10756 | for (i = 0; i < feaProblem->numDesignResponse; i++) { |
10757 | |
10758 | printf("\tDesign_Response name - %s\n", designResponseTuple[i].name); |
10759 | |
10760 | response = &feaProblem->feaDesignResponse[i]; |
10761 | |
10762 | // initiate design response structure |
10763 | status = initiate_feaDesignResponseStruct(response); |
10764 | if (status != CAPS_SUCCESS0) return status; |
10765 | |
10766 | // set name |
10767 | response->name = EG_strdup(designResponseTuple[i].name); |
10768 | |
10769 | // set response ID |
10770 | response->responseID = i+1; |
10771 | |
10772 | /*! \page feaDesignResponse |
10773 | * \section jsonStringDesignResponse JSON String Dictionary |
10774 | * |
10775 | * If "Value" is JSON string dictionary |
10776 | * \if NASTRAN |
10777 | * (eg. "Value" = {"responseType": "DISP", groupName": "plate", "component": 3}) |
10778 | * \endif |
10779 | * the following keywords ( = default values) may be used: |
10780 | * |
10781 | */ |
10782 | // make sure design response tuple value is json string |
10783 | if (!json_isDict(designResponseTuple[i].value)) { |
10784 | AIM_ERROR(aimInfo,{ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 10785, __func__ , "'Design_Response' tuple value must be a JSON dictionary"); } |
10785 | "'Design_Response' tuple value must be a JSON dictionary"){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 10785, __func__ , "'Design_Response' tuple value must be a JSON dictionary"); }; |
10786 | return CAPS_BADVALUE-311; |
10787 | } |
10788 | |
10789 | /*! \page feaDesignResponse |
10790 | * |
10791 | * \if NASTRAN |
10792 | * <ul> |
10793 | * <li> <B>responseType</B> </li> <br> |
10794 | * Type of design sensitivity response. For options, |
10795 | * see NASTRAN User Guide DRESP1 Design Sensitivity Response Attributes table. |
10796 | * </ul> |
10797 | * \endif |
10798 | */ |
10799 | keyword = "responseType"; |
10800 | status = json_getString( |
10801 | designResponseTuple[i].value, keyword, &response->responseType); |
10802 | if (status != CAPS_SUCCESS0) { |
10803 | AIM_ERROR(aimInfo, "Missing required entry \"responseType\" "{ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 10804, __func__ , "Missing required entry \"responseType\" " "in 'Design_Response' tuple value" ); } |
10804 | "in 'Design_Response' tuple value"){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 10804, __func__ , "Missing required entry \"responseType\" " "in 'Design_Response' tuple value" ); }; |
10805 | return status; |
10806 | } |
10807 | |
10808 | // keyword = "propertyType"; |
10809 | // status = json_getString( |
10810 | // designResponseTuple[i].value, keyword, &response->propertyType); |
10811 | // if (status != CAPS_SUCCESS) { |
10812 | // // optional |
10813 | // } |
10814 | |
10815 | /*! \page feaDesignResponse |
10816 | * |
10817 | * \if NASTRAN |
10818 | * <ul> |
10819 | * <li> <B>component = "(no default)"</B> </li> <br> |
10820 | * Component flag. |
10821 | * </ul> |
10822 | * \endif |
10823 | */ |
10824 | keyword = "component"; |
10825 | status = json_getInteger( |
10826 | designResponseTuple[i].value, keyword, &response->component); |
10827 | if (status != CAPS_SUCCESS0) { |
10828 | // optional |
10829 | } |
10830 | |
10831 | // TODO: temporary input |
10832 | keyword = "grid"; |
10833 | status = json_getInteger( |
10834 | designResponseTuple[i].value, keyword, &response->gridID); |
10835 | if (status != CAPS_SUCCESS0) { |
10836 | // optional |
10837 | } |
10838 | |
10839 | /*! \page feaDesignResponse |
10840 | * |
10841 | * \if NASTRAN |
10842 | * <ul> |
10843 | * <li> <B>groupName = "(no default)"</B> </li> <br> |
10844 | * Defines the reference <c>capsGroup</c> for the node being specified for the response. |
10845 | * </ul> |
10846 | * \endif |
10847 | */ |
10848 | keyword = "groupName"; |
10849 | status = json_getString( |
10850 | designResponseTuple[i].value, keyword, &groupName); |
10851 | |
10852 | if (status == CAPS_SUCCESS0) { |
10853 | |
10854 | // Get the corresponding response index |
10855 | status = get_mapAttrToIndexIndex(responseMap, (const char *) groupName, &attrIndex); |
10856 | |
10857 | if (status == CAPS_NOTFOUND-303) { |
10858 | printf("\tName %s not found in attribute map!!!!\n", groupName); |
10859 | continue; |
10860 | } else if (status != CAPS_SUCCESS0) return status; |
10861 | |
10862 | status = mesh_findNodes(&feaProblem->feaMesh, |
10863 | _matchResponseNode, (void *) &attrIndex, |
10864 | &numNode, &nodeSet); |
10865 | if (status != CAPS_SUCCESS0) return status; |
10866 | |
10867 | if (numNode == 0) { |
10868 | AIM_ERROR(aimInfo, "No node found for capsGroup %s", groupName){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 10868, __func__ , "No node found for capsGroup %s", groupName); }; |
10869 | return CAPS_NOTFOUND-303; |
10870 | } |
10871 | else if (numNode > 1) { // TODO: would there ever be more than 1 node expected? |
10872 | PRINT_WARNING("More than 1 node found for capsGroup %s"fprintf(stderr, "[ WARNING ] " "More than 1 node found for capsGroup %s" "... using first matching node." "\n", groupName); |
10873 | "... using first matching node.",fprintf(stderr, "[ WARNING ] " "More than 1 node found for capsGroup %s" "... using first matching node." "\n", groupName); |
10874 | groupName)fprintf(stderr, "[ WARNING ] " "More than 1 node found for capsGroup %s" "... using first matching node." "\n", groupName);; |
10875 | } |
10876 | |
10877 | response->gridID = nodeSet[0]->nodeID; |
10878 | |
10879 | EG_free(nodeSet); |
10880 | nodeSet = NULL((void*)0); |
10881 | |
10882 | } |
10883 | else { |
10884 | // required |
10885 | // AIM_ERROR(aimInfo, "Missing required entry \"groupName\" " |
10886 | // "in 'Design_Response' tuple value"); |
10887 | // return status; |
10888 | } |
10889 | |
10890 | if (groupName != NULL((void*)0)) { |
10891 | EG_free(groupName); |
10892 | groupName = NULL((void*)0); |
10893 | } |
10894 | |
10895 | } |
10896 | |
10897 | return CAPS_SUCCESS0; |
10898 | } |
10899 | |
10900 | int fea_getDesignEquationResponse(int numDesignEquationResponseTuple, |
10901 | capsTuple designEquationResponseTuple[], |
10902 | feaProblemStruct *feaProblem) { |
10903 | |
10904 | /*! \page feaDesignEquationResponse FEA Design Equation Responses |
10905 | * Structure for the design equation response tuple = ("DesignEquationResponse Name", "Value"). |
10906 | * "DesignEquationResponse Name" defines the reference name for the design equation response being specified. |
10907 | * This string will be used in the FEA input directly. The "Value" must be a JSON String dictionary |
10908 | * (see Section \ref jsonStringDesignEquationResponse). |
10909 | * \if NASTRAN |
10910 | * In Nastran the DesignEquationResponse Name will be the LABEL used in the DRESP2 input. |
10911 | * For this reason the user should keep the length of this input to a minimum number of characters, ideally 7 or less. |
10912 | * |
10913 | * - <c>DRESP2 ID LABEL EQID REGION ...</c> |
10914 | * \endif |
10915 | * |
10916 | */ |
10917 | int i, status; |
10918 | |
10919 | char *keyword; |
10920 | |
10921 | feaDesignEquationResponseStruct *equationResponse; |
10922 | |
10923 | // Ensure we are starting with no design equation responses |
10924 | if (feaProblem->feaEquationResponse != NULL((void*)0)) { |
10925 | for (i = 0; i < feaProblem->numEquationResponse; i++) { |
10926 | status = destroy_feaDesignEquationResponseStruct(&feaProblem->feaEquationResponse[i]); |
10927 | if (status != CAPS_SUCCESS0) return status; |
10928 | } |
10929 | EG_free(feaProblem->feaEquationResponse); |
10930 | } |
10931 | feaProblem->numEquationResponse = 0; |
10932 | feaProblem->feaEquationResponse = NULL((void*)0); |
10933 | |
10934 | printf("\nGetting Design Equation Responses.......\n"); |
10935 | |
10936 | feaProblem->numEquationResponse = numDesignEquationResponseTuple; |
10937 | printf("\tNumber of Design Equation Responses - %d\n", feaProblem->numEquationResponse); |
10938 | |
10939 | if (feaProblem->numEquationResponse > 0) { |
10940 | |
10941 | feaProblem->feaEquationResponse = EG_alloc( |
10942 | feaProblem->numEquationResponse * sizeof(feaDesignEquationResponseStruct)); |
10943 | if (feaProblem->feaEquationResponse == NULL((void*)0)) { |
10944 | return EGADS_MALLOC-4; |
10945 | } |
10946 | |
10947 | } else { |
10948 | printf("\tNumber of design equation responses in Analysis tuple is %d\n", |
10949 | feaProblem->numEquationResponse); |
10950 | return CAPS_NOTFOUND-303; |
10951 | } |
10952 | |
10953 | // for each analysis design equation response tuple |
10954 | for (i = 0; i < feaProblem->numEquationResponse; i++) { |
10955 | |
10956 | printf("\tDesign_Equation_Response name - %s\n", designEquationResponseTuple[i].name); |
10957 | |
10958 | equationResponse = &feaProblem->feaEquationResponse[i]; |
10959 | |
10960 | // initiate design response structure |
10961 | status = initiate_feaDesignEquationResponseStruct(equationResponse); |
10962 | if (status != CAPS_SUCCESS0) return status; |
10963 | |
10964 | // set name |
10965 | equationResponse->name = EG_strdup(designEquationResponseTuple[i].name); |
10966 | |
10967 | // set equation response ID |
10968 | equationResponse->equationResponseID = i+1; |
10969 | |
10970 | /*! \page feaDesignEquationResponse |
10971 | * \section jsonStringDesignEquationResponse JSON String Dictionary |
10972 | * |
10973 | * If "Value" is JSON string dictionary |
10974 | * \if NASTRAN |
10975 | * (eg. "Value" = {"equation": "EQ1", "constant": ["PI", "YM", "L"]}) |
10976 | * \endif |
10977 | * the following keywords ( = default values) may be used: |
10978 | * |
10979 | */ |
10980 | // make sure design response tuple value is json string |
10981 | if (!json_isDict(designEquationResponseTuple[i].value)) { |
10982 | PRINT_ERROR(fprintf(stderr, "\n" "--------------------------------------------------------------------------------\n" "[ ERROR ]\n" "File: %s\n" "Line: %d\n" "Function: %s\n" "Reason: " "'Design_Equation_Response' tuple value must be a JSON dictionary" "\n" "--------------------------------------------------------------------------------\n" "\n", "feaUtils.c", 10983, __func__); |
10983 | "'Design_Equation_Response' tuple value must be a JSON dictionary")fprintf(stderr, "\n" "--------------------------------------------------------------------------------\n" "[ ERROR ]\n" "File: %s\n" "Line: %d\n" "Function: %s\n" "Reason: " "'Design_Equation_Response' tuple value must be a JSON dictionary" "\n" "--------------------------------------------------------------------------------\n" "\n", "feaUtils.c", 10983, __func__);; |
10984 | return CAPS_BADVALUE-311; |
10985 | } |
10986 | |
10987 | /*! \page feaDesignEquationResponse |
10988 | * |
10989 | * \if NASTRAN |
10990 | * <ul> |
10991 | * <li> <B>equation</B> </li> <br> |
10992 | * The name of the equation referenced by this equation response. |
10993 | * </ul> |
10994 | * \endif |
10995 | */ |
10996 | keyword = "equation"; |
10997 | status = json_getString( |
10998 | designEquationResponseTuple[i].value, keyword, &equationResponse->equationName); |
10999 | if (status != CAPS_SUCCESS0) { |
11000 | PRINT_ERROR("Missing required entry \"equation\" "fprintf(stderr, "\n" "--------------------------------------------------------------------------------\n" "[ ERROR ]\n" "File: %s\n" "Line: %d\n" "Function: %s\n" "Reason: " "Missing required entry \"equation\" " "in 'Design_Equation_Response' tuple value" "\n" "--------------------------------------------------------------------------------\n" "\n", "feaUtils.c", 11001, __func__); |
11001 | "in 'Design_Equation_Response' tuple value")fprintf(stderr, "\n" "--------------------------------------------------------------------------------\n" "[ ERROR ]\n" "File: %s\n" "Line: %d\n" "Function: %s\n" "Reason: " "Missing required entry \"equation\" " "in 'Design_Equation_Response' tuple value" "\n" "--------------------------------------------------------------------------------\n" "\n", "feaUtils.c", 11001, __func__);; |
11002 | return status; |
11003 | } |
11004 | |
11005 | /*! \page feaDesignEquationResponse |
11006 | * |
11007 | * \if NASTRAN |
11008 | * <ul> |
11009 | * <li> <B>variable = "(no default)"</B> </li> <br> |
11010 | * Single or list of names of design variable equation parameters. |
11011 | * </ul> |
11012 | * \endif |
11013 | */ |
11014 | keyword = "variable"; |
11015 | status = json_getStringDynamicArray( |
11016 | designEquationResponseTuple[i].value, keyword, |
11017 | &equationResponse->numDesignVariable, &equationResponse->designVariableNameSet); |
11018 | if (status != CAPS_SUCCESS0) { |
11019 | // optional |
11020 | } |
11021 | |
11022 | /*! \page feaDesignEquationResponse |
11023 | * |
11024 | * \if NASTRAN |
11025 | * <ul> |
11026 | * <li> <B>constant = "(no default)"</B> </li> <br> |
11027 | * Single or list of names of table constant equation parameters. |
11028 | * </ul> |
11029 | * \endif |
11030 | */ |
11031 | keyword = "constant"; |
11032 | status = json_getStringDynamicArray( |
11033 | designEquationResponseTuple[i].value, keyword, |
11034 | &equationResponse->numConstant, &equationResponse->constantLabelSet); |
11035 | if (status != CAPS_SUCCESS0) { |
11036 | // optional |
11037 | } |
11038 | |
11039 | /*! \page feaDesignEquationResponse |
11040 | * |
11041 | * \if NASTRAN |
11042 | * <ul> |
11043 | * <li> <B>response = "(no default)"</B> </li> <br> |
11044 | * Single or list of names of design response equation parameters. |
11045 | * </ul> |
11046 | * \endif |
11047 | */ |
11048 | keyword = "response"; |
11049 | status = json_getStringDynamicArray( |
11050 | designEquationResponseTuple[i].value, keyword, |
11051 | &equationResponse->numResponse, &equationResponse->responseNameSet); |
11052 | if (status != CAPS_SUCCESS0) { |
11053 | // optional |
11054 | } |
11055 | |
11056 | /*! \page feaDesignEquationResponse |
11057 | * |
11058 | * \if NASTRAN |
11059 | * <ul> |
11060 | * <li> <B>equationResponse = "(no default)"</B> </li> <br> |
11061 | * Single or list of names of design equation response equation parameters. |
11062 | * </ul> |
11063 | * \endif |
11064 | */ |
11065 | keyword = "equationResponse"; |
11066 | status = json_getStringDynamicArray( |
11067 | designEquationResponseTuple[i].value, keyword, |
11068 | &equationResponse->numEquationResponse, &equationResponse->equationResponseNameSet); |
11069 | if (status != CAPS_SUCCESS0) { |
11070 | // optional |
11071 | } |
11072 | } |
11073 | |
11074 | return CAPS_SUCCESS0; |
11075 | } |
11076 | |
11077 | // Get the design optimization parameters from a capsTuple |
11078 | int fea_getDesignOptParam(int numParamTuple, |
11079 | capsTuple paramTuple[], |
11080 | feaProblemStruct *feaProblem) { |
11081 | |
11082 | /*! \page feaDesignOptParam FEA Design Optimization Parameters |
11083 | * Structure for the design optimization parameter tuple = ("DesignOptParam Name", "Value"). |
11084 | * "DesignOptParam Name" defines the reference name for the design optimization parameter being specified. |
11085 | * This string will be used in the FEA input directly. The "Value" is the value of the |
11086 | * design optimization parameter. |
11087 | * \if NASTRAN |
11088 | * In Nastran the DesignOptParam Name will be the PARAMi used in the DOPTPRM input. |
11089 | * For this reason the user should keep the length of this input to a minimum number of characters, ideally 7 or less. |
11090 | * |
11091 | * - <c>DOPTPRM PARAM1 VAL1 PARAM2 VAL2 PARAM3 VAL3 -etc- </c> |
11092 | * \endif |
11093 | * |
11094 | */ |
11095 | int i, status; |
11096 | |
11097 | int *paramInt = NULL((void*)0); |
11098 | double *paramDouble = NULL((void*)0); |
11099 | |
11100 | feaDesignOptParamStruct *table = &feaProblem->feaDesignOptParam; |
11101 | |
11102 | // Ensure we are starting with no params |
11103 | status = destroy_feaDesignOptParamStruct(table); |
11104 | if (status != CAPS_SUCCESS0) return status; |
11105 | |
11106 | printf("\nGetting Design Optimization Parameters.......\n"); |
11107 | |
11108 | table->numParam = numParamTuple; |
11109 | printf("\tNumber of Design Optimization Parameters - %d\n", table->numParam); |
11110 | |
11111 | if (table->numParam > 0) { |
11112 | |
11113 | table->paramLabel = EG_alloc(table->numParam * sizeof(char *)); |
11114 | if (table->paramLabel == NULL((void*)0)) { |
11115 | return EGADS_MALLOC-4; |
11116 | } |
11117 | |
11118 | table->paramValue = EG_alloc(table->numParam * sizeof(void *)); |
11119 | if (table->paramValue == NULL((void*)0)) { |
11120 | return EGADS_MALLOC-4; |
11121 | } |
11122 | |
11123 | table->paramType = EG_alloc(table->numParam * sizeof(int)); |
11124 | if (table->paramType == NULL((void*)0)) { |
11125 | return EGADS_MALLOC-4; |
11126 | } |
11127 | |
11128 | } else { |
11129 | printf("\tNumber of design optimization parameters in Analysis tuple is %d\n", |
11130 | table->numParam); |
11131 | return CAPS_NOTFOUND-303; |
11132 | } |
11133 | |
11134 | // for each analysis design optimization parameter tuple |
11135 | for (i = 0; i < table->numParam; i++) { |
11136 | |
11137 | printf("\tDesign_Opt_Param - %s: %s\n", |
11138 | paramTuple[i].name, paramTuple[i].value); |
11139 | |
11140 | // set param label |
11141 | // TODO: ensure label <= 8 chars |
11142 | table->paramLabel[i] = EG_strdup(paramTuple[i].name); |
11143 | |
11144 | // set param value |
11145 | |
11146 | // if param value is real |
11147 | if (strchr(paramTuple[i].value, '.') |
11148 | || strchr(paramTuple[i].value, 'e') |
11149 | || strchr(paramTuple[i].value, 'E')) { |
11150 | |
11151 | paramDouble = EG_alloc(sizeof(double)); |
11152 | if (paramDouble == NULL((void*)0)) return EGADS_MALLOC-4; |
11153 | |
11154 | status = string_toDouble(paramTuple[i].value, paramDouble); |
11155 | if (status != CAPS_SUCCESS0) { |
11156 | EG_free(paramDouble); |
11157 | return status; |
11158 | } |
11159 | |
11160 | table->paramType[i] = Double; |
11161 | table->paramValue[i] = (void*) paramDouble; |
11162 | } |
11163 | // else param is integer |
11164 | else { |
11165 | |
11166 | paramInt = EG_alloc(sizeof(int)); |
11167 | if (paramInt == NULL((void*)0)) return EGADS_MALLOC-4; |
11168 | |
11169 | status = string_toInteger(paramTuple[i].value, paramInt); |
11170 | if (status != CAPS_SUCCESS0) { |
11171 | EG_free(paramInt); |
11172 | return status; |
11173 | } |
11174 | |
11175 | table->paramType[i] = Integer; |
11176 | table->paramValue[i] = (void*) paramInt; |
11177 | } |
11178 | } |
11179 | |
11180 | return CAPS_SUCCESS0; |
11181 | } |
11182 | |
11183 | // Function used by fea_getAeroReference to determine which nodes are in reference group |
11184 | static int _matchReferenceNode(meshNodeStruct *node, void *referenceIndex) { |
11185 | |
11186 | feaMeshDataStruct *feaData; |
11187 | |
11188 | if (node->analysisType == MeshStructure) { |
11189 | |
11190 | feaData = (feaMeshDataStruct *) node->analysisData; |
11191 | |
11192 | if (feaData->referenceIndex == *((int *) referenceIndex)) { |
11193 | return (int) true1; |
11194 | } |
11195 | } |
11196 | return (int) false0; |
11197 | } |
11198 | |
11199 | // Get aero reference information from json dict |
11200 | int fea_getAeroReference(char *aeroRefInput, |
11201 | mapAttrToIndexStruct *attrMap, |
11202 | feaProblemStruct *feaProblem) { |
11203 | |
11204 | /*! \page feaAeroReference FEA Aerodynamic References |
11205 | * The aerodynamic reference input must be a JSON String dictionary |
11206 | * (see Section \ref jsonStringAeroReference). |
11207 | * |
11208 | */ |
11209 | int status, attrIndex = 0; |
11210 | |
11211 | char *keyword, *refNodeName = NULL((void*)0); |
11212 | |
11213 | int numNodes; |
11214 | meshNodeStruct **nodes = NULL((void*)0); |
11215 | |
11216 | printf("\nGetting Aero Reference Parameters.......\n"); |
11217 | |
11218 | /*! \page feaAeroReference |
11219 | * \section jsonStringAeroReference JSON String Dictionary |
11220 | * |
11221 | * The following keywords ( = default values) may be used: |
11222 | * |
11223 | */ |
11224 | // make sure input is json string |
11225 | if (!json_isDict(aeroRefInput)) { |
11226 | PRINT_ERROR(fprintf(stderr, "\n" "--------------------------------------------------------------------------------\n" "[ ERROR ]\n" "File: %s\n" "Line: %d\n" "Function: %s\n" "Reason: " "'Aero_Reference' value must be a JSON dictionary" "\n" "--------------------------------------------------------------------------------\n" "\n", "feaUtils.c", 11227, __func__); |
11227 | "'Aero_Reference' value must be a JSON dictionary")fprintf(stderr, "\n" "--------------------------------------------------------------------------------\n" "[ ERROR ]\n" "File: %s\n" "Line: %d\n" "Function: %s\n" "Reason: " "'Aero_Reference' value must be a JSON dictionary" "\n" "--------------------------------------------------------------------------------\n" "\n", "feaUtils.c", 11227, __func__);; |
11228 | return CAPS_BADVALUE-311; |
11229 | } |
11230 | |
11231 | /*! \page feaAeroReference |
11232 | * |
11233 | * \if ASTROS |
11234 | * <ul> |
11235 | * <li> <B>referenceNode</B> </li> <br> |
11236 | * Defines the reference <c>capsReference</c> for the node to be used for stability derivative calculations. |
11237 | * </ul> |
11238 | * \endif |
11239 | */ |
11240 | keyword = "referenceNode"; |
11241 | status = json_getString( |
11242 | aeroRefInput, keyword, &refNodeName); |
11243 | if (status == CAPS_SUCCESS0) { |
11244 | |
11245 | // find node with capsReference == refNodeName |
11246 | |
11247 | status = get_mapAttrToIndexIndex(attrMap, refNodeName, &attrIndex); |
11248 | if (status != CAPS_SUCCESS0) { |
11249 | PRINT_ERROR("capsGroup name %s not found in attribute to index map", refNodeName)fprintf(stderr, "\n" "--------------------------------------------------------------------------------\n" "[ ERROR ]\n" "File: %s\n" "Line: %d\n" "Function: %s\n" "Reason: " "capsGroup name %s not found in attribute to index map" "\n" "--------------------------------------------------------------------------------\n" "\n", "feaUtils.c", 11249, __func__, refNodeName);; |
11250 | goto cleanup; |
11251 | } |
11252 | |
11253 | status = mesh_findNodes( |
11254 | &feaProblem->feaMesh, _matchReferenceNode, &attrIndex, &numNodes, &nodes); |
11255 | if (status == CAPS_NOTFOUND-303) { |
11256 | PRINT_ERROR("No node found with capsReference name %s", refNodeName)fprintf(stderr, "\n" "--------------------------------------------------------------------------------\n" "[ ERROR ]\n" "File: %s\n" "Line: %d\n" "Function: %s\n" "Reason: " "No node found with capsReference name %s" "\n" "--------------------------------------------------------------------------------\n" "\n", "feaUtils.c", 11256, __func__, refNodeName);; |
11257 | } |
11258 | if (status != CAPS_SUCCESS0) { |
11259 | goto cleanup; |
11260 | } |
11261 | |
11262 | // set refGridID to the nodeID |
11263 | feaProblem->feaAeroRef.refGridID = nodes[0]->nodeID; |
11264 | } |
11265 | |
11266 | status = CAPS_SUCCESS0; |
11267 | |
11268 | cleanup: |
11269 | |
11270 | if (refNodeName != NULL((void*)0)) EG_free(refNodeName); |
11271 | if (nodes != NULL((void*)0)) EG_free(nodes); |
11272 | |
11273 | return status; |
11274 | } |
11275 | |
11276 | // Find feaPropertyStructs with given names in feaProblem |
11277 | int fea_findPropertiesByNames(feaProblemStruct *feaProblem, |
11278 | int numPropertyNames, |
11279 | char **propertyNames, |
11280 | int *numProperties, |
11281 | feaPropertyStruct ***properties) { |
11282 | int i, status; |
11283 | |
11284 | int numFound; |
11285 | feaPropertyStruct **propertiesFound, *property; |
11286 | |
11287 | propertiesFound = EG_alloc(sizeof(feaPropertyStruct *) * numPropertyNames); |
11288 | |
11289 | numFound = 0; |
11290 | for (i = 0; i < feaProblem->numProperty; i++) { |
11291 | |
11292 | property = &feaProblem->feaProperty[i]; |
11293 | |
11294 | if (string_isInArray(property->name, numPropertyNames, propertyNames)) { |
11295 | |
11296 | propertiesFound[numFound++] = property; |
11297 | |
11298 | if (numFound == numPropertyNames) { |
11299 | // found all |
11300 | break; |
11301 | } |
11302 | } |
11303 | } |
11304 | |
11305 | if (numFound < numPropertyNames) { |
11306 | propertiesFound = EG_reall(propertiesFound, sizeof(feaPropertyStruct *) * numFound); |
11307 | status = CAPS_NOTFOUND-303; |
11308 | } |
11309 | else { |
11310 | status = CAPS_SUCCESS0; |
11311 | } |
11312 | |
11313 | *numProperties = numFound; |
11314 | *properties = propertiesFound; |
11315 | |
11316 | return status; |
11317 | } |
11318 | |
11319 | // Find feaMaterialStructs with given names in feaProblem |
11320 | int fea_findMaterialsByNames(feaProblemStruct *feaProblem, |
11321 | int numMaterialNames, |
11322 | char **materialNames, |
11323 | int *numMaterials, |
11324 | feaMaterialStruct ***materials) { |
11325 | int i, status; |
11326 | |
11327 | int numFound; |
11328 | feaMaterialStruct **materialsFound, *material; |
11329 | |
11330 | materialsFound = EG_alloc(sizeof(feaMaterialStruct *) * numMaterialNames); |
11331 | |
11332 | numFound = 0; |
11333 | for (i = 0; i < feaProblem->numMaterial; i++) { |
11334 | |
11335 | material = &feaProblem->feaMaterial[i]; |
11336 | |
11337 | if (string_isInArray(material->name, numMaterialNames, materialNames)) { |
11338 | |
11339 | materialsFound[numFound++] = material; |
11340 | |
11341 | if (numFound == numMaterialNames) { |
11342 | // found all |
11343 | break; |
11344 | } |
11345 | } |
11346 | } |
11347 | |
11348 | if (numFound < numMaterialNames) { |
11349 | materialsFound = EG_reall(materialsFound, sizeof(feaMaterialStruct *) * numFound); |
11350 | status = CAPS_NOTFOUND-303; |
11351 | } |
11352 | else { |
11353 | status = CAPS_SUCCESS0; |
11354 | } |
11355 | |
11356 | *numMaterials = numFound; |
11357 | *materials = materialsFound; |
11358 | |
11359 | return status; |
11360 | } |
11361 | |
11362 | // Find feaDesignVariableStructs with given names in feaProblem |
11363 | int fea_findDesignVariablesByNames(const feaProblemStruct *feaProblem, |
11364 | int numDesignVariableNames, |
11365 | char **designVariableNames, |
11366 | int *numDesignVariables, |
11367 | feaDesignVariableStruct ***designVariables) { |
11368 | int i, status; |
11369 | |
11370 | int numFound; |
11371 | feaDesignVariableStruct **designVariablesFound=NULL((void*)0), *designVariable=NULL((void*)0); |
11372 | |
11373 | designVariablesFound = (feaDesignVariableStruct **) EG_alloc(numDesignVariableNames * sizeof(feaDesignVariableStruct *)); |
11374 | |
11375 | numFound = 0; |
11376 | for (i = 0; i < feaProblem->numDesignVariable; i++) { |
11377 | |
11378 | designVariable = &feaProblem->feaDesignVariable[i]; |
11379 | |
11380 | if (string_isInArray(designVariable->name, numDesignVariableNames, designVariableNames)) { |
11381 | |
11382 | designVariablesFound[numFound++] = designVariable; |
11383 | |
11384 | if (numFound == numDesignVariableNames) { |
11385 | // found all |
11386 | break; |
11387 | } |
11388 | } |
11389 | } |
11390 | |
11391 | if (numFound < numDesignVariableNames) { |
11392 | designVariablesFound = EG_reall(designVariablesFound, numFound * sizeof(feaDesignVariableStruct *)); |
11393 | status = CAPS_NOTFOUND-303; |
11394 | } else { |
11395 | status = CAPS_SUCCESS0; |
11396 | } |
11397 | |
11398 | *numDesignVariables = numFound; |
11399 | *designVariables = designVariablesFound; |
11400 | |
11401 | return status; |
11402 | } |
11403 | |
11404 | // Find feaDesignResponseStructs with given names in feaProblem |
11405 | int fea_findDesignResponsesByNames(const feaProblemStruct *feaProblem, |
11406 | int numDesignResponseNames, |
11407 | char **designResponseNames, |
11408 | int *numDesignResponses, |
11409 | feaDesignResponseStruct ***designResponses) { |
11410 | int i, status; |
11411 | |
11412 | int numFound; |
11413 | feaDesignResponseStruct **designResponsesFound, *designResponse; |
11414 | |
11415 | designResponsesFound = EG_alloc(sizeof(feaDesignResponseStruct *) * numDesignResponseNames); |
11416 | |
11417 | numFound = 0; |
11418 | for (i = 0; i < feaProblem->numDesignResponse; i++) { |
11419 | |
11420 | designResponse = &feaProblem->feaDesignResponse[i]; |
11421 | |
11422 | if (string_isInArray(designResponse->name, numDesignResponseNames, designResponseNames)) { |
11423 | |
11424 | designResponsesFound[numFound++] = designResponse; |
11425 | |
11426 | if (numFound == numDesignResponseNames) { |
11427 | // found all |
11428 | break; |
11429 | } |
11430 | } |
11431 | } |
11432 | |
11433 | if (numFound < numDesignResponseNames) { |
11434 | designResponsesFound = EG_reall(designResponsesFound, sizeof(feaDesignResponseStruct *) * numFound); |
11435 | status = CAPS_NOTFOUND-303; |
11436 | } |
11437 | else { |
11438 | status = CAPS_SUCCESS0; |
11439 | } |
11440 | |
11441 | *numDesignResponses = numFound; |
11442 | *designResponses = designResponsesFound; |
11443 | |
11444 | return status; |
11445 | } |
11446 | |
11447 | // Find feaDesignEquationResponseStructs with given names in feaProblem |
11448 | int fea_findEquationResponsesByNames(const feaProblemStruct *feaProblem, |
11449 | int numEquationResponseNames, |
11450 | char **equationResponseNames, |
11451 | int *numEquationResponses, |
11452 | feaDesignEquationResponseStruct ***equationResponses) { |
11453 | int i, status; |
11454 | |
11455 | int numFound; |
11456 | feaDesignEquationResponseStruct **equationResponsesFound, *equationResponse; |
11457 | |
11458 | equationResponsesFound = EG_alloc(sizeof(feaDesignEquationResponseStruct *) * numEquationResponseNames); |
11459 | |
11460 | numFound = 0; |
11461 | for (i = 0; i < feaProblem->numEquationResponse; i++) { |
11462 | |
11463 | equationResponse = &feaProblem->feaEquationResponse[i]; |
11464 | |
11465 | if (string_isInArray(equationResponse->name, numEquationResponseNames, equationResponseNames)) { |
11466 | |
11467 | equationResponsesFound[numFound++] = equationResponse; |
11468 | |
11469 | if (numFound == numEquationResponseNames) { |
11470 | // found all |
11471 | break; |
11472 | } |
11473 | } |
11474 | } |
11475 | |
11476 | if (numFound < numEquationResponseNames) { |
11477 | equationResponsesFound = EG_reall(equationResponsesFound, sizeof(feaDesignEquationResponseStruct *) * numFound); |
11478 | status = CAPS_NOTFOUND-303; |
11479 | } |
11480 | else { |
11481 | status = CAPS_SUCCESS0; |
11482 | } |
11483 | |
11484 | *numEquationResponses = numFound; |
11485 | *equationResponses = equationResponsesFound; |
11486 | |
11487 | return status; |
11488 | } |
11489 | |
11490 | // Find feaDesignEquationStruct with given equationName in feaProblem |
11491 | int fea_findEquationByName(const feaProblemStruct *feaProblem, char *equationName, feaDesignEquationStruct **equation) { |
11492 | |
11493 | int i; |
11494 | |
11495 | for (i = 0; i < feaProblem->numEquation; i++) { |
11496 | |
11497 | if (strcmp(feaProblem->feaEquation[i].name, equationName) == 0) { |
11498 | *equation = &feaProblem->feaEquation[i]; |
11499 | return CAPS_SUCCESS0; |
11500 | } |
11501 | } |
11502 | |
11503 | return CAPS_NOTFOUND-303; |
11504 | } |
11505 | |
11506 | // Find vlmControlStruct with given controlSurfName in feaProble |
11507 | int fea_findControlSurfaceByName(const feaProblemStruct *feaProblem, char *controlSurfName, vlmControlStruct **controlSurf) { |
11508 | |
11509 | int isection, icontrol; |
11510 | |
11511 | vlmSurfaceStruct *surface; |
11512 | vlmSectionStruct *section; |
11513 | |
11514 | surface = &feaProblem->feaAero->vlmSurface; |
11515 | |
11516 | for (isection = 0; isection < surface->numSection; isection++) { |
11517 | |
11518 | section = &surface->vlmSection[isection]; |
11519 | |
11520 | for (icontrol = 0; icontrol < section->numControl; icontrol++) { |
11521 | |
11522 | if (strcmp(section->vlmControl[icontrol].name, controlSurfName) == 0) { |
11523 | *controlSurf = §ion->vlmControl[icontrol]; |
11524 | return CAPS_SUCCESS0; |
11525 | } |
11526 | } |
11527 | } |
11528 | |
11529 | return CAPS_NOTFOUND-303; |
11530 | } |
11531 | |
11532 | // Find feaDesignConstraintStruct with given constraintType in feaProblem |
11533 | int fea_findDesignConstraintByType(const feaProblemStruct *feaProblem, feaDesignConstraintTypeEnum constraintType, feaDesignConstraintStruct **designConstraint) { |
11534 | |
11535 | int i; |
11536 | |
11537 | for (i = 0; i < feaProblem->numDesignConstraint; i++) { |
11538 | |
11539 | if (feaProblem->feaDesignConstraint[i].designConstraintType == constraintType) { |
11540 | *designConstraint = &feaProblem->feaDesignConstraint[i]; |
11541 | return CAPS_SUCCESS0; |
11542 | } |
11543 | } |
11544 | |
11545 | return CAPS_NOTFOUND-303; |
11546 | } |
11547 | |
11548 | static inline int _feaDesignVariableRelation_linkDesignVariable(feaDesignVariableRelationStruct *relation, |
11549 | feaDesignVariableStruct *desvar, |
11550 | int desvarIndex) { |
11551 | if (relation->designVariableSet == NULL((void*)0)) { |
11552 | relation->designVariableSet = ( |
11553 | (feaDesignVariableStruct **) |
11554 | EG_alloc(sizeof(feaDesignVariableStruct *) * relation->numDesignVariable) |
11555 | ); |
11556 | } |
11557 | if (relation->designVariableSet == NULL((void*)0)) { |
11558 | return EGADS_MALLOC-4; |
11559 | } |
11560 | |
11561 | relation->designVariableSet[desvarIndex] = desvar; |
11562 | |
11563 | return CAPS_SUCCESS0; |
11564 | } |
11565 | |
11566 | static inline int _feaDesignVariable_linkDesignVariableRelation(feaDesignVariableStruct *desvar, |
11567 | feaDesignVariableRelationStruct *relation) { |
11568 | |
11569 | if (desvar->numRelation == 0) { |
11570 | desvar->relationSet = ( |
11571 | (feaDesignVariableRelationStruct **) |
11572 | EG_alloc(sizeof(feaDesignVariableRelationStruct *)) |
11573 | ); |
11574 | } |
11575 | else { |
11576 | desvar->relationSet = ( |
11577 | (feaDesignVariableRelationStruct **) |
11578 | EG_reall(desvar->relationSet, sizeof(feaDesignVariableRelationStruct *) * (desvar->numRelation + 1)) |
11579 | ); |
11580 | } |
11581 | if (desvar->relationSet == NULL((void*)0)) { |
11582 | return EGADS_MALLOC-4; |
11583 | } |
11584 | |
11585 | desvar->relationSet[desvar->numRelation] = relation; |
11586 | desvar->numRelation++; |
11587 | |
11588 | return CAPS_SUCCESS0; |
11589 | } |
11590 | |
11591 | // Populate the feaDesignVariable.relationSet and feaDesignVariableRelation.variableSet members |
11592 | // in all feaDesignVariables and feaDesignVariableRelations |
11593 | int fea_linkDesignVariablesAndRelations(const feaProblemStruct *feaProblem) { |
11594 | |
11595 | int status; |
11596 | int idvGlobal, idv, irel; |
11597 | |
11598 | char *desvarName = NULL((void*)0), **desvarNameSet = NULL((void*)0); |
11599 | |
11600 | feaDesignVariableStruct *desvar = NULL((void*)0); |
11601 | feaDesignVariableRelationStruct *desvarRelation = NULL((void*)0); |
11602 | |
11603 | for (irel = 0; irel < feaProblem->numDesignVariableRelation; irel++) { |
11604 | |
11605 | desvarRelation = &feaProblem->feaDesignVariableRelation[irel]; |
11606 | desvarNameSet = desvarRelation->designVariableNameSet; |
11607 | |
11608 | for (idv = 0; idv < desvarRelation->numDesignVariable; idv++) { |
11609 | |
11610 | desvarName = desvarNameSet[idv]; |
11611 | |
11612 | for (idvGlobal = 0; idvGlobal < feaProblem->numDesignVariable; idvGlobal++) { |
11613 | |
11614 | desvar = &feaProblem->feaDesignVariable[idvGlobal]; |
11615 | |
11616 | if (strcmp(desvar->name, desvarName) == 0) { |
11617 | |
11618 | status = _feaDesignVariableRelation_linkDesignVariable(desvarRelation, desvar, idv); |
11619 | if (status != CAPS_SUCCESS0) return status; |
11620 | |
11621 | status = _feaDesignVariable_linkDesignVariableRelation(desvar, desvarRelation); |
11622 | if (status != CAPS_SUCCESS0) return status; |
11623 | break; |
11624 | } |
11625 | } |
11626 | } |
11627 | } |
11628 | |
11629 | return CAPS_SUCCESS0; |
11630 | } |
11631 | |
11632 | // Initiate (0 out all values and NULL all pointers) of feaProblem in the feaProblemStruct structure format |
11633 | int initiate_feaProblemStruct(feaProblemStruct *feaProblem) { |
11634 | |
11635 | int status = 0; |
11636 | |
11637 | // Problem analysis |
11638 | feaProblem->numAnalysis = 0; |
11639 | feaProblem->feaAnalysis = NULL((void*)0); |
11640 | |
11641 | // Materials |
11642 | feaProblem->numMaterial = 0; |
11643 | feaProblem->feaMaterial = NULL((void*)0); |
11644 | |
11645 | // Properties |
11646 | feaProblem->numProperty = 0; |
11647 | feaProblem->feaProperty = NULL((void*)0); |
11648 | |
11649 | // Constraints |
11650 | feaProblem->numConstraint = 0; |
11651 | feaProblem->feaConstraint = NULL((void*)0); |
11652 | |
11653 | // Supports |
11654 | feaProblem->numSupport = 0; |
11655 | feaProblem->feaSupport = NULL((void*)0); |
11656 | |
11657 | // Loads |
11658 | feaProblem->numLoad = 0; |
11659 | feaProblem->feaLoad = NULL((void*)0); |
11660 | |
11661 | // Connections |
11662 | feaProblem->numConnect = 0; |
11663 | feaProblem->feaConnect = NULL((void*)0); |
11664 | |
11665 | // Mesh |
11666 | status = initiate_meshStruct(&feaProblem->feaMesh); |
11667 | if (status != CAPS_SUCCESS0) goto cleanup; |
11668 | |
11669 | // Output formatting |
11670 | status = initiate_feaFileFormatStruct(&feaProblem->feaFileFormat); |
11671 | if (status != CAPS_SUCCESS0) goto cleanup; |
11672 | |
11673 | // Optimization - Design Variables |
11674 | feaProblem->numDesignVariable = 0; |
11675 | feaProblem->feaDesignVariable = NULL((void*)0); |
11676 | |
11677 | // Optimization - Design Variable Relations |
11678 | feaProblem->numDesignVariableRelation = 0; |
11679 | feaProblem->feaDesignVariableRelation = NULL((void*)0); |
11680 | |
11681 | // Optimization - Design Constraints |
11682 | feaProblem->numDesignConstraint = 0; |
11683 | feaProblem->feaDesignConstraint = NULL((void*)0); |
11684 | |
11685 | // Optimization - Equations |
11686 | feaProblem->numEquation = 0; |
11687 | feaProblem->feaEquation = NULL((void*)0); |
11688 | |
11689 | // Optimization - Table Constants |
11690 | status = initiate_feaDesignTableStruct(&feaProblem->feaDesignTable); |
11691 | if (status != CAPS_SUCCESS0) goto cleanup; |
11692 | |
11693 | // Optimization - Design Optimization Parameters |
11694 | status = initiate_feaDesignOptParamStruct(&feaProblem->feaDesignOptParam); |
11695 | if (status != CAPS_SUCCESS0) goto cleanup; |
11696 | |
11697 | // Optimization - Design Sensitivity Response Quantities |
11698 | feaProblem->numDesignResponse = 0; |
11699 | feaProblem->feaDesignResponse = NULL((void*)0); |
11700 | |
11701 | // Optimization - Design Sensitivity Equation Response Quantities |
11702 | feaProblem->numEquationResponse = 0; |
11703 | feaProblem->feaEquationResponse = NULL((void*)0); |
11704 | |
11705 | // Coordinate Systems |
11706 | feaProblem->numCoordSystem = 0; |
11707 | feaProblem->feaCoordSystem = NULL((void*)0); |
11708 | |
11709 | // Aerodynamics |
11710 | feaProblem->numAero = 0; |
11711 | feaProblem->feaAero = NULL((void*)0); |
11712 | status = initiate_feaAeroRefStruct(&feaProblem->feaAeroRef); |
11713 | if (status != CAPS_SUCCESS0) goto cleanup; |
11714 | |
11715 | aim_initMeshRef(&feaProblem->meshRefObj, aimUnknownMeshType); |
11716 | feaProblem->meshRefIn = NULL((void*)0); |
11717 | |
11718 | status = CAPS_SUCCESS0; |
11719 | |
11720 | cleanup: |
11721 | if (status != CAPS_SUCCESS0) printf("Error: Status %d during initiate_feaProblemStruct!\n", status); |
11722 | |
11723 | return status; |
11724 | } |
11725 | |
11726 | // Destroy (0 out all values and NULL all pointers) of feaProblem in the feaProblemStruct structure format |
11727 | int destroy_feaProblemStruct(feaProblemStruct *feaProblem) { |
11728 | |
11729 | int i; // Indexing |
11730 | |
11731 | int status = 0; // Status return |
11732 | |
11733 | // Analysis |
11734 | if (feaProblem->feaAnalysis != NULL((void*)0)) { |
11735 | for (i = 0; i < feaProblem->numAnalysis; i++) { |
11736 | status = destroy_feaAnalysisStruct(&feaProblem->feaAnalysis[i]); |
11737 | if (status != CAPS_SUCCESS0) printf("Status %d during destroy_feaAnalysisStruct\n", status); |
11738 | } |
11739 | } |
11740 | AIM_FREE(feaProblem->feaAnalysis){ EG_free(feaProblem->feaAnalysis); feaProblem->feaAnalysis = ((void*)0); }; |
11741 | feaProblem->numAnalysis = 0; |
11742 | |
11743 | // Materials |
11744 | if (feaProblem->feaMaterial != NULL((void*)0)) { |
11745 | for (i = 0; i < feaProblem->numMaterial; i++) { |
11746 | status = destroy_feaMaterialStruct(&feaProblem->feaMaterial[i]); |
11747 | if (status != CAPS_SUCCESS0) printf("Status %d during destroy_feaMaterialStruct\n", status); |
11748 | } |
11749 | } |
11750 | AIM_FREE(feaProblem->feaMaterial){ EG_free(feaProblem->feaMaterial); feaProblem->feaMaterial = ((void*)0); }; |
11751 | feaProblem->numMaterial = 0; |
11752 | |
11753 | // Properties |
11754 | if (feaProblem->feaProperty != NULL((void*)0)) { |
11755 | for (i = 0; i < feaProblem->numProperty; i++) { |
11756 | status = destroy_feaPropertyStruct(&feaProblem->feaProperty[i]); |
11757 | if (status != CAPS_SUCCESS0) printf("Status %d during destroy_feaPropertyStruct\n", status); |
11758 | } |
11759 | } |
11760 | AIM_FREE(feaProblem->feaProperty){ EG_free(feaProblem->feaProperty); feaProblem->feaProperty = ((void*)0); }; |
11761 | feaProblem->numProperty = 0; |
11762 | |
11763 | // Constraints |
11764 | if (feaProblem->feaConstraint != NULL((void*)0)) { |
11765 | for (i = 0; i < feaProblem->numConstraint; i++) { |
11766 | status = destroy_feaConstraintStruct(&feaProblem->feaConstraint[i]); |
11767 | if (status != CAPS_SUCCESS0) printf("Status %d during destroy_feaConstraintStruct\n", status); |
11768 | } |
11769 | } |
11770 | AIM_FREE(feaProblem->feaConstraint){ EG_free(feaProblem->feaConstraint); feaProblem->feaConstraint = ((void*)0); }; |
11771 | feaProblem->numConstraint = 0; |
11772 | |
11773 | // Supports |
11774 | if (feaProblem->feaSupport != NULL((void*)0)) { |
11775 | for (i = 0; i < feaProblem->numSupport; i++) { |
11776 | status = destroy_feaSupportStruct(&feaProblem->feaSupport[i]); |
11777 | if (status != CAPS_SUCCESS0) printf("Status %d during destroy_feaSupportStruct\n", status); |
11778 | } |
11779 | } |
11780 | AIM_FREE(feaProblem->feaSupport){ EG_free(feaProblem->feaSupport); feaProblem->feaSupport = ((void*)0); }; |
11781 | feaProblem->numSupport = 0; |
11782 | |
11783 | // Loads |
11784 | if (feaProblem->feaLoad != NULL((void*)0)) { |
11785 | for (i = 0; i < feaProblem->numLoad; i++) { |
11786 | status = destroy_feaLoadStruct(&feaProblem->feaLoad[i]); |
11787 | if (status != CAPS_SUCCESS0) printf("Status %d during destroy_feaLoadStruct\n", status); |
11788 | } |
11789 | } |
11790 | AIM_FREE(feaProblem->feaLoad){ EG_free(feaProblem->feaLoad); feaProblem->feaLoad = ( (void*)0); }; |
11791 | feaProblem->numLoad = 0; |
11792 | |
11793 | // Connections |
11794 | if (feaProblem->feaConnect != NULL((void*)0)) { |
11795 | for (i = 0; i < feaProblem->numConnect; i++) { |
11796 | status = destroy_feaConnectionStruct(&feaProblem->feaConnect[i]); |
11797 | if (status != CAPS_SUCCESS0) printf("Status %d during destroy_feaConnectStruct\n", status); |
11798 | } |
11799 | } |
11800 | AIM_FREE(feaProblem->feaConnect){ EG_free(feaProblem->feaConnect); feaProblem->feaConnect = ((void*)0); }; |
11801 | feaProblem->numConnect = 0; |
11802 | |
11803 | // Mesh |
11804 | status = destroy_meshStruct(&feaProblem->feaMesh); |
11805 | if (status != CAPS_SUCCESS0) printf("Status %d during destroy_meshStruct\n", status); |
11806 | |
11807 | // Output formatting |
11808 | status = destroy_feaFileFormatStruct(&feaProblem->feaFileFormat); |
11809 | if (status != CAPS_SUCCESS0) printf("Status %d during destroy_feaFileFormatStruct\n", status); |
11810 | |
11811 | |
11812 | if (feaProblem->feaDesignVariable != NULL((void*)0)) { |
11813 | for (i = 0; i < feaProblem->numDesignVariable; i++) { |
11814 | status = destroy_feaDesignVariableStruct(&feaProblem->feaDesignVariable[i]); |
11815 | if (status != CAPS_SUCCESS0) printf("Status %d during destroy_feaDesignVariableStruct\n", status); |
11816 | } |
11817 | } |
11818 | AIM_FREE(feaProblem->feaDesignVariable){ EG_free(feaProblem->feaDesignVariable); feaProblem->feaDesignVariable = ((void*)0); }; |
11819 | feaProblem->numDesignVariable = 0; |
11820 | |
11821 | // Optimization - design variable relations |
11822 | if (feaProblem->feaDesignVariableRelation != NULL((void*)0)) { |
11823 | for (i = 0; i < feaProblem->numDesignVariableRelation; i++) { |
11824 | status = destroy_feaDesignVariableRelationStruct(&feaProblem->feaDesignVariableRelation[i]); |
11825 | if (status != CAPS_SUCCESS0) printf("Status %d during destroy_feaDesignVariableRelationStruct\n", status); |
11826 | } |
11827 | AIM_FREE(feaProblem->feaDesignVariableRelation){ EG_free(feaProblem->feaDesignVariableRelation); feaProblem ->feaDesignVariableRelation = ((void*)0); }; |
11828 | } |
11829 | feaProblem->numDesignVariableRelation = 0; |
11830 | |
11831 | // Optimization - design constraint |
11832 | if (feaProblem->feaDesignConstraint != NULL((void*)0)) { |
11833 | for (i = 0; i < feaProblem->numDesignConstraint; i++) { |
11834 | status = destroy_feaDesignConstraintStruct(&feaProblem->feaDesignConstraint[i]); |
11835 | if (status != CAPS_SUCCESS0) printf("Status %d during destroy_feaDesignConstraintStruct\n", status); |
11836 | } |
11837 | } |
11838 | AIM_FREE(feaProblem->feaDesignConstraint){ EG_free(feaProblem->feaDesignConstraint); feaProblem-> feaDesignConstraint = ((void*)0); }; |
11839 | feaProblem->numDesignConstraint = 0; |
11840 | |
11841 | // Optimization - Equations |
11842 | if (feaProblem->feaEquation != NULL((void*)0)) { |
11843 | for (i = 0; i < feaProblem->numEquation; i++) { |
11844 | status = destroy_feaDesignEquationStruct(&feaProblem->feaEquation[i]); |
11845 | if (status != CAPS_SUCCESS0) printf("Status %d during destroy_feaDesignEquationStruct\n", status); |
11846 | } |
11847 | AIM_FREE(feaProblem->feaEquation){ EG_free(feaProblem->feaEquation); feaProblem->feaEquation = ((void*)0); }; |
11848 | } |
11849 | feaProblem->numEquation = 0; |
11850 | |
11851 | // Optimization - Table Constants |
11852 | status = destroy_feaDesignTableStruct(&feaProblem->feaDesignTable); |
11853 | if (status != CAPS_SUCCESS0) printf("Status %d during destroy_feaDesignTableStruct\n", status); |
11854 | |
11855 | // Optimization - Design Optimization Parameters |
11856 | status = destroy_feaDesignOptParamStruct(&feaProblem->feaDesignOptParam); |
11857 | if (status != CAPS_SUCCESS0) printf("Status %d during destroy_feaDesignOptParamStruct\n", status); |
11858 | |
11859 | // Optimization - Design Sensitivity Response Quantities |
11860 | if (feaProblem->feaDesignResponse != NULL((void*)0)) { |
11861 | for (i = 0; i < feaProblem->numDesignResponse; i++) { |
11862 | status = destroy_feaDesignResponseStruct(&feaProblem->feaDesignResponse[i]); |
11863 | if (status != CAPS_SUCCESS0) printf("Status %d during destroy_feaDesignResponseStruct\n", status); |
11864 | } |
11865 | AIM_FREE(feaProblem->feaDesignResponse){ EG_free(feaProblem->feaDesignResponse); feaProblem->feaDesignResponse = ((void*)0); }; |
11866 | } |
11867 | feaProblem->numDesignResponse = 0; |
11868 | |
11869 | // Optimization - Design Sensitivity Equation Response Quantities |
11870 | if (feaProblem->feaEquationResponse != NULL((void*)0)) { |
11871 | for (i = 0; i < feaProblem->numEquationResponse; i++) { |
11872 | status = destroy_feaDesignEquationResponseStruct(&feaProblem->feaEquationResponse[i]); |
11873 | if (status != CAPS_SUCCESS0) printf("Status %d during destroy_feaEquationResponseStruct\n", status); |
11874 | } |
11875 | AIM_FREE(feaProblem->feaEquationResponse){ EG_free(feaProblem->feaEquationResponse); feaProblem-> feaEquationResponse = ((void*)0); }; |
11876 | } |
11877 | feaProblem->numEquationResponse = 0; |
11878 | |
11879 | // Coordinate Systems |
11880 | if (feaProblem->feaCoordSystem != NULL((void*)0)) { |
11881 | |
11882 | for (i = 0; i < feaProblem->numCoordSystem; i++) { |
11883 | status = destroy_feaCoordSystemStruct(&feaProblem->feaCoordSystem[i]); |
11884 | if (status != CAPS_SUCCESS0) printf("Status %d during destroy_feaCoordSystemStruct\n", status); |
11885 | } |
11886 | } |
11887 | AIM_FREE(feaProblem->feaCoordSystem){ EG_free(feaProblem->feaCoordSystem); feaProblem->feaCoordSystem = ((void*)0); }; |
11888 | feaProblem->numCoordSystem = 0; |
11889 | |
11890 | // Aerodynamics |
11891 | if (feaProblem->feaAero != NULL((void*)0)) { |
11892 | |
11893 | for (i = 0; i < feaProblem->numAero; i++) { |
11894 | status = destroy_feaAeroStruct(&feaProblem->feaAero[i]); |
11895 | if (status != CAPS_SUCCESS0) printf("Status %d during destroy_feaAeroStruct\n", status); |
11896 | } |
11897 | } |
11898 | AIM_FREE(feaProblem->feaAero){ EG_free(feaProblem->feaAero); feaProblem->feaAero = ( (void*)0); }; |
11899 | feaProblem->numAero = 0; |
11900 | |
11901 | (void) destroy_feaAeroRefStruct(&feaProblem->feaAeroRef); |
11902 | |
11903 | aim_freeMeshRef(&feaProblem->meshRefObj); |
11904 | feaProblem->meshRefIn = NULL((void*)0); |
11905 | |
11906 | return CAPS_SUCCESS0; |
11907 | } |
11908 | |
11909 | // Initiate (0 out all values and NULL all pointers) of feaFileFormat in the feaFileFormatStruct structure format |
11910 | int initiate_feaFileFormatStruct(feaFileFormatStruct *feaFileFormat) { |
11911 | |
11912 | feaFileFormat->fileType = SmallField; |
11913 | |
11914 | feaFileFormat->gridFileType = LargeField; |
11915 | |
11916 | return CAPS_SUCCESS0; |
11917 | } |
11918 | |
11919 | // Destroy (0 out all values and NULL all pointers) of feaFileFormat in the feaFileFormatStruct structure format |
11920 | int destroy_feaFileFormatStruct(feaFileFormatStruct *feaFileFormat) { |
11921 | |
11922 | feaFileFormat->fileType = SmallField; |
11923 | |
11924 | feaFileFormat->gridFileType = LargeField; |
11925 | |
11926 | return CAPS_SUCCESS0; |
11927 | } |
11928 | |
11929 | // Transfer external pressure from the discrObj into the feaLoad structure |
11930 | int fea_transferExternalPressure(void *aimInfo, const meshStruct *feaMesh, feaLoadStruct *feaLoad) { |
11931 | |
11932 | // [in/out] feaLoad |
11933 | // [in] feaMesh |
11934 | // [in] aimInfo |
11935 | |
11936 | int status; // Function status return |
11937 | |
11938 | int i, j, bIndex; // Indexing |
11939 | |
11940 | // Variables used in global node mapping |
11941 | int globalNodeID; |
11942 | int nodeIndex[4], transferIndex[4], elementID, elementIndex, elementCount; |
11943 | |
11944 | // Discrete data transfer variables |
11945 | capsDiscr *dataTransferDiscreteObj; |
11946 | char **transferName = NULL((void*)0); |
11947 | int numTransferName, transferNameIndex; |
11948 | enum capsdMethod dataTransferMethod; |
11949 | int numDataTransferPoint; |
11950 | int numDataTransferElement = 0, discElements; |
11951 | int dataTransferRank; |
11952 | double *dataTransferData; |
11953 | char *units; |
11954 | |
11955 | feaLoad->numElementID = 0; |
11956 | AIM_FREE(feaLoad->pressureMultiDistributeForce){ EG_free(feaLoad->pressureMultiDistributeForce); feaLoad-> pressureMultiDistributeForce = ((void*)0); }; |
11957 | AIM_FREE(feaLoad->elementIDSet){ EG_free(feaLoad->elementIDSet); feaLoad->elementIDSet = ((void*)0); }; |
11958 | |
11959 | //See if we have data transfer information |
11960 | status = aim_getBounds(aimInfo, &numTransferName, &transferName); |
11961 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 11961 , __func__, 0); goto cleanup; }; |
11962 | |
11963 | numDataTransferElement = 0; |
11964 | elementIndex = 0; |
11965 | elementCount = 0; |
11966 | |
11967 | for (transferNameIndex = 0; transferNameIndex < numTransferName; transferNameIndex++) { |
11968 | |
11969 | status = aim_getDiscr(aimInfo, transferName[transferNameIndex], &dataTransferDiscreteObj); |
11970 | if (status == CAPS_NOTFOUND-303) continue; |
11971 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 11971 , __func__, 0); goto cleanup; }; |
11972 | |
11973 | status = aim_getDataSet(dataTransferDiscreteObj, |
11974 | "Pressure", |
11975 | &dataTransferMethod, |
11976 | &numDataTransferPoint, |
11977 | &dataTransferRank, |
11978 | &dataTransferData, |
11979 | &units); |
11980 | if (status == CAPS_NOTFOUND-303) continue; // If no elements in this object skip to next transfer name |
11981 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 11981 , __func__, 0); goto cleanup; }; |
11982 | |
11983 | printf("Extracting external pressure loads from data transfer....\n"); |
11984 | |
11985 | // If we do have data ready, how many elements there are? |
11986 | if (numDataTransferPoint == 1) { |
11987 | AIM_ERROR(aimInfo, "Pressures not initialized!"){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 11987, __func__ , "Pressures not initialized!"); }; |
11988 | status = CAPS_BADINIT-338; |
11989 | goto cleanup; |
11990 | } |
11991 | |
11992 | if (dataTransferRank != 1) { |
11993 | AIM_ERROR(aimInfo, "Pressure transfer data found however rank is %d not 1!!!!", dataTransferRank){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 11993, __func__ , "Pressure transfer data found however rank is %d not 1!!!!" , dataTransferRank); }; |
11994 | status = CAPS_BADRANK-301; |
11995 | goto cleanup; |
11996 | } |
11997 | |
11998 | discElements = 0; |
11999 | for (bIndex = 0; bIndex < dataTransferDiscreteObj->nBodys; bIndex++) |
12000 | discElements += dataTransferDiscreteObj->bodys[bIndex].nElems; |
12001 | |
12002 | numDataTransferElement += discElements; |
12003 | printf("\tTransferName = %s\n", transferName[transferNameIndex]); |
12004 | printf("\tNumber of Elements = %d (total = %d)\n", discElements, numDataTransferElement); |
12005 | |
12006 | // allocate arrays |
12007 | AIM_REALL(feaLoad->elementIDSet, numDataTransferElement, int, aimInfo, status){ size_t memorysize = numDataTransferElement; feaLoad->elementIDSet = (int *) EG_reall(feaLoad->elementIDSet, memorysize*sizeof (int)); if (feaLoad->elementIDSet == ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 12007, __func__ , 3, "AIM_REALL: %s size %zu type %s", "feaLoad->elementIDSet" , memorysize, "int"); goto cleanup; } }; |
12008 | AIM_REALL(feaLoad->pressureMultiDistributeForce, 4*numDataTransferElement, double, aimInfo, status){ size_t memorysize = 4*numDataTransferElement; feaLoad->pressureMultiDistributeForce = (double *) EG_reall(feaLoad->pressureMultiDistributeForce , memorysize*sizeof(double)); if (feaLoad->pressureMultiDistributeForce == ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c" , 12008, __func__, 3, "AIM_REALL: %s size %zu type %s", "feaLoad->pressureMultiDistributeForce" , memorysize, "double"); goto cleanup; } }; |
12009 | |
12010 | //Now lets loop through our ctria3 mesh and get the node indexes for each element |
12011 | for (i = 0; i < feaMesh->numElement; i++) { |
12012 | |
12013 | if (feaMesh->element[i].elementType != Triangle) continue; |
12014 | |
12015 | elementID = feaMesh->element[i].elementID; |
12016 | //printf("Element Id = %d\n", elementID); |
12017 | |
12018 | // elementID is 1 bias |
12019 | nodeIndex[0] = feaMesh->element[i].connectivity[0]; |
12020 | nodeIndex[1] = feaMesh->element[i].connectivity[1]; |
12021 | nodeIndex[2] = feaMesh->element[i].connectivity[2]; |
12022 | |
12023 | //printf("Node Index = %d %d %d\n", nodeIndex[0], nodeIndex[1], nodeIndex[2]); |
12024 | |
12025 | transferIndex[0] = -1; |
12026 | transferIndex[1] = -1; |
12027 | transferIndex[2] = -1; |
12028 | transferIndex[3] = -1; |
12029 | |
12030 | // Loop through the nodeMap of the data set getting nodeIDs trying |
12031 | // to match the nodes in the element |
12032 | for (j = 0; j < numDataTransferPoint; j++) { |
12033 | |
12034 | bIndex = dataTransferDiscreteObj->tessGlobal[2*j ]; |
12035 | globalNodeID = dataTransferDiscreteObj->tessGlobal[2*j+1] + |
12036 | dataTransferDiscreteObj->bodys[bIndex-1].globalOffset; |
12037 | |
12038 | if (nodeIndex[0] == globalNodeID) transferIndex[0] = j; |
12039 | if (nodeIndex[1] == globalNodeID) transferIndex[1] = j; |
12040 | if (nodeIndex[2] == globalNodeID) transferIndex[2] = j; |
12041 | |
12042 | // If the nodes completely match the nodes on the element - break |
12043 | if (transferIndex[0] >= 0 && transferIndex[1] >= 0 && transferIndex[2] >= 0) { |
12044 | break; |
12045 | } |
12046 | } |
12047 | |
12048 | // If all the nodeIndexes match the transferIndex the element is in the data set |
12049 | // so transfer the pressure forces |
12050 | if (transferIndex[0] >= 0 && transferIndex[1] >= 0 && transferIndex[2] >= 0) { |
12051 | |
12052 | feaLoad->elementIDSet[elementIndex] = elementID; |
12053 | |
12054 | feaLoad->pressureMultiDistributeForce[4*elementIndex+0] = dataTransferData[transferIndex[0]]; |
12055 | feaLoad->pressureMultiDistributeForce[4*elementIndex+1] = dataTransferData[transferIndex[1]]; |
12056 | feaLoad->pressureMultiDistributeForce[4*elementIndex+2] = dataTransferData[transferIndex[2]]; |
12057 | feaLoad->pressureMultiDistributeForce[4*elementIndex+3] = 0.0; |
12058 | |
12059 | elementIndex += 1; |
12060 | elementCount += 1; |
12061 | feaLoad->numElementID += 1; |
12062 | |
12063 | } |
12064 | } |
12065 | |
12066 | //Now lets loop through our cquad4 mesh and get the node indexes for each element |
12067 | for (i = 0; i < feaMesh->numElement; i++) { |
12068 | |
12069 | if (feaMesh->element[i].elementType != Quadrilateral) continue; |
12070 | |
12071 | elementID = feaMesh->element[i].elementID; |
12072 | |
12073 | // elementID is 1 bias |
12074 | nodeIndex[0] = feaMesh->element[i].connectivity[0]; |
12075 | nodeIndex[1] = feaMesh->element[i].connectivity[1]; |
12076 | nodeIndex[2] = feaMesh->element[i].connectivity[2]; |
12077 | nodeIndex[3] = feaMesh->element[i].connectivity[3]; |
12078 | |
12079 | transferIndex[0] = -1; |
12080 | transferIndex[1] = -1; |
12081 | transferIndex[2] = -1; |
12082 | transferIndex[3] = -1; |
12083 | |
12084 | // Loop through the nodeMap of the data set getting nodeIDs trying |
12085 | // to match the nodes in the element |
12086 | for (j = 0; j < numDataTransferPoint; j++) { |
12087 | |
12088 | bIndex = dataTransferDiscreteObj->tessGlobal[2*j ]; |
12089 | globalNodeID = dataTransferDiscreteObj->tessGlobal[2*j+1] + |
12090 | dataTransferDiscreteObj->bodys[bIndex-1].globalOffset; |
12091 | |
12092 | if (nodeIndex[0] == globalNodeID) transferIndex[0] = j; |
12093 | if (nodeIndex[1] == globalNodeID) transferIndex[1] = j; |
12094 | if (nodeIndex[2] == globalNodeID) transferIndex[2] = j; |
12095 | if (nodeIndex[3] == globalNodeID) transferIndex[3] = j; |
12096 | |
12097 | // If the nodes completely match the nodes on the element - break |
12098 | if (transferIndex[0] >= 0 && transferIndex[1] >= 0 && |
12099 | transferIndex[2] >= 0 && transferIndex[3] >= 0) { |
12100 | break; |
12101 | } |
12102 | } |
12103 | |
12104 | // If all the nodeIndexes match the transferIndex the element is in the data set |
12105 | // so transfer the pressure forces |
12106 | if (transferIndex[0] >= 0 && transferIndex[1] >= 0 && |
12107 | transferIndex[2] >= 0 && transferIndex[3] >= 0) { |
12108 | |
12109 | feaLoad->elementIDSet[elementIndex] = elementID; |
12110 | |
12111 | feaLoad->pressureMultiDistributeForce[4*elementIndex+0] = dataTransferData[transferIndex[0]]; |
12112 | feaLoad->pressureMultiDistributeForce[4*elementIndex+1] = dataTransferData[transferIndex[1]]; |
12113 | feaLoad->pressureMultiDistributeForce[4*elementIndex+2] = dataTransferData[transferIndex[2]]; |
12114 | feaLoad->pressureMultiDistributeForce[4*elementIndex+3] = dataTransferData[transferIndex[3]]; |
12115 | |
12116 | elementIndex += 1; |
12117 | elementCount += 1; |
12118 | feaLoad->numElementID += 1; |
12119 | } |
12120 | } |
12121 | |
12122 | if (elementCount != numDataTransferElement) { |
12123 | AIM_ERROR(aimInfo, "Element transfer mismatch: number of elements found = %d, number"{ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 12124, __func__ , "Element transfer mismatch: number of elements found = %d, number" " of elements in transfer data set %d", elementCount, numDataTransferElement ); } |
12124 | " of elements in transfer data set %d", elementCount, numDataTransferElement){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 12124, __func__ , "Element transfer mismatch: number of elements found = %d, number" " of elements in transfer data set %d", elementCount, numDataTransferElement ); }; |
12125 | AIM_FREE(transferName){ EG_free(transferName); transferName = ((void*)0); }; |
12126 | |
12127 | status = CAPS_MISMATCH-324; |
12128 | goto cleanup; |
12129 | } |
12130 | |
12131 | // Resize |
12132 | if (feaLoad->numElementID != numDataTransferElement) { |
12133 | AIM_REALL(feaLoad->pressureMultiDistributeForce, 4*feaLoad->numElementID, double, aimInfo, status){ size_t memorysize = 4*feaLoad->numElementID; feaLoad-> pressureMultiDistributeForce = (double *) EG_reall(feaLoad-> pressureMultiDistributeForce, memorysize*sizeof(double)); if ( feaLoad->pressureMultiDistributeForce == ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 12133, __func__ , 3, "AIM_REALL: %s size %zu type %s", "feaLoad->pressureMultiDistributeForce" , memorysize, "double"); goto cleanup; } }; |
12134 | } |
12135 | |
12136 | } // End data transfer name loop |
12137 | |
12138 | |
12139 | status = CAPS_SUCCESS0; |
12140 | |
12141 | cleanup: |
12142 | |
12143 | AIM_FREE(transferName){ EG_free(transferName); transferName = ((void*)0); }; |
12144 | |
12145 | return status; |
12146 | } |
12147 | |
12148 | // Transfer external temperature from the discrObj into the feaLoad structure |
12149 | int fea_transferExternalTemperature(void *aimInfo, feaLoadStruct *feaLoad) { |
12150 | |
12151 | // [in/out] feaLoad |
12152 | // [in] aimInfo |
12153 | |
12154 | int status; // Function status return |
12155 | |
12156 | int i, bIndex; // Indexing |
12157 | |
12158 | // Variables used in global node mapping |
12159 | int globalNodeID; |
12160 | |
12161 | // Discrete data transfer variables |
12162 | capsDiscr *dataTransferDiscreteObj; |
12163 | char **transferName = NULL((void*)0); |
12164 | int numTransferName, transferNameIndex; |
12165 | enum capsdMethod dataTransferMethod; |
12166 | int numDataTransferPoint; |
12167 | int dataTransferRank; |
12168 | double *dataTransferData; |
12169 | char *units; |
12170 | |
12171 | feaLoad->numGridID = 0; |
12172 | AIM_FREE(feaLoad->temperatureMultiDistribute){ EG_free(feaLoad->temperatureMultiDistribute); feaLoad-> temperatureMultiDistribute = ((void*)0); }; |
12173 | AIM_FREE(feaLoad->gridIDSet){ EG_free(feaLoad->gridIDSet); feaLoad->gridIDSet = ((void *)0); }; |
12174 | |
12175 | //See if we have data transfer information |
12176 | status = aim_getBounds(aimInfo, &numTransferName, &transferName); |
12177 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 12177 , __func__, 0); goto cleanup; }; |
12178 | |
12179 | for (transferNameIndex = 0; transferNameIndex < numTransferName; transferNameIndex++) { |
12180 | |
12181 | status = aim_getDiscr(aimInfo, transferName[transferNameIndex], &dataTransferDiscreteObj); |
12182 | if (status == CAPS_NOTFOUND-303) continue; |
12183 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 12183 , __func__, 0); goto cleanup; }; |
12184 | |
12185 | status = aim_getDataSet(dataTransferDiscreteObj, |
12186 | "Temperature", |
12187 | &dataTransferMethod, |
12188 | &numDataTransferPoint, |
12189 | &dataTransferRank, |
12190 | &dataTransferData, |
12191 | &units); |
12192 | if (status == CAPS_NOTFOUND-303) continue; // If no elements in this object skip to next transfer name |
12193 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "feaUtils.c", 12193 , __func__, 0); goto cleanup; }; |
12194 | |
12195 | printf("Extracting external thermal loads from data transfer....\n"); |
12196 | |
12197 | // If we do have data ready, how many elements there are? |
12198 | if (numDataTransferPoint == 1) { |
12199 | AIM_ERROR(aimInfo, "Temperature not initialized!"){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 12199, __func__ , "Temperature not initialized!"); }; |
12200 | status = CAPS_BADINIT-338; |
12201 | goto cleanup; |
12202 | } |
12203 | |
12204 | if (dataTransferRank != 1) { |
12205 | AIM_ERROR(aimInfo, "Temperature transfer data found however rank is %d not 1!!!!", dataTransferRank){ aim_message(aimInfo, CERROR, 0 , "feaUtils.c", 12205, __func__ , "Temperature transfer data found however rank is %d not 1!!!!" , dataTransferRank); }; |
12206 | status = CAPS_BADRANK-301; |
12207 | goto cleanup; |
12208 | } |
12209 | |
12210 | printf("\tTransferName = %s\n", transferName[transferNameIndex]); |
12211 | printf("\tNumber of Nodes = %d (total = %d)\n", numDataTransferPoint, feaLoad->numGridID+numDataTransferPoint); |
12212 | |
12213 | // allocate arrays |
12214 | AIM_REALL(feaLoad->gridIDSet, feaLoad->numGridID+numDataTransferPoint, int, aimInfo, status){ size_t memorysize = feaLoad->numGridID+numDataTransferPoint ; feaLoad->gridIDSet = (int *) EG_reall(feaLoad->gridIDSet , memorysize*sizeof(int)); if (feaLoad->gridIDSet == ((void *)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c" , 12214, __func__, 3, "AIM_REALL: %s size %zu type %s", "feaLoad->gridIDSet" , memorysize, "int"); goto cleanup; } }; |
12215 | AIM_REALL(feaLoad->temperatureMultiDistribute, feaLoad->numGridID+numDataTransferPoint, double, aimInfo, status){ size_t memorysize = feaLoad->numGridID+numDataTransferPoint ; feaLoad->temperatureMultiDistribute = (double *) EG_reall (feaLoad->temperatureMultiDistribute, memorysize*sizeof(double )); if (feaLoad->temperatureMultiDistribute == ((void*)0)) { status = -4; aim_status(aimInfo, status, "feaUtils.c", 12215 , __func__, 3, "AIM_REALL: %s size %zu type %s", "feaLoad->temperatureMultiDistribute" , memorysize, "double"); goto cleanup; } }; |
12216 | |
12217 | // Loop through the nodeMap of the data set getting nodeIDs trying |
12218 | // to match the nodes in the element |
12219 | for (i = 0; i < numDataTransferPoint; i++) { |
12220 | |
12221 | bIndex = dataTransferDiscreteObj->tessGlobal[2*i ]; |
12222 | globalNodeID = dataTransferDiscreteObj->tessGlobal[2*i+1] + |
12223 | dataTransferDiscreteObj->bodys[bIndex-1].globalOffset; |
12224 | |
12225 | feaLoad->gridIDSet[feaLoad->numGridID+i] = globalNodeID; |
12226 | feaLoad->temperatureMultiDistribute[feaLoad->numGridID+i] = dataTransferData[i]; |
12227 | } |
12228 | |
12229 | feaLoad->numGridID += numDataTransferPoint; |
12230 | |
12231 | } // End data transfer name loop |
12232 | |
12233 | status = CAPS_SUCCESS0; |
12234 | |
12235 | cleanup: |
12236 | |
12237 | AIM_FREE(transferName){ EG_free(transferName); transferName = ((void*)0); }; |
12238 | |
12239 | return status; |
12240 | } |
12241 | |
12242 | // Retrieve aerodynamic reference quantities from bodies |
12243 | int fea_retrieveAeroRef(int numBody, ego *bodies, feaAeroRefStruct *feaAeroRef) { |
12244 | |
12245 | int status; // Function return status |
12246 | int body; |
12247 | |
12248 | // EGADS return values |
12249 | int atype, alen; |
12250 | const int *ints; |
12251 | const char *string; |
12252 | const double *reals; |
12253 | |
12254 | // Get reference quantities from the bodies |
12255 | for (body = 0; body < numBody; body++) { |
12256 | |
12257 | status = EG_attributeRet(bodies[body], "capsReferenceArea", &atype, &alen, &ints, &reals, &string); |
12258 | if (status == EGADS_SUCCESS0 && atype == Double) { |
12259 | |
12260 | feaAeroRef->refArea = (double) reals[0]; |
12261 | } |
12262 | |
12263 | status = EG_attributeRet(bodies[body], "capsReferenceChord", &atype, &alen, &ints, &reals, &string); |
12264 | if (status == EGADS_SUCCESS0 && atype == Double){ |
12265 | |
12266 | feaAeroRef->refChord = (double) reals[0]; |
12267 | } |
12268 | |
12269 | status = EG_attributeRet(bodies[body], "capsReferenceSpan", &atype, &alen, &ints, &reals, &string); |
12270 | if (status == EGADS_SUCCESS0 && atype == Double) { |
12271 | |
12272 | feaAeroRef->refSpan = (double) reals[0]; |
12273 | } |
12274 | |
12275 | /* |
12276 | status = EG_attributeRet(bodies[body], "capsReferenceX", &atype, &alen, &ints, &reals, &string); |
12277 | if (status == EGADS_SUCCESS && atype == Double) { |
12278 | XX = (double) reals[0]; |
12279 | } |
12280 | |
12281 | status = EG_attributeRet(bodies[body], "capsReferenceY", &atype, &alen, &ints, &reals, &string); |
12282 | if (status == EGADS_SUCCESS && atype == Double) { |
12283 | XX = (double) reals[0]; |
12284 | } |
12285 | |
12286 | status = EG_attributeRet(bodies[body], "capsReferenceZ", &atype, &alen, &ints, &reals, &string); |
12287 | if (status == EGADS_SUCCESS && atype == Double) { |
12288 | XX = (double) reals[0]; |
12289 | } |
12290 | */ |
12291 | } |
12292 | |
12293 | return CAPS_SUCCESS0; |
12294 | } |
12295 | |
12296 | |
12297 | // Assign element "subtypes" based on properties set |
12298 | int fea_assignElementSubType(int numProperty, feaPropertyStruct *feaProperty, meshStruct *feaMesh) |
12299 | { |
12300 | int propertyIndex, i ; |
12301 | |
12302 | feaMeshDataStruct *feaData; |
12303 | |
12304 | if (numProperty > 0 && feaProperty == NULL((void*)0)) return CAPS_NULLVALUE-307; |
12305 | if (feaMesh == NULL((void*)0)) return CAPS_NULLVALUE-307; |
12306 | |
12307 | printf("Updating mesh element types based on properties input\n"); |
12308 | |
12309 | for (propertyIndex = 0; propertyIndex < numProperty; propertyIndex++ ) { |
12310 | |
12311 | // Types that don't need subtypes - setting this correctly requires knowledge of what mesh_writeNastran |
12312 | // writes by default for each mesh element type |
12313 | if (feaProperty[propertyIndex].propertyType == Rod || |
12314 | //feaProperty[propertyIndex].propertyType == Shell || |
12315 | //feaProperty[propertyIndex].propertyType == Composite || |
12316 | feaProperty[propertyIndex].propertyType == Solid) continue; |
12317 | |
12318 | for (i = 0; i < feaMesh->numElement; i++) { |
12319 | |
12320 | // What if this is a volume mesh we inherited ? |
12321 | if (feaMesh->element[i].analysisType != MeshStructure) { |
12322 | printf("Developer error: Analysis type not set to MeshStructure for element %d\n", feaMesh->element[i].elementID); |
12323 | return CAPS_BADVALUE-311; |
12324 | } |
12325 | |
12326 | // Matching proptery id |
12327 | if (feaMesh->element[i].analysisData != NULL((void*)0)) { |
12328 | feaData = (feaMeshDataStruct *) feaMesh->element[i].analysisData; |
12329 | |
12330 | if (feaData->propertyID != feaProperty[propertyIndex].propertyID) continue; |
12331 | |
12332 | } else { |
12333 | printf("Developer error: No 'feaData' set on element %d\n", feaMesh->element[i].elementID); |
12334 | return CAPS_BADVALUE-311; |
12335 | |
12336 | } |
12337 | |
12338 | // if (feaMesh->element[i].markerID != feaProperty[propertyIndex].propertyID) continue; |
12339 | // |
12340 | // feaData = (feaMeshDataStruct *) feaMesh->element[i].analysisData; |
12341 | // if (feaData->propertyID != feaProperty[propertyIndex].propertyID) { |
12342 | // printf("Developer error: Property ID mismatch between element \"markerID\" (%d) and feaData \"propertyID\" (%d) for element %d\n", |
12343 | // feaData->propertyID, feaProperty[propertyIndex].propertyID, feaMesh->element[i].elementID); |
12344 | // return CAPS_BADVALUE; |
12345 | // } |
12346 | |
12347 | |
12348 | if (feaProperty[propertyIndex].propertyType == ConcentratedMass && |
12349 | feaMesh->element[i].elementType == Node) { |
12350 | |
12351 | feaData->elementSubType = ConcentratedMassElement; |
12352 | } |
12353 | |
12354 | if (feaProperty[propertyIndex].propertyType == Bar && |
12355 | feaMesh->element[i].elementType == Line) { |
12356 | |
12357 | feaData->elementSubType = BarElement; |
12358 | } |
12359 | |
12360 | if (feaProperty[propertyIndex].propertyType == Beam && |
12361 | feaMesh->element[i].elementType == Line) { |
12362 | |
12363 | feaData->elementSubType = BeamElement; |
12364 | } |
12365 | |
12366 | if (feaProperty[propertyIndex].propertyType == Shear && |
12367 | feaMesh->element[i].elementType == Quadrilateral){ |
12368 | |
12369 | feaData->elementSubType = ShearElement; |
12370 | } |
12371 | |
12372 | if (feaProperty[propertyIndex].propertyType == Membrane && |
12373 | feaMesh->element[i].elementType == Quadrilateral){ |
12374 | |
12375 | feaData->elementSubType = MembraneElement; |
12376 | } |
12377 | |
12378 | // Only need to set these if the zOffset is needed based on mesh_writeNASTRAN |
12379 | if ( ( feaProperty[propertyIndex].propertyType == Shell || feaProperty[propertyIndex].propertyType == Composite ) && |
12380 | feaProperty[propertyIndex].zOffsetRel != 0.0 && |
12381 | ( feaMesh->element[i].elementType == Quadrilateral || |
12382 | feaMesh->element[i].elementType == Triangle || |
12383 | feaMesh->element[i].elementType == Triangle_6 || |
12384 | feaMesh->element[i].elementType == Quadrilateral_8)) { |
12385 | |
12386 | feaData->elementSubType = ShellElement; |
12387 | } |
12388 | } |
12389 | } |
12390 | |
12391 | return CAPS_SUCCESS0; |
12392 | } |
12393 | |
12394 | // Create connections for gluing - Connections are appended |
12395 | int fea_glueMesh(meshStruct *mesh, |
12396 | int connectionID, |
12397 | /*@unused@*/ int connectionType, |
12398 | int dofDependent, |
12399 | char *slaveName, |
12400 | int numMasterName, |
12401 | char *masterName[], |
12402 | mapAttrToIndexStruct *attrMap, |
12403 | int maxNumMaster, |
12404 | double searchRadius, |
12405 | int *numConnect, |
12406 | feaConnectionStruct *feaConnect[]) { |
12407 | |
12408 | // Input parameters |
12409 | //double exactTol=1E-9; |
12410 | //int weigthing = 1; // 1=linear |
12411 | |
12412 | int masterWeight = 1; |
12413 | int masterComponent = 123; |
12414 | |
12415 | int status; |
12416 | int i, masterIndex, slaveIndex, distIndex, attrIndex; |
12417 | |
12418 | int numMaster; |
12419 | |
12420 | int *glueConn=NULL((void*)0); |
12421 | double *glueDist=NULL((void*)0); |
12422 | |
12423 | double dist, maxDist; |
12424 | |
12425 | feaMeshDataStruct *feaData, *feaDataMaster; |
12426 | |
12427 | // int numConnect; |
12428 | // feaConnectionStruct *feaConnect; |
12429 | |
12430 | |
12431 | // maps from nodeID to mesh->node index |
12432 | // mesh_nodeID2Array(nasMesh, &n2a); |
12433 | |
12434 | printf("\tCreating glue connections\n"); |
12435 | |
12436 | if (searchRadius <=0) { |
12437 | printf("\tSearch radius must be greater than 0 when gluing, current value = %g\n", searchRadius); |
12438 | status = CAPS_BADVALUE-311; |
12439 | goto cleanup; |
12440 | } |
12441 | |
12442 | status = array_allocIntegerVector(maxNumMaster, -1, &glueConn); |
12443 | if (status != CAPS_SUCCESS0) goto cleanup; |
12444 | |
12445 | status = array_allocDoubleVector(maxNumMaster, 1E9, &glueDist); |
12446 | if (status != CAPS_SUCCESS0) goto cleanup; |
12447 | |
12448 | for (slaveIndex = 0; slaveIndex < mesh->numNode; slaveIndex++) { |
12449 | |
12450 | feaData = (feaMeshDataStruct *) mesh->node[slaveIndex].analysisData; |
12451 | |
12452 | status = get_mapAttrToIndexIndex(attrMap, (const char *) slaveName, &attrIndex); |
12453 | if (status == CAPS_NOTFOUND-303) { |
12454 | printf("\tName %s not found in attribute map of capsConnect!!!!\n", slaveName); |
12455 | continue; |
12456 | } else if (status != CAPS_SUCCESS0) return status; |
12457 | |
12458 | if (feaData->connectIndex != attrIndex) continue; |
12459 | |
12460 | // We have a slave at this point |
12461 | |
12462 | // printf("Slave - node ID %d\n", mesh->node[slaveIndex].nodeID); |
12463 | |
12464 | status = array_setDoubleVectorValue(maxNumMaster, 1E9, &glueDist); |
12465 | if (status != CAPS_SUCCESS0) goto cleanup; |
12466 | |
12467 | status = array_setIntegerVectorValue(maxNumMaster, -1, &glueConn); |
12468 | if (status != CAPS_SUCCESS0) goto cleanup; |
12469 | |
12470 | for (masterIndex = 0; masterIndex < mesh->numNode; masterIndex++) { |
12471 | |
12472 | if (slaveIndex == masterIndex) continue; |
12473 | |
12474 | feaDataMaster = (feaMeshDataStruct *) mesh->node[masterIndex].analysisData; |
12475 | |
12476 | for (i = 0; i < numMasterName; i++) { |
12477 | status = get_mapAttrToIndexIndex(attrMap, (const char *) masterName[i], &attrIndex); |
12478 | if (status == CAPS_NOTFOUND-303) { |
12479 | printf("\tName %s not found in attribute map of capsConnect!!!!\n", masterName[i]); |
12480 | continue; |
12481 | } else if (status != CAPS_SUCCESS0) return status; |
12482 | |
12483 | if (feaDataMaster->connectIndex != attrIndex) continue; |
12484 | |
12485 | break; |
12486 | } |
12487 | |
12488 | if (i >= numMasterName) continue; |
12489 | |
12490 | // We have a potential master at this point |
12491 | |
12492 | dist = dist_DoubleVal(mesh->node[masterIndex].xyz, mesh->node[slaveIndex].xyz); |
12493 | |
12494 | //printf("dist = %f (radius = %f), masterIndex %d\n", dist, searchRadius, masterIndex); |
12495 | |
12496 | if ( dist > searchRadius) continue; |
12497 | |
12498 | status = array_maxDoubleValue(maxNumMaster, glueDist, &distIndex, &maxDist); |
12499 | if (status != CAPS_SUCCESS0) goto cleanup; |
12500 | |
12501 | //printf("dist = %f, maxdist = %e (index = %d)\n", dist, maxDist, distIndex); |
12502 | |
12503 | if (dist < maxDist) { |
12504 | glueDist[distIndex] = dist; |
12505 | glueConn[distIndex] = masterIndex; |
12506 | } |
12507 | } // End of master loop |
12508 | |
12509 | // How many masters were found |
12510 | numMaster = 0; |
12511 | for (i = 0; i < maxNumMaster; i++) { |
12512 | if (glueDist[i] > searchRadius) continue; // Nothing was every set |
12513 | numMaster += 1; |
12514 | } |
12515 | |
12516 | if (numMaster <= 0) { |
12517 | printf("\tWarning: no masters were found for slave node (id = %d, slave name = %s)!\n", mesh->node[slaveIndex].nodeID, slaveName); |
12518 | } else { |
12519 | // Create and set connections |
12520 | status = fea_setConnection(slaveName, |
12521 | RigidBodyInterpolate, |
12522 | connectionID, |
12523 | mesh->numElement, |
12524 | dofDependent, |
12525 | 0.0, |
12526 | 0.0, |
12527 | 0.0, |
12528 | 0, |
12529 | 0, |
12530 | mesh->node[slaveIndex].nodeID, |
12531 | masterWeight, |
12532 | masterComponent, |
12533 | numMaster, glueConn, |
12534 | numConnect,feaConnect); |
12535 | if (status != CAPS_SUCCESS0) goto cleanup; |
12536 | } |
12537 | // |
12538 | // *numConnect += 1; |
12539 | // |
12540 | // (*feaConnect) = (feaConnectionStruct *) EG_reall((*feaConnect),*numConnect*sizeof(feaConnectionStruct)); |
12541 | // if ((*feaConnect) == NULL) { |
12542 | // *numConnect = 0; |
12543 | // status = EGADS_MALLOC; |
12544 | // goto cleanup; |
12545 | // } |
12546 | // |
12547 | // status = initiate_feaConnectionStruct(&(*feaConnect)[*numConnect-1]); |
12548 | // if (status != CAPS_SUCCESS) goto cleanup; |
12549 | // |
12550 | // (*feaConnect)[*numConnect-1].name = (char *) EG_alloc((strlen(slaveName) + 1)*sizeof(char)); |
12551 | // if ((*feaConnect)[*numConnect-1].name == NULL) { |
12552 | // status = EGADS_MALLOC; |
12553 | // goto cleanup; |
12554 | // } |
12555 | // |
12556 | // memcpy((*feaConnect)[*numConnect-1].name, slaveName, strlen(slaveName)*sizeof(char)); |
12557 | // (*feaConnect)[*numConnect-1].name[strlen(slaveName)] = '\0'; |
12558 | // |
12559 | // (*feaConnect)[*numConnect-1].connectionID = connectionID; // ConnectionTuple index |
12560 | // (*feaConnect)[*numConnect-1].connectionType = connectionType; |
12561 | // |
12562 | // (*feaConnect)[*numConnect-1].elementID = *numConnect + mesh->numElement; |
12563 | // |
12564 | // (*feaConnect)[*numConnect-1].dofDependent = dofDependent; |
12565 | // |
12566 | // (*feaConnect)[*numConnect-1].connectivity[1] = mesh->node[slaveIndex].nodeID; // Dependent |
12567 | // (*feaConnect)[*numConnect-1].numMaster = numMaster; // Independent |
12568 | // |
12569 | // (*feaConnect)[*numConnect-1].masterIDSet = (int *) EG_alloc(numMaster*sizeof(int)); // [numMaster] |
12570 | // if ((*feaConnect)[*numConnect-1].masterIDSet == NULL) { |
12571 | // status = EGADS_MALLOC; |
12572 | // goto cleanup; |
12573 | // } |
12574 | // (*feaConnect)[*numConnect-1].masterWeighting = (double *) EG_alloc(numMaster*sizeof(double));; // [numMaster] |
12575 | // if ((*feaConnect)[*numConnect-1].masterWeighting == NULL) { |
12576 | // status = EGADS_MALLOC; |
12577 | // goto cleanup; |
12578 | // } |
12579 | // |
12580 | // (*feaConnect)[*numConnect-1].masterComponent =(int *) EG_alloc(numMaster*sizeof(int));; // [numMaster] |
12581 | // if ((*feaConnect)[*numConnect-1].masterComponent == NULL) { |
12582 | // status = EGADS_MALLOC; |
12583 | // goto cleanup; |
12584 | // } |
12585 | // |
12586 | // printf("\tMasters (%d)", numMaster); |
12587 | // |
12588 | // // Master values; |
12589 | // numMaster = 0; |
12590 | // for (i = 0; i < maxNumMaster; i++) { |
12591 | // if (glueDist[i] > searchRadius) continue; // Nothing was every set |
12592 | // printf(" %d(%d)", mesh->node[glueConn[i]].nodeID, glueConn[i]); |
12593 | // (*feaConnect)[*numConnect-1].masterIDSet[numMaster] = mesh->node[glueConn[i]].nodeID; |
12594 | // (*feaConnect)[*numConnect-1].masterWeighting[numMaster] = masterWeight; |
12595 | // (*feaConnect)[*numConnect-1].masterComponent[numMaster] = masterComponent; |
12596 | // numMaster += 1; |
12597 | // } |
12598 | // printf("\n"); |
12599 | |
12600 | } // End of slave loop |
12601 | |
12602 | cleanup: |
12603 | if (status != CAPS_SUCCESS0) printf("\tPremature exit in fea_glueMesh, status = %d\n", status); |
12604 | |
12605 | if (glueDist != NULL((void*)0)) EG_free(glueDist); |
12606 | if (glueConn != NULL((void*)0)) EG_free(glueConn); |
12607 | |
12608 | return status; |
12609 | } |
12610 | |
12611 | //int fea_glueMesh2(meshStruct *meshIn, |
12612 | // |
12613 | // mapAttrToIndexStruct *attrMap) { |
12614 | // |
12615 | // // Input parameters |
12616 | // int numGlue=5; |
12617 | // double exactTol=1E-9; |
12618 | // double radiusOfInfluence = 0.1;//1E-3; |
12619 | // int weigthing = 1; // 1=linear |
12620 | // |
12621 | // int status; |
12622 | // int i, j, k, m, masterIndex, slaveIndex, distIndex; |
12623 | // int found; |
12624 | // |
12625 | // int numMesh; |
12626 | // meshStruct *mesh, *master, *slave, *search; |
12627 | // |
12628 | // int **glueConn=NULL; |
12629 | // double **glueDist=NULL; |
12630 | // |
12631 | // double *tempDist=NULL; |
12632 | // int *tempGlue=NULL; |
12633 | // int numNode = 0; |
12634 | // int *meshIndexStart=NULL; |
12635 | // |
12636 | // double dist, maxDist; |
12637 | // |
12638 | // feaMeshDataStruct *feaData; |
12639 | // |
12640 | //// maps from nodeID to mesh->node index |
12641 | //// mesh_nodeID2Array(nasMesh, &n2a); |
12642 | // |
12643 | // printf("Welcome to glueing!\n"); |
12644 | // numMesh = meshIn->numReferenceMesh; |
12645 | // mesh = meshIn->referenceMesh; |
12646 | // |
12647 | // printf("Start with allocation!\n"); |
12648 | // status = array_allocIntegerVector(numMesh, 0, &meshIndexStart); |
12649 | // if (status != CAPS_SUCCESS) goto cleanup; |
12650 | // |
12651 | // // Determine number of nodes in reference meshes - Remember capsIgnore may have already been applied |
12652 | // for (i=0; i < numMesh; i++) { |
12653 | // meshIndexStart[i] = numNode; |
12654 | // numNode += mesh[i].numNode; |
12655 | // } |
12656 | // |
12657 | // if (numNode != meshIn->numNode) { |
12658 | // printf("Inconsistent number of nodes determined!"); |
12659 | // status = CAPS_MISMATCH; |
12660 | // goto cleanup; |
12661 | // } |
12662 | // |
12663 | // // glueConn structure: |
12664 | // // glueConn[row][col] where [row] is node index and |
12665 | // // [row][0] : 1=master, 0=slave, -1=unused |
12666 | // // [row][1:numGlue+1] : nearest node indices, -1=unused |
12667 | // status = array_allocIntegerMatrix(numNode, numGlue+1, -1, &glueConn); |
12668 | // if (status != CAPS_SUCCESS) goto cleanup; |
12669 | // |
12670 | // // glueDist structure: |
12671 | // // glueDist[row][col] where [row] is node index and |
12672 | // // [row][0:numGlue] : distance to nearest node indices found in glueConn[row][1:numGlue+1] |
12673 | // status = array_allocDoubleMatrix(numNode, numGlue, -1, &glueDist); |
12674 | // if (status != CAPS_SUCCESS) goto cleanup; |
12675 | // |
12676 | // status = array_allocIntegerVector(numGlue, 0, &tempGlue); |
12677 | // if (status != CAPS_SUCCESS) goto cleanup; |
12678 | // |
12679 | // status = array_allocDoubleVector(numGlue, 0, &tempDist); |
12680 | // if (status != CAPS_SUCCESS) goto cleanup; |
12681 | // |
12682 | // printf("Done with allocation!\n"); |
12683 | // |
12684 | // // Lets mark all slaves |
12685 | // // |
12686 | // |
12687 | // int attrIndex; |
12688 | // int numSlave=1; |
12689 | // char slaveName[] = "slave"; |
12690 | // int numMasterName; |
12691 | // char **masterName; |
12692 | // |
12693 | // for (i = 0; i < numNode; i++) { |
12694 | // |
12695 | // feaData = (feaMeshDataStruct *) meshIn->node[i].analysisData; |
12696 | // |
12697 | // for (j = 0; j < numSlave; j++) { |
12698 | // status = get_mapAttrToIndexIndex(attrMap, (const char *) slaveName, &attrIndex); |
12699 | // if (status == CAPS_NOTFOUND) { |
12700 | // printf("\tName %s not found in attribute map of capsConnect!!!!\n", slaveName); |
12701 | // continue; |
12702 | // } else if (status != CAPS_SUCCESS) return status; |
12703 | // |
12704 | // |
12705 | // if (feaData->connectIndex != attrIndex) continue; |
12706 | // |
12707 | // glueConn[i][0] = 0; |
12708 | // break; |
12709 | // } |
12710 | // |
12711 | // if (glueConn[i][0] != 0) continue; |
12712 | // |
12713 | // status = string_toStringDynamicArray('["master"]', &numMasterName, &masterName); |
12714 | // if (status != CAPS_SUCCESS); goto cleanup; |
12715 | // |
12716 | // for (k = 0; k < numNode; k++) { |
12717 | // |
12718 | // if (i == k) continue; |
12719 | // for (m = 0; m < numMasterName; m++) { |
12720 | // |
12721 | // } |
12722 | // } |
12723 | // |
12724 | // |
12725 | // (void) string_freeArray(numMasterName, &masterName); |
12726 | // masterName = NULL; |
12727 | // numMasterName = 0; |
12728 | // } |
12729 | // |
12730 | // |
12731 | // // for (i = 0; i < numMesh; i++) { // THIS IS MOSTLY correct - error in master slave relation of RBE3 elements |
12732 | //// master = &mesh[i]; |
12733 | //// |
12734 | ////// printf("Master Mesh %d (of %d)\n", i, numMesh); |
12735 | //// //Exhaustive search |
12736 | //// for (masterIndex = 0; masterIndex < master->numNode; masterIndex++) { |
12737 | //// |
12738 | ////// printf("master index %d (of %d)\n", masterIndex, master->numNode); |
12739 | //// // Slaves may be promoted to masters, but cannot be slaves to multiple masters |
12740 | //// //if (glueConn[masterIndex+meshIndexStart[masterIndex]][0] != 0) continue; |
12741 | //// |
12742 | //// status = array_setDoubleVectorValue(numGlue, 1E9, &tempDist); |
12743 | //// if (status != CAPS_SUCCESS) goto cleanup; |
12744 | //// |
12745 | //// status = array_setIntegerVectorValue(numGlue, -1, &tempGlue); |
12746 | //// if (status != CAPS_SUCCESS) goto cleanup; |
12747 | //// |
12748 | //// for (j = 0; j < numMesh; j++) { |
12749 | //// |
12750 | //// if (i == j) continue; |
12751 | //// |
12752 | //// slave = &mesh[j]; |
12753 | //// |
12754 | //// for (slaveIndex = 0; slaveIndex < slave->numNode; slaveIndex++) { |
12755 | //// |
12756 | //// // Slaves cannot have multiple masters - FALSE |
12757 | //// if (glueConn[slaveIndex+meshIndexStart[j]][0] == 0) continue; |
12758 | //// |
12759 | //// // Make sure master slave relation doesn't already exist |
12760 | //// found = (int) false; |
12761 | //// for (k =1; k < numGlue+1; k++) { |
12762 | //// if (masterIndex+meshIndexStart[i] == glueConn[slaveIndex+meshIndexStart[j]][k]){ |
12763 | //// found = (int) true; |
12764 | //// break; |
12765 | //// } |
12766 | //// } |
12767 | //// |
12768 | //// if (found == (int) true) continue; |
12769 | //// |
12770 | ////// printf("glueConn %d\n", glueConn[slaveIndex+meshIndexStart[j]][0]); |
12771 | //// |
12772 | //// dist = dist_DoubleVal(master->node[masterIndex].xyz, slave->node[slaveIndex].xyz); |
12773 | //// |
12774 | ////// printf("dist = %f (radius = %f)\n", dist, radiusOfInfluence); |
12775 | //// |
12776 | //// if ( dist > radiusOfInfluence) continue; |
12777 | //// |
12778 | //// status = array_maxDoubleValue(numGlue, tempDist, &distIndex, &maxDist); |
12779 | //// if (status != CAPS_SUCCESS) goto cleanup; |
12780 | //// |
12781 | //// //printf("dist = %f, maxdist = %e (index = %d)\n", dist, maxDist, distIndex); |
12782 | //// |
12783 | //// if (dist < maxDist) { |
12784 | //// tempDist[distIndex] = dist; |
12785 | //// tempGlue[distIndex] = slaveIndex + meshIndexStart[j] ; |
12786 | //// } |
12787 | //// } |
12788 | //// } |
12789 | //// |
12790 | //// if (tempDist[0] > radiusOfInfluence) continue; // Nothing was every set |
12791 | //// |
12792 | //// // glueConn structure: |
12793 | //// // glueConn[row][col] where [row] is node index and |
12794 | //// // [row][0] : 1=master, 0=slave, -1=unused |
12795 | //// // [row][1:numGlue+1] : nearest node indices, -1=unused |
12796 | //// |
12797 | //// // glueDist[row][col] where [row] is node index and |
12798 | //// // [row][0:numGlue] : distance to nearest node indices found in glueConn[row][1:numGlue+1] |
12799 | //// |
12800 | //// glueConn[masterIndex+meshIndexStart[i]][0] = 1; //Mark as Master |
12801 | //// distIndex = 0; |
12802 | //// for (j = 0; j < numGlue; j++) { |
12803 | //// if (tempDist[j] > radiusOfInfluence) continue; // Nothing was every set |
12804 | //// |
12805 | //// glueDist[masterIndex+meshIndexStart[i]][distIndex] = tempDist[j]; // Distances for a master |
12806 | //// glueConn[masterIndex+meshIndexStart[i]][distIndex+1] = tempGlue[j]; // Glue connections/slaves for a master |
12807 | //// |
12808 | //// // Mark the masters slave's as slaves - A slave can become a master to another slave, |
12809 | //// // but it can not be a slave to another master |
12810 | //// if (glueConn[tempGlue[j]][0] < 0) glueConn[tempGlue[j]][0] = 0; |
12811 | //// |
12812 | //// distIndex +=1; |
12813 | //// } |
12814 | //// |
12815 | //// printf("Set %d : %d: ",masterIndex+meshIndexStart[i], glueConn[masterIndex+meshIndexStart[i]][0]); |
12816 | //// for(j = 0; j < numGlue; j++) { |
12817 | //// printf("%d ", glueConn[masterIndex+meshIndexStart[i]][j+1]); |
12818 | //// } |
12819 | //// printf("\n"); |
12820 | //// } |
12821 | //// } |
12822 | //// |
12823 | //// for (i = 0; i < numNode;i++) { |
12824 | //// if (glueConn[i][0] < 0) continue; |
12825 | //// printf("Node %d : %d : ", i, glueConn[i][0]); |
12826 | //// for(j = 0; j < numGlue; j++) { |
12827 | ////// printf("%d (%.2f)", glueConn[i][j+1], glueDist[i][j]); |
12828 | //// printf("%d ", glueConn[i][j+1]); |
12829 | //// } |
12830 | //// printf("\n"); |
12831 | //// } |
12832 | //// // Finished getting all my glue |
12833 | // |
12834 | // cleanup: |
12835 | // if (status != CAPS_SUCCESS) printf("\tPremature exit in fea_glueMesh, status = %d\n", status); |
12836 | // |
12837 | // if (tempDist != NULL) EG_free(tempDist); |
12838 | // if (tempGlue != NULL) EG_free(tempGlue); |
12839 | // if (meshIndexStart != NULL) EG_free(meshIndexStart); |
12840 | // |
12841 | // if (glueConn != NULL) (void) array_freeIntegerMatrix(numNode, numGlue, &glueConn); |
12842 | // |
12843 | // if (glueDist != NULL) (void) array_freeDoubleMatrix(numNode, numGlue, &glueDist); |
12844 | // |
12845 | // (void) string_freeArray(numMasterName, &masterName); |
12846 | // masterName = NULL; |
12847 | // |
12848 | // return status; |
12849 | //} |
12850 | |
12851 | // Create a default analysis structure based on previous inputs |
12852 | int fea_createDefaultAnalysis(feaProblemStruct *feaProblem, const char *analysisType) { |
12853 | |
12854 | int status; |
12855 | int i; |
12856 | |
12857 | capsTuple *tupleVal; |
12858 | |
12859 | char *json=NULL((void*)0); |
12860 | int maxSize=2048; |
12861 | |
12862 | if (feaProblem == NULL((void*)0)) return CAPS_NULLVALUE-307; |
12863 | |
12864 | if (feaProblem->numAnalysis != 0 || feaProblem->feaAnalysis != NULL((void*)0)) { |
12865 | // Destroy our analysis structures coming in if aren't 0 and NULL already |
12866 | for (i = 0; i < feaProblem->numAnalysis; i++) { |
12867 | status = destroy_feaAnalysisStruct(&feaProblem->feaAnalysis[i]); |
12868 | if (status != CAPS_SUCCESS0) return status; |
12869 | } |
12870 | |
12871 | if (feaProblem->feaAnalysis != NULL((void*)0)) EG_free(feaProblem->feaAnalysis); |
12872 | feaProblem->feaAnalysis = NULL((void*)0); |
12873 | feaProblem->numAnalysis = 0; |
12874 | } |
12875 | |
12876 | tupleVal = (capsTuple *) EG_alloc(1*sizeof(capsTuple)); |
12877 | if (tupleVal == NULL((void*)0)) { |
12878 | status = EGADS_MALLOC-4; |
12879 | goto cleanup; |
12880 | } |
12881 | tupleVal[0].name = NULL((void*)0); |
12882 | tupleVal[0].value = NULL((void*)0); |
12883 | |
12884 | json = (char *) EG_alloc(maxSize*sizeof(char)); |
12885 | if (json == NULL((void*)0)) { |
12886 | status = EGADS_MALLOC-4; |
12887 | goto cleanup; |
12888 | } |
12889 | |
12890 | strcpy(json,"{\"analysisType\":\""); |
12891 | if (strcasecmp(analysisType, "Optimization") == 0) strcat(json,"Static"); |
12892 | else strcat(json, analysisType); |
12893 | strcat(json,"\""); |
12894 | |
12895 | if (feaProblem->numLoad != 0) { |
12896 | strcat(json,",\"analysisLoad\":["); |
12897 | for (i = 0; i < feaProblem->numLoad; i++) { |
12898 | if (i != 0) strcat(json,","); |
12899 | strcat(json,"\""); |
12900 | strcat(json,feaProblem->feaLoad[i].name); |
12901 | strcat(json,"\""); |
12902 | } |
12903 | strcat(json, "]"); |
12904 | } |
12905 | |
12906 | if (feaProblem->numConstraint != 0) { |
12907 | strcat(json,",\"analysisConstraint\":["); |
12908 | for (i = 0; i < feaProblem->numConstraint; i++) { |
12909 | if (i != 0) strcat(json,","); |
12910 | strcat(json,"\""); |
12911 | strcat(json,feaProblem->feaConstraint[i].name); |
12912 | strcat(json,"\""); |
12913 | } |
12914 | strcat(json, "]"); |
12915 | } |
12916 | |
12917 | if (feaProblem->numSupport != 0) { |
12918 | strcat(json,",\"analysisSupport\":["); |
12919 | for (i = 0; i < feaProblem->numSupport; i++) { |
12920 | if (i != 0) strcat(json,","); |
12921 | strcat(json,"\""); |
12922 | strcat(json,feaProblem->feaSupport[i].name); |
12923 | strcat(json,"\""); |
12924 | } |
12925 | strcat(json, "]"); |
12926 | } |
12927 | |
12928 | if (feaProblem->numDesignConstraint != 0) { |
12929 | strcat(json,",\"analysisDesignConstraint\":["); |
12930 | for (i = 0; i < feaProblem->numDesignConstraint; i++) { |
12931 | if (i != 0) strcat(json,","); |
12932 | strcat(json,"\""); |
12933 | strcat(json,feaProblem->feaDesignConstraint[i].name); |
12934 | strcat(json,"\""); |
12935 | } |
12936 | strcat(json, "]"); |
12937 | } |
12938 | |
12939 | strcat(json,"}"); |
12940 | |
12941 | tupleVal[0].name = EG_strdup("Default"); |
12942 | tupleVal[0].value = json; |
12943 | |
12944 | //printf("Default analysis tuple - %s\n", tupleVal[0].value); |
12945 | |
12946 | status = fea_getAnalysis(1, |
12947 | tupleVal, |
12948 | feaProblem); |
12949 | if (status != CAPS_SUCCESS0) goto cleanup; |
12950 | |
12951 | // feaProblem->numAnalysis = 1; |
12952 | // feaProblem->feaAnalysis = (feaAnalysisStruct *) EG_alloc(feaProblem->numAnalysis*sizeof(feaAnalysisStruct)); |
12953 | // if (feaProblem->feaAnalysis == NULL) return EGADS_MALLOC; |
12954 | // |
12955 | // feaAnalysis=&feaProblem->feaAnalysis[0]; |
12956 | // status = initiate_feaAnalysisStruct(feaAnalysis); |
12957 | // if (status != CAPS_SUCCESS) return status; |
12958 | // |
12959 | // |
12960 | // feaAnalysis->name = (char *) EG_alloc(((strlen(name)) + 1)*sizeof(char)); |
12961 | // if (feaProblem->feaAnalysis->name == NULL) return EGADS_MALLOC; |
12962 | // |
12963 | // memcpy(feaAnalysis->name, name, strlen(name)*sizeof(char)); |
12964 | // feaAnalysis->name[strlen(name)] = '\0'; |
12965 | // |
12966 | // feaAnalysis->analysisID = 1; |
12967 | |
12968 | |
12969 | status = CAPS_SUCCESS0; |
12970 | goto cleanup; |
12971 | |
12972 | cleanup: |
12973 | if (status != CAPS_SUCCESS0) printf("\tPremature exit in fea_createDefaultAnalysis, status = %d\n", status); |
12974 | |
12975 | if (tupleVal != NULL((void*)0)) { |
12976 | if (tupleVal[0].name != NULL((void*)0)) EG_free(tupleVal[0].name); |
12977 | if (tupleVal[0].value != NULL((void*)0)) EG_free(tupleVal[0].value); |
12978 | EG_free(tupleVal); |
12979 | } |
12980 | |
12981 | return status; |
12982 | } |
12983 | |
12984 | // Setup the default flutter velocities if not specified |
12985 | int fea_defaultFlutterVelocity(feaAnalysisStruct *feaAnalysis) { |
12986 | int i; |
12987 | |
12988 | int defaultNum = 23; |
12989 | double velocity=0, dv=1, vmin=0, vmax=0; |
12990 | |
12991 | if (feaAnalysis->numFlutterVel == 0) { |
12992 | AIM_FREE(feaAnalysis->flutterVel){ EG_free(feaAnalysis->flutterVel); feaAnalysis->flutterVel = ((void*)0); }; |
12993 | |
12994 | feaAnalysis->numFlutterVel = defaultNum; |
12995 | feaAnalysis->flutterVel = EG_alloc(feaAnalysis->numFlutterVel*sizeof(double)); |
12996 | if (feaAnalysis->flutterVel == NULL((void*)0)) { |
12997 | return EGADS_MALLOC-4; |
12998 | } |
12999 | |
13000 | velocity = sqrt(2*feaAnalysis->dynamicPressure/feaAnalysis->density); |
13001 | vmin = velocity / 2.0; |
13002 | vmax = 2 * velocity; |
13003 | dv = (vmax - vmin) / (double) (feaAnalysis->numFlutterVel-3); |
13004 | |
13005 | for (i = 0; i < feaAnalysis->numFlutterVel-2; i++) { |
13006 | feaAnalysis->flutterVel[i+1] = vmin + (double) i * dv; |
13007 | } |
13008 | |
13009 | feaAnalysis->flutterVel[0] = velocity/10; |
13010 | feaAnalysis->flutterVel[feaAnalysis->numFlutterVel-1] = velocity*10; |
13011 | } |
13012 | |
13013 | return CAPS_SUCCESS0; |
13014 | } |