clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name capsValue.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -D REVISION=7.6 -I ../include -I /home/jenkins/workspace/ESP_Stanalizer/LINUX64/CAPS/scan-build/ESP/LINUX64/include -I . -I /usr/include/udunits2 -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-dangling-else -Wno-parentheses -Wno-unused-result -Wno-format-truncation -fdebug-compilation-dir /home/jenkins/workspace/ESP_Stanalizer/LINUX64/CAPS/scan-build/CAPS/src -ferror-limit 19 -fmessage-length 0 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/jenkins/workspace/ESP_Stanalizer/LINUX64/CAPS/scan-build/scanCAPS/2022-02-28-212352-64886-1 -x c capsValue.c
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | #include <stdio.h> |
13 | #include <stdlib.h> |
14 | #include <string.h> |
15 | #include <math.h> |
16 | |
17 | #ifdef WIN32 |
18 | #define getcwd _getcwd |
19 | #define PATH_MAX _MAX_PATH |
20 | #define snprintf _snprintf |
21 | #else |
22 | #include <unistd.h> |
23 | #include <limits.h> |
24 | #endif |
25 | |
26 | #include "udunits.h" |
27 | |
28 | #include "capsBase.h" |
29 | #include "capsAIM.h" |
30 | |
31 | |
32 | #include "common.h" |
33 | #include "OpenCSM.h" |
34 | |
35 | |
36 | |
37 | extern void ut_free( ut_unit* const unit); |
38 | |
39 | |
40 | extern |
41 | char *EG_strdup( const char *str); |
42 | |
43 | extern int caps_rename(const char *src, const char *dst); |
44 | extern int caps_writeValueObj(capsProblem *problem, capsObject *obj); |
45 | extern void caps_jrnlWrite(int funID, capsProblem *problem, capsObject *obj, |
46 | int status, int nargs, capsJrnl *args, CAPSLONG sNm0, |
47 | CAPSLONG sNum); |
48 | extern int caps_jrnlEnd(capsProblem *problem); |
49 | extern int caps_jrnlRead(int funID, capsProblem *problem, capsObject *obj, |
50 | int nargs, capsJrnl *args, CAPSLONG *sNum, int *stat); |
51 | |
52 | extern int caps_integrateData(const capsObject *vobject, enum capstMethod method, |
53 | int *rank, double **data, char **units); |
54 | extern int caps_getDataX(const capsObject *vobject, int *npts, int *rank, |
55 | const double **data, const char **units); |
56 | extern void caps_geomOutSensit(capsProblem *problem, int ipmtr, int irow, |
57 | int icol); |
58 | extern int caps_build(capsObject *pobject, int *nErr, capsErrs **errors); |
59 | extern void caps_concatErrs( capsErrs *errs, capsErrs **errors); |
60 | extern void caps_getAIMerrs(capsAnalysis *analy, int *nErr, capsErrs **errors); |
61 | extern int caps_analysisInfX(const capsObj aobject, char **apath, char **unSys, |
62 | int *major, int *minor, char **intents, |
63 | int *nField, char ***fnames, int **ranks, |
64 | int **fInOut, int *execution, int *status); |
65 | extern int caps_postAnalysiX(capsObject *aobject, int *nErr, capsErrs **errors, |
66 | int flag); |
67 | extern int caps_unitConvertible(const char *unit1, const char *unit2); |
68 | extern int caps_convert(int count, |
69 | const char *inUnit, double *inVal, |
70 | const char *outUnit, double *outVal); |
71 | extern int caps_unitParse( const char *unit); |
72 | extern int caps_execX(capsObject *aobject, int *nErr, capsErrs **errors); |
73 | extern int caps_circularAutoExecs(capsObject *asrc, |
74 | capsObject *aobject); |
75 | extern int caps_transferLinks(capsAnalysis *analysis, int *nErr, |
76 | capsErrs **errors); |
77 | |
78 | |
79 | int |
80 | caps_checkValueObj(capsObject *object) |
81 | { |
82 | const char *name = NULL; |
83 | capsValue *value; |
84 | |
85 | if (object == NULL) return CAPS_NULLOBJ; |
86 | if (object->magicnumber != CAPSMAGIC) return CAPS_BADOBJECT; |
87 | if (object->type != VALUE) return CAPS_BADTYPE; |
88 | if (object->blind == NULL) return CAPS_NULLBLIND; |
89 | value = (capsValue *) object->blind; |
90 | |
91 | |
92 | name = object->name; |
93 | if(name == NULL) { |
94 | printf(" CAPS Error: Value Object name is NULL\n"); |
95 | return CAPS_NULLNAME; |
96 | } |
97 | |
98 | |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 | |
107 | |
108 | if ((value->type == Pointer) || (value->type == PointerMesh)) { |
109 | |
110 | if ((value->type == Pointer) && (value->units == NULL)) { |
111 | printf(" CAPS Error: Value '%s' Pointer units is NULL!\n", object->name); |
112 | return CAPS_UNITERR; |
113 | } |
114 | } else { |
115 | if (value->units != NULL) { |
116 | |
117 | if (value->type == Boolean) { |
118 | printf(" CAPS Error: Value '%s' Integer cannot have units '%s'!\n", |
119 | object->name, value->units); |
120 | return CAPS_UNITERR; |
121 | } else if (value->type == Integer) { |
122 | printf(" CAPS Error: Value '%s' Boolean cannot have units '%s'!\n", |
123 | object->name, value->units); |
124 | return CAPS_UNITERR; |
125 | } else if (value->type == Tuple) { |
126 | printf(" CAPS Error: Value '%s' Tuple cannot have units '%s'!\n", |
127 | object->name, value->units); |
128 | return CAPS_UNITERR; |
129 | } |
130 | |
131 | if ((value->type == Double) || |
132 | (value->type == DoubleDeriv)) { |
133 | if (caps_unitParse(value->units) != CAPS_SUCCESS) { |
134 | printf(" CAPS Error: Value '%s' invalid units '%s'!\n", |
135 | object->name, value->units); |
136 | return CAPS_UNITERR; |
137 | } |
138 | } |
139 | } |
140 | } |
141 | |
142 | |
143 | value->length = value->ncol*value->nrow; |
144 | if (value->length <= 0 && value->nullVal != IsNull) { |
145 | printf(" CAPS Error: Value '%s' length <= 0 (nrow = %d, ncol = %d) and not IsNull!\n", |
146 | object->name, value->nrow, value->ncol); |
147 | return CAPS_SHAPEERR; |
148 | } |
149 | |
150 | |
151 | if (value->type == Integer) { |
152 | |
153 | if (value->dim > Scalar && value->length > 1) { |
154 | if (value->nullVal == NotAllowed && value->vals.integers == NULL) { |
155 | printf(" CAPS Error: Value '%s' integers is NULL (NotAllowed)!\n", |
156 | object->name); |
157 | return CAPS_NULLVALUE; |
158 | } |
159 | } |
160 | |
161 | } else if ((value->type == Double) || (value->type == DoubleDeriv)) { |
162 | |
163 | if (value->dim > Scalar && value->length > 1) { |
164 | if (value->nullVal == NotAllowed && value->vals.reals == NULL) { |
165 | printf(" CAPS Error: Value '%s' reals is NULL (NotAllowed)!\n", |
166 | object->name); |
167 | return CAPS_NULLVALUE; |
168 | } |
169 | } |
170 | |
171 | } else if (value->type == String) { |
172 | |
173 | if (value->nullVal == NotAllowed && value->vals.string == NULL) { |
174 | printf(" CAPS Error: Value '%s' string is NULL (NotAllowed)!\n", |
175 | object->name); |
176 | return CAPS_NULLVALUE; |
177 | } |
178 | if (value->nullVal != NotAllowed) |
179 | value->nullVal = (value->vals.string == NULL) ? IsNull : NotNull; |
180 | |
181 | } else if (value->type == Tuple) { |
182 | |
183 | if (value->nullVal == NotAllowed && value->vals.tuple == NULL) { |
184 | printf(" CAPS Error: Value '%s' tuple is NULL (NotAllowed)!\n", |
185 | object->name); |
186 | return CAPS_NULLVALUE; |
187 | } |
188 | if (value->nullVal != NotAllowed) |
189 | value->nullVal = (value->vals.tuple == NULL) ? IsNull : NotNull; |
190 | |
191 | if (value->dim != Vector) { |
192 | printf(" CAPS Error: Value '%s' Tuple dim must be Vector!\n", |
193 | object->name); |
194 | return CAPS_SHAPEERR; |
195 | } |
196 | |
197 | } else if ((value->type == Pointer) || (value->type == PointerMesh)) { |
198 | |
199 | if (value->nullVal == NotAllowed && value->vals.AIMptr == NULL) { |
200 | printf(" CAPS Error: Value '%s' AIMptr is NULL (NotAllowed)!\n", |
201 | object->name); |
202 | return CAPS_NULLVALUE; |
203 | } |
204 | if (value->nullVal != NotAllowed) |
205 | value->nullVal = (value->vals.AIMptr == NULL) ? IsNull : NotNull; |
206 | |
207 | } |
208 | |
209 | |
210 | if (value->dim == Scalar) { |
211 | if (value->length > 1) { |
212 | printf(" CAPS Error: Value '%s' dim = Scalar and length > 1 (length = %d)!\n", |
213 | object->name, value->length); |
214 | return CAPS_SHAPEERR; |
215 | } |
216 | } else if (value->dim == Vector) { |
217 | if ((value->ncol != 1) && (value->nrow != 1)) { |
218 | printf(" CAPS Error: Value '%s' dim = Vector nrow = %d ncol = %d!\n", |
219 | object->name, value->nrow, value->ncol); |
220 | return CAPS_SHAPEERR; |
221 | } |
222 | } else if (value->dim != Array2D) { |
223 | printf(" CAPS Error: Value '%s' Invalid dim = %d!\n", |
224 | object->name, value->dim); |
225 | return CAPS_BADINDEX; |
226 | } |
227 | |
228 | return CAPS_SUCCESS; |
229 | } |
230 | |
231 | |
232 | static int |
233 | caps_updateAnalysisOut(capsObject *vobject, const int funID, |
234 | int *nErr, capsErrs **errors) |
235 | { |
236 | int i, in, status, major, minor, nField, exec, dirty; |
237 | int *ranks, *fInOut; |
238 | char *intents, *apath, *unitSys, **fnames, temp[PATH_MAX]; |
239 | capsValue *value, *valu0, *valIn=NULL; |
240 | capsObject *pobject, *aobject; |
241 | capsProblem *problem; |
242 | capsAnalysis *analysis; |
243 | capsErrs *errs = NULL; |
244 | |
245 | *nErr = 0; |
246 | *errors = NULL; |
247 | |
248 | if (vobject->type != VALUE) return CAPS_BADTYPE; |
249 | if (vobject->subtype != ANALYSISOUT) return CAPS_BADTYPE; |
250 | value = (capsValue *) vobject->blind; |
251 | |
252 | status = caps_findProblem(vobject, funID, &pobject); |
253 | if (status != CAPS_SUCCESS) return status; |
254 | problem = (capsProblem *) pobject->blind; |
255 | |
256 | |
257 | aobject = vobject->parent; |
258 | if (aobject == NULL) return CAPS_NULLOBJ; |
259 | if (aobject->blind == NULL) return CAPS_NULLBLIND; |
260 | analysis = (capsAnalysis *) aobject->blind; |
261 | if (aobject->parent == NULL) return CAPS_NULLOBJ; |
262 | |
263 | |
264 | status = caps_analysisInfX(aobject, &apath, &unitSys, &major, &minor, |
265 | &intents, &nField, &fnames, &ranks, &fInOut, |
266 | &exec, &dirty); |
267 | if (status != CAPS_SUCCESS) return status; |
268 | if (dirty > 0) { |
269 | |
270 | if ((exec == 2) && (dirty < 5)) { |
271 | status = caps_execX(aobject, nErr, errors); |
272 | if (status != CAPS_SUCCESS) return status; |
273 | } else { |
274 | return CAPS_DIRTY; |
275 | } |
276 | } else if (analysis->reload == 1) { |
277 | |
278 | |
279 | status = caps_transferLinks(analysis, nErr, errors); |
280 | if (status != CAPS_SUCCESS) return status; |
281 | |
282 | if (analysis->nAnalysisIn > 0) |
283 | valIn = (capsValue *) analysis->analysisIn[0]->blind; |
284 | |
285 | status = aim_PostAnalysis(problem->aimFPTR, analysis->loadName, |
286 | analysis->instStore, &analysis->info, 1, |
287 | valIn); |
288 | analysis->info.inPost = 0; |
289 | |
290 | if (*nErr != 0) { |
291 | errs = *errors; |
292 | *nErr = 0; |
293 | *errors = NULL; |
294 | } |
295 | caps_getAIMerrs(analysis, nErr, errors); |
296 | caps_concatErrs(errs, errors); |
297 | *nErr = 0; |
298 | if (*errors != NULL) *nErr = (*errors)->nError; |
299 | if (status != CAPS_SUCCESS) { |
300 | printf(" CAPS Error: PostAnalysis %s (%d) ret = %d (%s -> caps_updateAnalysisOut)!\n", |
301 | analysis->loadName, analysis->info.instance, status, caps_funID[funID]); |
302 | return CAPS_BADINIT; |
303 | } |
304 | analysis->reload = 0; |
305 | } |
306 | |
307 | valu0 = (capsValue *) analysis->analysisOut[0]->blind; |
308 | in = value - valu0; |
309 | if (vobject->last.sNum < aobject->last.sNum) { |
310 | if ((value->type == Boolean) || (value->type == Integer)) { |
311 | if (value->length > 1) { |
312 | EG_free(value->vals.integers); |
313 | } |
314 | value->vals.integers = NULL; |
315 | } else if ((value->type == Double) || (value->type == DoubleDeriv)) { |
316 | if (value->length > 1) { |
317 | EG_free(value->vals.reals); |
318 | } |
319 | value->vals.reals = NULL; |
320 | for (i = 0; i < value->nderiv; i++) { |
321 | EG_free(value->derivs[i].name); |
322 | EG_free(value->derivs[i].deriv); |
323 | } |
324 | EG_free(value->derivs); |
325 | value->derivs = NULL; |
326 | value->nderiv = 0; |
327 | } else if (value->type == String) { |
328 | EG_free(value->vals.string); |
329 | value->vals.string = NULL; |
330 | } else if (value->type == Tuple) { |
331 | caps_freeTuple(value->length, value->vals.tuple); |
332 | value->vals.tuple = NULL; |
333 | } else if ((value->type != Pointer) && (value->type != PointerMesh)) { |
334 | return CAPS_BADTYPE; |
335 | } |
336 | caps_freeOwner(&vobject->last); |
337 | vobject->last.sNum = 0; |
338 | status = aim_CalcOutput(problem->aimFPTR, analysis->loadName, |
339 | analysis->instStore, &analysis->info, in+1, value); |
340 | caps_getAIMerrs(analysis, nErr, errors); |
341 | if (status != CAPS_SUCCESS) return status; |
342 | status = caps_checkValueObj(analysis->analysisOut[in]); |
343 | if (status != CAPS_SUCCESS) { |
344 | snprintf(temp, PATH_MAX, "'%s' CalcOutput Check Value %d (%s)", |
345 | analysis->loadName, status, caps_funID[funID]); |
346 | caps_makeSimpleErr(analysis->analysisOut[in], CERROR, temp, |
347 | NULL, NULL, errors); |
348 | if (*errors != NULL) *nErr = (*errors)->nError; |
349 | return status; |
350 | } |
351 | vobject->last.sNum = aobject->last.sNum; |
352 | status = caps_addHistory(vobject, problem); |
353 | if (status != CAPS_SUCCESS) |
354 | printf(" CAPS Warning: caps_addHistory = %d (%s)\n", |
355 | status, caps_funID[funID]); |
356 | status = caps_writeValueObj(problem, analysis->analysisOut[in]); |
357 | if (status != CAPS_SUCCESS) |
358 | printf(" CAPS Warning: caps_writeValueObj = %d (%s)\n", |
359 | status, caps_funID[funID]); |
360 | } |
361 | |
362 | return CAPS_SUCCESS; |
363 | } |
364 | |
365 | |
366 | static int |
367 | caps_getValuX(capsObject *object, enum capsvType *type, int *nrow, int *ncol, |
368 | const void **data, const int **partial, const char **units, |
369 | int *nErr, capsErrs **errors) |
370 | { |
371 | int status; |
372 | capsValue *value; |
373 | capsObject *pobject, *source, *last; |
374 | capsProblem *problem; |
375 | |
376 | *nErr = 0; |
377 | *errors = NULL; |
378 | status = caps_findProblem(object, 9999, &pobject); |
379 | if (status != CAPS_SUCCESS) return status; |
380 | problem = (capsProblem *) pobject->blind; |
381 | |
382 | source = object; |
383 | do { |
384 | if (source->magicnumber != CAPSMAGIC) return CAPS_BADOBJECT; |
385 | if (source->type != VALUE) return CAPS_BADTYPE; |
386 | if (source->blind == NULL) return CAPS_NULLBLIND; |
387 | value = (capsValue *) source->blind; |
388 | if (value->link == object) return CAPS_CIRCULARLINK; |
389 | last = source; |
390 | source = value->link; |
391 | } while (value->link != NULL); |
392 | |
393 | |
394 | if (problem->dbFlag == 0) |
395 | if (last->subtype == ANALYSISOUT) { |
396 | status = caps_updateAnalysisOut(last, CAPS_GETVALUE, nErr, errors); |
397 | if (status != CAPS_SUCCESS) return status; |
398 | } else if (last->subtype == GEOMETRYOUT) { |
399 | |
400 | status = caps_build(pobject, nErr, errors); |
401 | if ((status != CAPS_SUCCESS) && (status != CAPS_CLEAN)) return status; |
402 | } |
403 | |
404 | *type = value->type; |
405 | *nrow = value->nrow; |
406 | *ncol = value->ncol; |
407 | *partial = value->partial; |
408 | *units = value->units; |
409 | if (value->nullVal == IsNull) *nrow = *ncol = 0; |
410 | |
411 | |
412 | if (value->dim == Vector && value->ncol > 1) { |
413 | *nrow = value->ncol; |
414 | *ncol = value->nrow; |
415 | } |
416 | |
417 | if (data != NULL) { |
418 | *data = NULL; |
419 | if (value->nullVal != IsNull) { |
420 | if ((value->type == Boolean) || (value->type == Integer)) { |
421 | if (value->length == 1) { |
422 | *data = &value->vals.integer; |
423 | } else { |
424 | *data = value->vals.integers; |
425 | } |
426 | } else if ((value->type == Double) || (value->type == DoubleDeriv)) { |
427 | if (value->length == 1) { |
428 | *data = &value->vals.real; |
429 | } else { |
430 | *data = value->vals.reals; |
431 | } |
432 | } else if (value->type == String) { |
433 | *data = value->vals.string; |
434 | } else if (value->type == Tuple) { |
435 | *data = value->vals.tuple; |
436 | } else { |
437 | *data = value->vals.AIMptr; |
438 | } |
439 | } |
440 | } |
441 | |
442 | return CAPS_SUCCESS; |
443 | } |
444 | |
445 | |
446 | int |
447 | caps_getValue(capsObject *object, enum capsvType *type, int *nrow, int *ncol, |
448 | const void **data, const int **partial, const char **units, |
449 | int *nErr, capsErrs **errors) |
450 | { |
451 | int i, stat, ret, vlen; |
452 | const char *string; |
453 | CAPSLONG sNum; |
454 | capsObject *pobject; |
455 | capsProblem *problem; |
456 | capsValue *value; |
457 | capsJrnl args[8]; |
458 | enum capsvType itype; |
459 | size_t len; |
460 | |
461 | if (nErr == NULL) return CAPS_NULLVALUE; |
462 | if (errors == NULL) return CAPS_NULLVALUE; |
463 | *nErr = 0; |
464 | *errors = NULL; |
465 | if (object == NULL) return CAPS_NULLOBJ; |
466 | if (nrow == NULL) return CAPS_NULLVALUE; |
467 | if (ncol == NULL) return CAPS_NULLVALUE; |
468 | if (partial == NULL) return CAPS_NULLVALUE; |
469 | if (units == NULL) return CAPS_NULLVALUE; |
470 | if (object->magicnumber != CAPSMAGIC) return CAPS_BADOBJECT; |
471 | if (object->type != VALUE) return CAPS_BADTYPE; |
472 | if (object->blind == NULL) return CAPS_NULLBLIND; |
473 | value = (capsValue *) object->blind; |
474 | stat = caps_findProblem(object, CAPS_GETVALUE, &pobject); |
475 | if (stat != CAPS_SUCCESS) return stat; |
476 | problem = (capsProblem *) pobject->blind; |
477 | |
478 | |
479 | if (problem->dbFlag == 1) { |
480 | ret = caps_getValuX(object, type, nrow, ncol, data, partial, units, |
481 | nErr, errors); |
482 | *nErr = 0; |
483 | if (*errors != NULL) *nErr = (*errors)->nError; |
484 | return ret; |
485 | } |
486 | |
487 | args[0].type = jInteger; |
488 | args[1].type = jInteger; |
489 | args[2].type = jInteger; |
490 | args[3].type = jPointer; |
491 | args[4].type = jPointer; |
492 | args[5].type = jString; |
493 | args[6].type = jInteger; |
494 | args[7].type = jErr; |
495 | if (value->type == Tuple) args[3].type = jTuple; |
496 | stat = caps_jrnlRead(CAPS_GETVALUE, problem, object, 8, args, &sNum, |
497 | &ret); |
498 | if (stat == CAPS_JOURNALERR) return stat; |
499 | if (stat == CAPS_JOURNAL) { |
500 | *type = args[0].members.integer; |
501 | *nrow = args[1].members.integer; |
502 | *ncol = args[2].members.integer; |
503 | if (value->type == Tuple) { |
504 | *data = args[3].members.tuple; |
505 | } else { |
506 | *data = args[3].members.pointer; |
507 | } |
508 | *partial = args[4].members.pointer; |
509 | *units = args[5].members.string; |
510 | *nErr = args[6].members.integer; |
511 | *errors = args[7].members.errs; |
512 | return ret; |
513 | } |
514 | |
515 | itype = Pointer; |
516 | *nrow = *ncol = 0; |
517 | *data = NULL; |
518 | *partial = NULL; |
519 | *units = NULL; |
520 | if (ret == CAPS_SUCCESS) { |
521 | ret = caps_getValuX(object, &itype, nrow, ncol, data, partial, units, |
522 | nErr, errors); |
523 | *nErr = 0; |
524 | if (*errors != NULL) *nErr = (*errors)->nError; |
525 | } |
526 | args[0].members.integer = itype; |
527 | args[1].members.integer = *nrow; |
528 | args[2].members.integer = *ncol; |
529 | if (itype == Tuple) args[3].members.tuple = (void *) *data; |
530 | |
531 | if (itype != Tuple) args[3].members.pointer = (void *) *data; |
532 | |
533 | args[4].members.pointer = (void *) *partial; |
534 | args[5].members.string = (void *) *units; |
535 | args[6].members.integer = *nErr; |
536 | args[7].members.errs = *errors; |
537 | args[3].length = 0; |
538 | args[3].num = 0; |
539 | args[4].length = 0; |
540 | vlen = *nrow; |
541 | vlen *= *ncol; |
542 | if (*data != NULL) { |
543 | if (itype == Tuple) { |
544 | args[3].num = vlen; |
545 | } else { |
546 | len = sizeof(char *); |
547 | if ((itype == Integer) || (itype == Boolean)) { |
548 | len = vlen*sizeof(int); |
549 | } else if ((itype == Double) || (itype == DoubleDeriv)) { |
550 | len = vlen*sizeof(double); |
551 | } else if (itype == String) { |
552 | string = (char *) *data; |
553 | if (vlen == 1) { |
554 | len = (strlen(string)+1)*sizeof(char); |
555 | } else { |
556 | len = 0; |
557 | for (i = 0; i < vlen; i++) |
558 | len += strlen(string + len) + 1; |
559 | len *= sizeof(char); |
560 | } |
561 | } |
562 | args[3].length = len; |
563 | } |
564 | } |
565 | if (*partial != NULL) { |
566 | len = *nrow; |
567 | len *= *ncol*sizeof(int); |
568 | args[4].length = len; |
569 | } |
570 | *type = itype; |
571 | caps_jrnlWrite(CAPS_GETVALUE, problem, object, ret, 8, args, sNum, |
572 | problem->sNum); |
573 | |
574 | return ret; |
575 | } |
576 | |
577 | |
578 | int |
579 | caps_makeValueX(capsObject *pobject, const char *vname, enum capssType stype, |
580 | enum capsvType vtype, int nrow, int ncol, const void *data, |
581 | int *partial, const char *units, |
582 | capsObject **vobj) |
583 | { |
584 | int status, i, vlen; |
585 | char filename[PATH_MAX], temp[PATH_MAX]; |
586 | capsObject *object, **tmp; |
587 | capsProblem *problem; |
588 | capsValue *value; |
589 | FILE *fp; |
590 | |
591 | vlen = ncol*nrow; |
592 | problem = (capsProblem *) pobject->blind; |
593 | |
594 | status = caps_makeVal(vtype, vlen, data, &value); |
595 | if (status != CAPS_SUCCESS) return status; |
596 | value->nrow = nrow; |
597 | value->ncol = ncol; |
598 | value->dim = Scalar; |
599 | if ((nrow > 1) || (ncol > 1)) value->dim = Vector; |
600 | if ((nrow > 1) && (ncol > 1)) value->dim = Array2D; |
601 | |
602 | |
603 | if (partial != NULL) { |
604 | value->partial = (int*) EG_alloc(vlen*sizeof(int)); |
605 | if (value->partial == NULL) { |
606 | if (value->length != 1) { |
607 | if (value->type == Integer) { |
608 | EG_free(value->vals.integers); |
609 | } else if ((value->type == Double) || (value->type == DoubleDeriv)) { |
610 | EG_free(value->vals.reals); |
611 | } else if (value->type == String) { |
612 | EG_free(value->vals.string); |
613 | } else if (value->type == Tuple) { |
614 | caps_freeTuple(value->length, value->vals.tuple); |
615 | } |
616 | } |
617 | EG_free(value); |
618 | return EGADS_MALLOC; |
619 | } |
620 | for (i = 0; i < vlen; i++) value->partial[i] = partial[i]; |
621 | value->nullVal = IsPartial; |
622 | } |
623 | |
624 | |
625 | status = caps_makeObject(&object); |
626 | if (status != CAPS_SUCCESS) { |
627 | if (value->length != 1) { |
628 | if (value->type == Integer) { |
629 | EG_free(value->vals.integers); |
630 | } else if ((value->type == Double) || (value->type == DoubleDeriv)) { |
631 | EG_free(value->vals.reals); |
632 | } else if (value->type == String) { |
633 | EG_free(value->vals.string); |
634 | } else if (value->type == Tuple) { |
635 | caps_freeTuple(value->length, value->vals.tuple); |
636 | } |
637 | } |
638 | EG_free(value->partial); |
639 | EG_free(value); |
640 | return status; |
641 | } |
642 | object->parent = pobject; |
643 | |
644 | |
645 | if (stype == PARAMETER) { |
646 | value->index = problem->nParam + 1; |
647 | if (problem->params == NULL) { |
648 | problem->params = (capsObject **) EG_alloc(sizeof(capsObject *)); |
649 | if (problem->params == NULL) { |
650 | if (value->length != 1) { |
651 | if (value->type == Integer) { |
652 | EG_free(value->vals.integers); |
653 | } else if ((value->type == Double) || (value->type == DoubleDeriv)) { |
654 | EG_free(value->vals.reals); |
655 | } else if (value->type == String) { |
656 | EG_free(value->vals.string); |
657 | } else if (value->type == Tuple) { |
658 | caps_freeTuple(value->length, value->vals.tuple); |
659 | } |
660 | } |
661 | EG_free(value->partial); |
662 | EG_free(value); |
663 | EG_free(object); |
664 | return EGADS_MALLOC; |
665 | } |
666 | } else { |
667 | tmp = (capsObject **) EG_reall( problem->params, |
668 | (problem->nParam+1)*sizeof(capsObject *)); |
669 | if (tmp == NULL) { |
670 | if (value->length != 1) { |
671 | if (value->type == Integer) { |
672 | EG_free(value->vals.integers); |
673 | } else if ((value->type == Double) || (value->type == DoubleDeriv)) { |
674 | EG_free(value->vals.reals); |
675 | } else if (value->type == String) { |
676 | EG_free(value->vals.string); |
677 | } else if (value->type == Tuple) { |
678 | caps_freeTuple(value->length, value->vals.tuple); |
679 | } |
680 | } |
681 | EG_free(value->partial); |
682 | EG_free(value); |
683 | EG_free(object); |
684 | return EGADS_MALLOC; |
685 | } |
686 | problem->params = tmp; |
687 | } |
688 | problem->params[problem->nParam] = object; |
689 | problem->nParam += 1; |
690 | } else { |
691 | value->index = problem->nUser + 1; |
692 | if (problem->users == NULL) { |
693 | problem->users = (capsObject **) EG_alloc(sizeof(capsObject *)); |
694 | if (problem->users == NULL) { |
695 | if (value->length != 1) { |
696 | if (value->type == Integer) { |
697 | EG_free(value->vals.integers); |
698 | } else if ((value->type == Double) || (value->type == DoubleDeriv)) { |
699 | EG_free(value->vals.reals); |
700 | } else if (value->type == String) { |
701 | EG_free(value->vals.string); |
702 | } else if (value->type == Tuple) { |
703 | caps_freeTuple(value->length, value->vals.tuple); |
704 | } |
705 | } |
706 | EG_free(value->partial); |
707 | EG_free(value); |
708 | EG_free(object); |
709 | return EGADS_MALLOC; |
710 | } |
711 | } else { |
712 | tmp = (capsObject **) EG_reall( problem->users, |
713 | (problem->nUser+1)*sizeof(capsObject *)); |
714 | if (tmp == NULL) { |
715 | if (value->length != 1) { |
716 | if (value->type == Integer) { |
717 | EG_free(value->vals.integers); |
718 | } else if ((value->type == Double) || (value->type == DoubleDeriv)) { |
719 | EG_free(value->vals.reals); |
720 | } else if (value->type == String) { |
721 | EG_free(value->vals.string); |
722 | } else if (value->type == Tuple) { |
723 | caps_freeTuple(value->length, value->vals.tuple); |
724 | } |
725 | } |
726 | EG_free(value->partial); |
727 | EG_free(value); |
728 | EG_free(object); |
729 | return EGADS_MALLOC; |
730 | } |
731 | problem->users = tmp; |
732 | } |
733 | problem->users[problem->nUser] = object; |
734 | problem->nUser += 1; |
735 | } |
736 | problem->sNum += 1; |
737 | object->last.sNum = problem->sNum; |
738 | |
739 | |
740 | if ((units != NULL) && |
741 | (strlen(units) > 0)) value->units = EG_strdup(units); |
742 | object->name = EG_strdup(vname); |
743 | object->type = VALUE; |
744 | object->subtype = stype; |
745 | object->blind = value; |
746 | |
747 | object->parent = pobject; |
748 | |
749 | |
750 | |
751 | #ifdef WIN32 |
752 | snprintf(filename, PATH_MAX, "%s\\capsRestart\\param.txt", problem->root); |
753 | snprintf(temp, PATH_MAX, "%s\\capsRestart\\xxTempxx", problem->root); |
754 | #else |
755 | snprintf(filename, PATH_MAX, "%s/capsRestart/param.txt", problem->root); |
756 | snprintf(temp, PATH_MAX, "%s/capsRestart/xxTempxx", problem->root); |
757 | #endif |
758 | fp = fopen(temp, "w"); |
759 | if (fp == NULL) { |
760 | printf(" CAPS Warning: Cannot open %s (caps_makeValue)\n", filename); |
761 | } else { |
762 | fprintf(fp, "%d %d\n", problem->nParam, problem->nUser); |
763 | if (problem->params != NULL) |
764 | for (i = 0; i < problem->nParam; i++) |
765 | fprintf(fp, "%s\n", problem->params[i]->name); |
766 | fclose(fp); |
767 | status = caps_rename(temp, filename); |
768 | if (status != CAPS_SUCCESS) |
769 | printf(" CAPS Warning: Cannot rename %s!\n", filename); |
770 | } |
771 | status = caps_writeValueObj(problem, object); |
772 | if (status != CAPS_SUCCESS) |
773 | printf(" CAPS Warning: caps_writeValueObj = %d (caps_makeValue)\n", |
774 | status); |
775 | |
776 | *vobj = object; |
777 | |
778 | return CAPS_SUCCESS; |
779 | } |
780 | |
781 | |
782 | int |
783 | caps_makeValue(capsObject *pobject, const char *vname, enum capssType stype, |
784 | enum capsvType vtype, int nrow, int ncol, const void *data, |
785 | int *partial, const char *units, |
786 | capsObject **vobj) |
787 | { |
788 | int i, stat, ret, vlen; |
789 | CAPSLONG sNum; |
790 | capsProblem *problem; |
791 | ut_unit *utunit; |
792 | capsJrnl args[1]; |
793 | |
794 | if (pobject == NULL) return CAPS_NULLOBJ; |
795 | if (vobj == NULL) return CAPS_NULLOBJ; |
796 | *vobj = NULL; |
797 | if (pobject->magicnumber != CAPSMAGIC) return CAPS_BADOBJECT; |
798 | if (pobject->type != PROBLEM) return CAPS_BADTYPE; |
799 | if (pobject->blind == NULL) return CAPS_NULLBLIND; |
800 | if (vname == NULL) return CAPS_NULLNAME; |
801 | if ((stype != PARAMETER) && (stype != USER)) return CAPS_BADTYPE; |
802 | if (!((vtype == Double) || (vtype == DoubleDeriv) || (vtype == String)) |
803 | && (units != NULL)) return CAPS_UNITERR; |
804 | vlen = ncol*nrow; |
805 | if (vlen <= 0) return CAPS_BADINDEX; |
806 | problem = (capsProblem *) pobject->blind; |
807 | if (problem->dbFlag == 1) return CAPS_READONLYERR; |
808 | |
809 | args[0].type = jObject; |
810 | stat = caps_jrnlRead(CAPS_MAKEVALUE, problem, *vobj, 1, args, &sNum, |
811 | &ret); |
812 | if (stat == CAPS_JOURNALERR) return stat; |
813 | if (stat == CAPS_JOURNAL) { |
814 | if (ret == CAPS_SUCCESS) *vobj = args[0].members.obj; |
815 | return ret; |
816 | } |
817 | |
818 | |
819 | ret = CAPS_SUCCESS; |
820 | if ((stype == PARAMETER) && (problem->params != NULL)) |
821 | for (i = 0; i < problem->nParam; i++) { |
822 | if (problem->params[i] == NULL) continue; |
823 | if (problem->params[i]->name == NULL) continue; |
824 | if (strcmp(problem->params[i]->name, vname) == 0) ret = CAPS_BADNAME; |
825 | } |
826 | |
827 | |
828 | if ((units != NULL) && (ret == CAPS_SUCCESS)) { |
829 | utunit = ut_parse((ut_system *) problem->utsystem, units, UT_ASCII); |
830 | if (utunit == NULL) ret = CAPS_UNITERR; |
831 | ut_free(utunit); |
832 | } |
833 | |
834 | sNum = problem->sNum; |
835 | if (ret == CAPS_SUCCESS) |
836 | ret = caps_makeValueX(pobject, vname, stype, vtype, nrow, ncol, data, |
837 | partial, units, vobj); |
838 | args[0].members.obj = *vobj; |
839 | caps_jrnlWrite(CAPS_MAKEVALUE, problem, *vobj, ret, 1, args, sNum, |
840 | problem->sNum); |
841 | |
842 | return ret; |
843 | } |
844 | |
845 | |
846 | static int |
847 | caps_setValuX(capsObject *object, enum capsvType vtype, int nrow, int ncol, |
848 | const void *data, const int *partial, |
849 | const char *units, int *nErr, capsErrs **errors) |
850 | { |
851 | int i, j, k, n, vlen, slen=0, status; |
852 | int *ints = NULL; |
853 | double *reals = NULL; |
854 | char *str = NULL; |
855 | capsTuple *tuple = NULL; |
856 | capsObject *pobject, *source, *last; |
857 | capsValue *value; |
858 | capsProblem *problem; |
859 | |
860 | *nErr = 0; |
861 | *errors = NULL; |
862 | value = (capsValue *) object->blind; |
863 | vlen = nrow*ncol; |
864 | status = caps_unitConvertible(units, value->units); |
865 | if (status != CAPS_SUCCESS) return status; |
| 1 | Assuming 'status' is equal to CAPS_SUCCESS | |
|
| |
866 | |
867 | status = caps_findProblem(object, 9999, &pobject); |
868 | if (status != CAPS_SUCCESS) return status; |
| 3 | | Assuming 'status' is equal to CAPS_SUCCESS | |
|
| |
869 | problem = (capsProblem *) pobject->blind; |
870 | |
871 | if (data == NULL) { |
| 5 | | Assuming 'data' is equal to NULL | |
|
| |
872 | if(value->lfixed == Change) vlen = 0; |
| 7 | | Assuming field 'lfixed' is not equal to Change | |
|
| |
873 | else vlen = value->length; |
874 | } |
875 | |
876 | if ((value->type != vtype) && (data != NULL)) { |
| 9 | | Assuming 'vtype' is equal to field 'type' | |
|
877 | if (!(((value->type == Double) || (value->type == DoubleDeriv)) && |
878 | ((vtype == Integer) || (vtype == Boolean)))) |
879 | return CAPS_BADTYPE; |
880 | } |
881 | if (value->nullVal == IsNull || |
| 10 | | Assuming field 'nullVal' is not equal to IsNull | |
|
| |
882 | value->nullVal == IsPartial) value->nullVal = NotNull; |
| 11 | | Assuming field 'nullVal' is not equal to IsPartial | |
|
883 | |
884 | |
885 | if (value->type == Integer) { |
| 13 | | Assuming field 'type' is not equal to Integer | |
|
| |
886 | if (value->limits.ilims[0] != value->limits.ilims[1]) |
887 | if (vtype == Integer) { |
888 | ints = (int *) data; |
889 | for (i = 0; i < vlen; i++) |
890 | if ((ints[i] < value->limits.ilims[0]) || |
891 | (ints[i] > value->limits.ilims[1])) return CAPS_RANGEERR; |
892 | } else { |
893 | reals = (double *) data; |
894 | for (i = 0; i < vlen; i++) |
895 | if ((reals[i] < value->limits.ilims[0]) || |
896 | (reals[i] > value->limits.ilims[1])) return CAPS_RANGEERR; |
897 | } |
898 | } else if ((value->type == Double) || (value->type == DoubleDeriv)) { |
| 15 | | Assuming field 'type' is equal to Double | |
|
899 | if (value->limits.dlims[0] != value->limits.dlims[1]) |
| 16 | | Assuming the condition is true | |
|
| |
900 | if (vtype == Integer) { |
| 18 | | Assuming 'vtype' is equal to Integer | |
|
| |
901 | ints = (int *) data; |
| 20 | | Null pointer value stored to 'ints' | |
|
902 | for (i = 0; i < vlen; i++) |
| 21 | | Assuming 'i' is < 'vlen' | |
|
| 22 | | Loop condition is true. Entering loop body | |
|
903 | if ((ints[i] < value->limits.dlims[0]) || |
| 23 | | Array access (from variable 'ints') results in a null pointer dereference |
|
904 | (ints[i] > value->limits.dlims[1])) return CAPS_RANGEERR; |
905 | } else { |
906 | reals = (double *) data; |
907 | for (i = 0; i < vlen; i++) |
908 | if ((reals[i] < value->limits.dlims[0]) || |
909 | (reals[i] > value->limits.dlims[1])) return CAPS_RANGEERR; |
910 | } |
911 | } |
912 | |
913 | |
914 | if ((vtype == Tuple) && (data != NULL)) { |
915 | tuple = (capsTuple *) data; |
916 | for (i = 0; i < vlen; i++) |
917 | for (j = i+1; j < vlen; j++) |
918 | if (strcmp(tuple[i].name, tuple[j].name) == 0) |
919 | return CAPS_BADVALUE; |
920 | } |
921 | |
922 | |
923 | if (vlen != value->length) { |
924 | if ((value->lfixed == Fixed) && (value->type != String) && |
925 | (value->type != Pointer) && (value->type != Tuple) && |
926 | (value->type != PointerMesh)) return CAPS_SHAPEERR; |
927 | if ((value->type == Boolean) || (value->type == Integer)) { |
928 | if (vlen > 1) { |
929 | ints = (int *) EG_alloc(vlen*sizeof(int)); |
930 | if (ints == NULL) return EGADS_MALLOC; |
931 | } |
932 | if (value->length > 1) EG_free(value->vals.integers); |
933 | if (ints != NULL) value->vals.integers = ints; |
934 | } else if ((value->type == Double) || (value->type == DoubleDeriv)) { |
935 | if (vlen > 1) { |
936 | reals = (double *) EG_alloc(vlen*sizeof(double)); |
937 | if (reals == NULL) return EGADS_MALLOC; |
938 | } |
939 | if (value->length > 1) EG_free(value->vals.reals); |
940 | if (reals != NULL) value->vals.reals = reals; |
941 | } else if (value->type == Tuple) { |
942 | if (vlen > 0) { |
943 | status = caps_makeTuple(vlen, &tuple); |
944 | if ((status != CAPS_SUCCESS) || (tuple == NULL)) { |
945 | if (tuple == NULL) status = CAPS_NULLVALUE; |
946 | return status; |
947 | } |
948 | } |
949 | caps_freeTuple(value->length, value->vals.tuple); |
950 | value->vals.tuple = tuple; |
951 | } |
952 | |
953 | if ((value->nullVal == IsPartial) || (partial != NULL)) { |
954 | ints = (int *) EG_alloc(vlen*sizeof(int)); |
955 | if (ints == NULL) return EGADS_MALLOC; |
956 | EG_free(value->partial); |
957 | value->partial = ints; |
958 | for (i = 0; i < vlen; i++) value->partial[i] = NotNull; |
959 | value->nullVal = IsPartial; |
960 | } |
961 | |
962 | value->length = vlen; |
963 | } else { |
964 | if (value->type == Tuple) { |
965 | status = caps_makeTuple(vlen, &tuple); |
966 | if ((status != CAPS_SUCCESS) || (tuple == NULL)) { |
967 | if (tuple == NULL) status = CAPS_NULLVALUE; |
968 | return status; |
969 | } |
970 | caps_freeTuple(value->length, value->vals.tuple); |
971 | value->vals.tuple = tuple; |
972 | } |
973 | } |
974 | |
975 | |
976 | if (data == NULL) { |
977 | value->nullVal = IsNull; |
978 | } else { |
979 | if ((value->type == Boolean) || (value->type == Integer)) { |
980 | ints = (int *) data; |
981 | if (vlen == 1) { |
982 | value->vals.integer = ints[0]; |
983 | } else { |
984 | for (i = 0; i < vlen; i++) value->vals.integers[i] = ints[i]; |
985 | } |
986 | } else if ((value->type == Double) || (value->type == DoubleDeriv)) { |
987 | if ((vtype == Double) || (vtype == DoubleDeriv)) { |
988 | reals = (double *) data; |
989 | if (vlen == 1) { |
990 | value->vals.real = reals[0]; |
991 | reals = &value->vals.real; |
992 | } else { |
993 | for (i = 0; i < vlen; i++) value->vals.reals[i] = reals[i]; |
994 | reals = value->vals.reals; |
995 | } |
996 | } else { |
997 | ints = (int *) data; |
998 | if (vlen == 1) { |
999 | value->vals.real = ints[0]; |
1000 | reals = &value->vals.real; |
1001 | } else { |
1002 | for (i = 0; i < vlen; i++) value->vals.reals[i] = ints[i]; |
1003 | reals = value->vals.reals; |
1004 | } |
1005 | } |
1006 | status = caps_convert(vlen, units, reals, value->units, reals); |
1007 | if (status != CAPS_SUCCESS) return status; |
1008 | } else if (value->type == String) { |
1009 | |
1010 | EG_free(value->vals.string); |
1011 | value->vals.string = NULL; |
1012 | str = (char *) data; |
1013 | for (slen = i = 0; i < vlen; i++) |
1014 | slen += strlen(str + slen)+1; |
1015 | value->vals.string = (char *) EG_alloc(slen*sizeof(char)); |
1016 | if (value->vals.string == NULL) return EGADS_MALLOC; |
1017 | for (i = 0; i < slen; i++) value->vals.string[i] = str[i]; |
1018 | } else if (value->type == Tuple) { |
1019 | tuple = (capsTuple *) data; |
1020 | for (i = 0; i < vlen; i++) { |
1021 | value->vals.tuple[i].name = EG_strdup(tuple[i].name); |
1022 | value->vals.tuple[i].value = EG_strdup(tuple[i].value); |
1023 | if ((tuple[i].name != NULL) && |
1024 | (value->vals.tuple[i].name == NULL)) return EGADS_MALLOC; |
1025 | if ((tuple[i].value != NULL) && |
1026 | (value->vals.tuple[i].value == NULL)) return EGADS_MALLOC; |
1027 | } |
1028 | } else { |
1029 | |
1030 | value->vals.AIMptr = (void *) data; |
1031 | |
1032 | } |
1033 | if (partial != NULL) { |
1034 | if (value->partial == NULL) { |
1035 | ints = (int *) EG_alloc(vlen*sizeof(int)); |
1036 | if (ints == NULL) return EGADS_MALLOC; |
1037 | value->partial = ints; |
1038 | } |
1039 | for (i = 0; i < vlen; i++) value->partial[i] = partial[i]; |
1040 | value->nullVal = IsPartial; |
1041 | } else { |
1042 | EG_free(value->partial); |
1043 | value->partial = NULL; |
1044 | } |
1045 | } |
1046 | |
1047 | if (value->dim == Vector) { |
1048 | if (value->ncol == 1) value->nrow = vlen; |
1049 | else value->ncol = vlen; |
1050 | } else { |
1051 | value->nrow = nrow; |
1052 | value->ncol = ncol; |
1053 | } |
1054 | |
1055 | if (object->subtype != USER) { |
1056 | caps_freeOwner(&object->last); |
1057 | problem->sNum += 1; |
1058 | object->last.sNum = problem->sNum; |
1059 | status = caps_addHistory(object, problem); |
1060 | if (status != CAPS_SUCCESS) |
1061 | printf(" CAPS Warning: caps_addHistory = %d (caps_setValue)\n", status); |
1062 | } |
1063 | |
1064 | |
1065 | if (object->subtype == GEOMETRYIN) { |
1066 | if (vlen == 1) { |
1067 | reals = &value->vals.real; |
1068 | } else { |
1069 | reals = value->vals.reals; |
1070 | } |
1071 | for (n = k = 0; k < value->nrow; k++) |
1072 | for (j = 0; j < value->ncol; j++, n++) { |
1073 | if (value->partial != NULL) { |
1074 | status = ocsmSetValuD(problem->modl, value->pIndex, k+1, j+1, |
1075 | value->partial[n] == NotNull ? reals[n] : -HUGEQ); |
1076 | } else { |
1077 | status = ocsmSetValuD(problem->modl, value->pIndex, k+1, j+1, |
1078 | reals[n]); |
1079 | } |
1080 | if (status != SUCCESS) { |
1081 | printf(" CAPS Error: Cant change %s[%d,%d] = %d (caps_setValue)!\n", |
1082 | object->name, k+1, j+1, status); |
1083 | return CAPS_BADVALUE; |
1084 | } |
1085 | } |
1086 | } else { |
1087 | for (i = 0; i < problem->nGeomIn; i++) { |
1088 | source = problem->geomIn[i]; |
1089 | last = NULL; |
1090 | do { |
1091 | if (source->magicnumber != CAPSMAGIC) break; |
1092 | if (source->type != VALUE) break; |
1093 | if (source->blind == NULL) break; |
1094 | value = (capsValue *) source->blind; |
1095 | if (value->link == problem->geomIn[i]) break; |
1096 | last = source; |
1097 | source = value->link; |
1098 | } while (value->link != NULL); |
1099 | if (last != object) continue; |
1100 | |
1101 | source = problem->geomIn[i]; |
1102 | value = (capsValue *) source->blind; |
1103 | if ((value->nrow != nrow) || (value->ncol != ncol)) { |
1104 | printf(" CAPS Warning: Shape problem with link %s %s (caps_setValue)!\n", |
1105 | object->name, source->name); |
1106 | continue; |
1107 | } |
1108 | if ((vtype == Double) || (vtype == DoubleDeriv)) { |
1109 | reals = (double *) data; |
1110 | if (vlen == 1) { |
1111 | value->vals.real = reals[0]; |
1112 | reals = &value->vals.real; |
1113 | } else { |
1114 | for (i = 0; i < vlen; i++) value->vals.reals[i] = reals[i]; |
1115 | reals = value->vals.reals; |
1116 | } |
1117 | } else { |
1118 | ints = (int *) data; |
1119 | if (vlen == 1) { |
1120 | value->vals.real = ints[0]; |
1121 | reals = &value->vals.real; |
1122 | } else { |
1123 | for (i = 0; i < vlen; i++) value->vals.reals[i] = ints[i]; |
1124 | reals = value->vals.reals; |
1125 | } |
1126 | } |
1127 | status = caps_convert(vlen, units, reals, value->units, reals); |
1128 | if (status != CAPS_SUCCESS) return status; |
1129 | for (n = k = 0; k < nrow; k++) |
1130 | for (j = 0; j < ncol; j++, n++) { |
1131 | if (value->nullVal == IsPartial) { |
1132 | status = ocsmSetValuD(problem->modl, value->pIndex, k+1, j+1, |
1133 | value->partial[n] == NotNull ? reals[n] : -HUGEQ); |
1134 | } else { |
1135 | status = ocsmSetValuD(problem->modl, value->pIndex, k+1, j+1, |
1136 | reals[n]); |
1137 | } |
1138 | if (status != SUCCESS) { |
1139 | printf(" CAPS Error: Cant change %s[%d,%d] = %d (caps_setValue)!\n", |
1140 | object->name, k+1, j+1, status); |
1141 | return CAPS_BADVALUE; |
1142 | } |
1143 | } |
1144 | caps_freeOwner(&source->last); |
1145 | source->last = object->last; |
1146 | source->last.pname = EG_strdup(object->last.pname); |
1147 | source->last.pID = EG_strdup(object->last.pID); |
1148 | source->last.user = EG_strdup(object->last.user); |
1149 | } |
1150 | } |
1151 | |
1152 | |
1153 | if (object->subtype != USER) { |
1154 | status = caps_writeValueObj(problem, object); |
1155 | if (status != CAPS_SUCCESS) |
1156 | printf(" CAPS Warning: caps_writeValueObj = %d (caps_setValue)\n", |
1157 | status); |
1158 | } |
1159 | |
1160 | return CAPS_SUCCESS; |
1161 | } |
1162 | |
1163 | |
1164 | int |
1165 | caps_setValue(capsObject *object, enum capsvType vtype, int nrow, int ncol, |
1166 | const void *data, const int *partial, |
1167 | const char *units, int *nErr, capsErrs **errors) |
1168 | { |
1169 | int i, stat, ret, vlen; |
1170 | CAPSLONG sNum; |
1171 | capsObject *pobject; |
1172 | capsValue *value; |
1173 | capsProblem *problem; |
1174 | capsJrnl args[2]; |
1175 | |
1176 | if (nErr == NULL) return CAPS_NULLVALUE; |
1177 | if (errors == NULL) return CAPS_NULLVALUE; |
1178 | *nErr = 0; |
1179 | *errors = NULL; |
1180 | if (object == NULL) return CAPS_NULLOBJ; |
1181 | if (object->magicnumber != CAPSMAGIC) return CAPS_BADOBJECT; |
1182 | if (object->type != VALUE) return CAPS_BADTYPE; |
1183 | if (object->subtype == GEOMETRYOUT) return CAPS_BADTYPE; |
1184 | if (object->subtype == ANALYSISOUT) return CAPS_BADTYPE; |
1185 | if (object->blind == NULL) return CAPS_NULLBLIND; |
1186 | value = (capsValue *) object->blind; |
1187 | if (object->subtype == GEOMETRYIN) |
1188 | if (value->gInType == 2) return CAPS_READONLYERR; |
1189 | if (value->link != NULL) return CAPS_LINKERR; |
1190 | if (data == NULL) { |
1191 | if (value->nullVal == NotAllowed) return CAPS_NULLVALUE; |
1192 | } else { |
1193 | vlen = nrow*ncol; |
1194 | if (vlen <= 0) return CAPS_RANGEERR; |
1195 | if (value->sfixed == Fixed) { |
1196 | if (value->dim == Scalar) { |
1197 | if (vlen > 1) return CAPS_SHAPEERR; |
1198 | } else if (value->dim == Vector) { |
1199 | if ((ncol != 1) && (nrow != 1)) return CAPS_SHAPEERR; |
1200 | } |
1201 | } |
1202 | if ((value->lfixed == Fixed) && (vlen != value->length)) |
1203 | return CAPS_SHAPEERR; |
1204 | if (partial != NULL) { |
1205 | for (i = 0; i < vlen; i++) |
1206 | if (!(partial[i] == NotNull || |
1207 | partial[i] == IsNull)) return CAPS_NULLVALUE; |
1208 | } |
1209 | } |
1210 | |
1211 | stat = caps_findProblem(object, CAPS_SETVALUE, &pobject); |
1212 | if (stat != CAPS_SUCCESS) return stat; |
1213 | if (( object->subtype == GEOMETRYIN) && |
1214 | (pobject->subtype == STATIC )) return CAPS_READONLYERR; |
1215 | problem = (capsProblem *) pobject->blind; |
1216 | if (problem->dbFlag == 1) return CAPS_READONLYERR; |
1217 | |
1218 | args[0].type = jInteger; |
1219 | args[1].type = jErr; |
1220 | stat = caps_jrnlRead(CAPS_SETVALUE, problem, object, 2, args, &sNum, |
1221 | &ret); |
1222 | if (stat == CAPS_JOURNALERR) return stat; |
1223 | if (stat == CAPS_JOURNAL) { |
1224 | *nErr = args[0].members.integer; |
1225 | *errors = args[1].members.errs; |
1226 | return ret; |
1227 | } |
1228 | |
1229 | sNum = problem->sNum; |
1230 | ret = caps_setValuX(object, vtype, nrow, ncol, data, partial, units, nErr, |
1231 | errors); |
1232 | args[0].members.integer = *nErr; |
1233 | args[1].members.errs = *errors; |
1234 | caps_jrnlWrite(CAPS_SETVALUE, problem, object, ret, 2, args, sNum, |
1235 | problem->sNum); |
1236 | |
1237 | return ret; |
1238 | } |
1239 | |
1240 | |
1241 | int |
1242 | caps_getLimits(const capsObj object, enum capsvType *vtype, const void **limits, |
1243 | const char **units) |
1244 | { |
1245 | int status, ret; |
1246 | CAPSLONG sNum; |
1247 | capsObject *pobject; |
1248 | capsValue *value; |
1249 | capsProblem *problem; |
1250 | capsJrnl args[3]; |
1251 | |
1252 | if (limits == NULL) return CAPS_NULLVALUE; |
1253 | *limits = NULL; |
1254 | if (units == NULL) return CAPS_NULLVALUE; |
1255 | *units = NULL; |
1256 | if (vtype == NULL) return CAPS_NULLVALUE; |
1257 | *vtype = 0; |
1258 | |
1259 | if (object == NULL) return CAPS_NULLOBJ; |
1260 | if (object->magicnumber != CAPSMAGIC) return CAPS_BADOBJECT; |
1261 | if (object->type != VALUE) return CAPS_BADTYPE; |
1262 | if (object->blind == NULL) return CAPS_NULLBLIND; |
1263 | value = (capsValue *) object->blind; |
1264 | if ((value->type != Integer) && (value->type != Double) && |
1265 | (value->type != DoubleDeriv)) return CAPS_BADTYPE; |
1266 | |
1267 | status = caps_findProblem(object, CAPS_GETLIMITS, &pobject); |
1268 | if (status != CAPS_SUCCESS) return status; |
1269 | problem = (capsProblem *) pobject->blind; |
1270 | |
1271 | args[0].type = jInteger; |
1272 | args[1].type = jPointer; |
1273 | args[2].type = jString; |
1274 | if (problem->dbFlag == 0) { |
1275 | status = caps_jrnlRead(CAPS_GETLIMITS, problem, object, 3, args, &sNum, |
1276 | &ret); |
1277 | if (status == CAPS_JOURNALERR) return status; |
1278 | if (status == CAPS_JOURNAL) { |
1279 | *vtype = args[0].members.integer; |
1280 | *limits = args[1].members.pointer; |
1281 | *units = args[2].members.string; |
1282 | return ret; |
1283 | } |
1284 | } |
1285 | |
1286 | *vtype = value->type; |
1287 | *units = value->units; |
1288 | args[1].length = 0; |
1289 | if (value->type == Integer) { |
1290 | if (value->limits.ilims[0] == value->limits.ilims[1]) goto complete; |
1291 | *limits = value->limits.ilims; |
1292 | args[1].length = 2*sizeof(int); |
1293 | } else { |
1294 | if (value->limits.dlims[0] == value->limits.dlims[1]) goto complete; |
1295 | *limits = value->limits.dlims; |
1296 | args[1].length = 2*sizeof(double); |
1297 | } |
1298 | |
1299 | complete: |
1300 | if (problem->dbFlag == 1) return CAPS_SUCCESS; |
1301 | args[0].members.integer = *vtype; |
1302 | args[1].members.pointer = (void *) *limits; |
1303 | args[2].members.string = (char *) *units; |
1304 | caps_jrnlWrite(CAPS_GETLIMITS, problem, object, CAPS_SUCCESS, 3, args, |
1305 | problem->sNum, problem->sNum); |
1306 | |
1307 | return CAPS_SUCCESS; |
1308 | } |
1309 | |
1310 | |
1311 | int |
1312 | caps_setLimits(capsObject *object, enum capsvType vtype, void *limits, |
1313 | const char *units, int *nErr, capsErrs **errors) |
1314 | { |
1315 | int *ints, i, status; |
1316 | double *realp, reals[2]; |
1317 | capsValue *value; |
1318 | capsObject *pobject; |
1319 | capsProblem *problem; |
1320 | |
1321 | if (nErr == NULL) return CAPS_NULLVALUE; |
1322 | if (errors == NULL) return CAPS_NULLVALUE; |
1323 | *nErr = 0; |
1324 | *errors = NULL; |
1325 | if (object == NULL) return CAPS_NULLOBJ; |
1326 | if (object->magicnumber != CAPSMAGIC) return CAPS_BADOBJECT; |
1327 | if (object->type != VALUE) return CAPS_BADTYPE; |
1328 | if ((object->subtype != USER) && (object->subtype != PARAMETER)) |
1329 | return CAPS_BADTYPE; |
1330 | if (object->blind == NULL) return CAPS_NULLBLIND; |
1331 | value = (capsValue *) object->blind; |
1332 | status = caps_findProblem(object, CAPS_SETLIMITS, &pobject); |
1333 | if (status != CAPS_SUCCESS) return status; |
1334 | problem = (capsProblem *) pobject->blind; |
1335 | if (problem->dbFlag == 1) return CAPS_READONLYERR; |
1336 | |
1337 | |
1338 | if (problem->stFlag == CAPS_JOURNALERR) return CAPS_JOURNALERR; |
1339 | if (problem->stFlag == 4) { |
1340 | status = caps_jrnlEnd(problem); |
1341 | if (status != CAPS_CLEAN) return CAPS_SUCCESS; |
1342 | } |
1343 | |
1344 | if (limits == NULL) { |
1345 | value->limits.ilims[0] = value->limits.ilims[1] = 0; |
1346 | value->limits.dlims[0] = value->limits.dlims[1] = 0.0; |
1347 | return CAPS_SUCCESS; |
1348 | } |
1349 | if (value->type != vtype) { |
1350 | if (!( ((value->type == Double) || (value->type == DoubleDeriv)) && |
1351 | (vtype == Integer) )) return CAPS_BADTYPE; |
1352 | } |
1353 | |
1354 | status = caps_unitConvertible(units, value->units); |
1355 | if (status != CAPS_SUCCESS) return status; |
1356 | |
1357 | if (value->type == Integer) { |
1358 | if ( units != NULL ) return CAPS_UNITERR; |
1359 | ints = (int *) limits; |
1360 | if (ints[0] >= ints[1]) return CAPS_RANGEERR; |
1361 | if (value->length == 1) { |
1362 | if ((value->vals.integer < ints[0]) || |
1363 | (value->vals.integer > ints[1])) return CAPS_RANGEERR; |
1364 | } else { |
1365 | for (i = 0; i < value->length; i++) |
1366 | if ((value->vals.integers[i] < ints[0]) || |
1367 | (value->vals.integers[i] > ints[1])) return CAPS_RANGEERR; |
1368 | } |
1369 | value->limits.ilims[0] = ints[0]; |
1370 | value->limits.ilims[1] = ints[1]; |
1371 | } else if ((value->type == Double) || (value->type == DoubleDeriv)) { |
1372 | if (vtype == Integer) { |
1373 | ints = (int *) limits; |
1374 | reals[0] = ints[0]; |
1375 | reals[1] = ints[1]; |
1376 | } else { |
1377 | realp = (double *) limits; |
1378 | reals[0] = realp[0]; |
1379 | reals[1] = realp[1]; |
1380 | } |
1381 | if (reals[0] >= reals[1]) return CAPS_RANGEERR; |
1382 | |
1383 | status = caps_convert(2, units, reals, value->units, reals); |
1384 | if (status != CAPS_SUCCESS) return status; |
1385 | |
1386 | if (value->length == 1) { |
1387 | if ((value->vals.real < reals[0]) || |
1388 | (value->vals.real > reals[1])) return CAPS_RANGEERR; |
1389 | } else { |
1390 | for (i = 0; i < value->length; i++) |
1391 | if ((value->vals.reals[i] < reals[0]) || |
1392 | (value->vals.reals[i] > reals[1])) return CAPS_RANGEERR; |
1393 | } |
1394 | value->limits.dlims[0] = reals[0]; |
1395 | value->limits.dlims[1] = reals[1]; |
1396 | } else { |
1397 | return CAPS_BADTYPE; |
1398 | } |
1399 | |
1400 | return CAPS_SUCCESS; |
1401 | } |
1402 | |
1403 | |
1404 | int |
1405 | caps_getValueProps(capsObject *object, int *dim, int *pmtr, |
1406 | enum capsFixed *lfixed, enum capsFixed *sfixed, |
1407 | enum capsNull *nval) |
1408 | { |
1409 | int status, ret; |
1410 | CAPSLONG sNum; |
1411 | capsValue *value; |
1412 | capsObject *pobject; |
1413 | capsProblem *problem; |
1414 | capsJrnl args[5]; |
1415 | |
1416 | if (dim == NULL) return CAPS_NULLVALUE; |
1417 | if (pmtr == NULL) return CAPS_NULLVALUE; |
1418 | if (lfixed == NULL) return CAPS_NULLVALUE; |
1419 | if (sfixed == NULL) return CAPS_NULLVALUE; |
1420 | if (nval == NULL) return CAPS_NULLVALUE; |
1421 | |
1422 | *dim = *pmtr = 0; |
1423 | *lfixed = *sfixed = Fixed; |
1424 | if (object == NULL) return CAPS_NULLOBJ; |
1425 | if (object->magicnumber != CAPSMAGIC) return CAPS_BADOBJECT; |
1426 | if (object->type != VALUE) return CAPS_BADTYPE; |
1427 | if (object->blind == NULL) return CAPS_NULLBLIND; |
1428 | value = (capsValue *) object->blind; |
1429 | status = caps_findProblem(object, CAPS_GETVALUEPROPS, &pobject); |
1430 | if (status != CAPS_SUCCESS) return status; |
1431 | problem = (capsProblem *) pobject->blind; |
1432 | |
1433 | args[0].type = jInteger; |
1434 | args[1].type = jInteger; |
1435 | args[2].type = jInteger; |
1436 | args[3].type = jInteger; |
1437 | args[4].type = jInteger; |
1438 | if (problem->dbFlag == 0) { |
1439 | status = caps_jrnlRead(CAPS_GETVALUEPROPS, problem, object, 5, args, |
1440 | &sNum, &ret); |
1441 | if (status == CAPS_JOURNALERR) return status; |
1442 | if (status == CAPS_JOURNAL) { |
1443 | *dim = args[0].members.integer; |
1444 | *pmtr = args[1].members.integer; |
1445 | *lfixed = args[2].members.integer; |
1446 | *sfixed = args[3].members.integer; |
1447 | *nval = args[4].members.integer; |
1448 | return ret; |
1449 | } |
1450 | } |
1451 | |
1452 | args[0].members.integer = *dim = value->dim; |
1453 | args[1].members.integer = *pmtr = value->gInType; |
1454 | args[2].members.integer = *lfixed = value->lfixed; |
1455 | args[3].members.integer = *sfixed = value->sfixed; |
1456 | args[4].members.integer = *nval = value->nullVal; |
1457 | if (problem->dbFlag == 1) return CAPS_SUCCESS; |
1458 | |
1459 | caps_jrnlWrite(CAPS_GETVALUEPROPS, problem, object, CAPS_SUCCESS, 5, args, |
1460 | problem->sNum, problem->sNum); |
1461 | |
1462 | return CAPS_SUCCESS; |
1463 | } |
1464 | |
1465 | |
1466 | int |
1467 | caps_setValueProps(capsObject *object, int dim, enum capsFixed lfixed, |
1468 | enum capsFixed sfixed, enum capsNull nval, |
1469 | int *nErr, capsErrs **errors) |
1470 | { |
1471 | int status; |
1472 | capsValue *value; |
1473 | capsObject *pobject; |
1474 | capsProblem *problem; |
1475 | |
1476 | if (nErr == NULL) return CAPS_NULLVALUE; |
1477 | if (errors == NULL) return CAPS_NULLVALUE; |
1478 | *nErr = 0; |
1479 | *errors = NULL; |
1480 | if (object == NULL) return CAPS_NULLOBJ; |
1481 | if (object->magicnumber != CAPSMAGIC) return CAPS_BADOBJECT; |
1482 | if (object->type != VALUE) return CAPS_BADTYPE; |
1483 | if ((object->subtype != PARAMETER) && |
1484 | (object->subtype != USER)) return CAPS_BADTYPE; |
1485 | if (object->blind == NULL) return CAPS_NULLBLIND; |
1486 | value = (capsValue *) object->blind; |
1487 | if ((nval == NotAllowed) && |
1488 | (value->nullVal == IsNull)) return CAPS_NULLVALUE; |
1489 | status = caps_findProblem(object, CAPS_SETVALUEPROPS, &pobject); |
1490 | if (status != CAPS_SUCCESS) return status; |
1491 | problem = (capsProblem *) pobject->blind; |
1492 | if (problem->dbFlag == 1) return CAPS_READONLYERR; |
1493 | |
1494 | |
1495 | if (problem->stFlag == CAPS_JOURNALERR) return CAPS_JOURNALERR; |
1496 | if (problem->stFlag == 4) { |
1497 | status = caps_jrnlEnd(problem); |
1498 | if (status != CAPS_CLEAN) return CAPS_SUCCESS; |
1499 | } |
1500 | |
1501 | |
1502 | if (dim == 0) { |
1503 | if ((value->ncol != 1) || (value->nrow != 1)) return CAPS_SHAPEERR; |
1504 | } else if (dim == 1) { |
1505 | if ((value->ncol > 1) && (value->nrow > 1)) return CAPS_SHAPEERR; |
1506 | } else if (dim != 2) { |
1507 | return CAPS_RANGEERR; |
1508 | } |
1509 | |
1510 | value->dim = dim; |
1511 | value->lfixed = lfixed; |
1512 | value->sfixed = sfixed; |
1513 | if ((nval == IsNull) && (value->nullVal == NotNull)) return CAPS_SUCCESS; |
1514 | if ((nval == NotNull) && (value->nullVal == IsNull)) return CAPS_SUCCESS; |
1515 | value->nullVal = nval; |
1516 | |
1517 | return CAPS_SUCCESS; |
1518 | } |
1519 | |
1520 | |
1521 | int |
1522 | caps_convertValue(capsObject *object, double inp, const char *units, |
1523 | double *outp) |
1524 | { |
1525 | int status, ret; |
1526 | CAPSLONG sNum; |
1527 | capsObject *pobject; |
1528 | capsValue *value; |
1529 | capsProblem *problem; |
1530 | capsJrnl args[1]; |
1531 | |
1532 | if (object == NULL) return CAPS_NULLOBJ; |
1533 | if (object->magicnumber != CAPSMAGIC) return CAPS_BADOBJECT; |
1534 | if (object->type != VALUE) return CAPS_BADTYPE; |
1535 | if (object->blind == NULL) return CAPS_NULLBLIND; |
1536 | value = (capsValue *) object->blind; |
1537 | if (units == NULL) return CAPS_UNITERR; |
1538 | if (value->units == NULL) return CAPS_UNITERR; |
1539 | status = caps_findProblem(object, CAPS_CONVERTVALUE, &pobject); |
1540 | if (status != CAPS_SUCCESS) return status; |
1541 | problem = (capsProblem *) pobject->blind; |
1542 | if (problem->dbFlag == 1) return CAPS_READONLYERR; |
1543 | |
1544 | args[0].type = jDouble; |
1545 | status = caps_jrnlRead(CAPS_CONVERTVALUE, problem, object, 1, args, |
1546 | &sNum, &ret); |
1547 | if (status == CAPS_JOURNALERR) return status; |
1548 | if (status == CAPS_JOURNAL) { |
1549 | *outp = args[0].members.real; |
1550 | return ret; |
1551 | } |
1552 | |
1553 | ret = caps_convert(1, units, &inp, value->units, outp); |
1554 | args[0].members.real = *outp; |
1555 | caps_jrnlWrite(CAPS_CONVERTVALUE, problem, object, ret, 1, args, |
1556 | problem->sNum, problem->sNum); |
1557 | |
1558 | return ret; |
1559 | } |
1560 | |
1561 | |
1562 | int |
1563 | caps_dupValues(capsValue *val1, capsValue *val2) |
1564 | { |
1565 | int i, j, len, status; |
1566 | |
1567 | |
1568 | val2->type = val1->type; |
1569 | val2->length = val1->length; |
1570 | val2->dim = val1->dim; |
1571 | val2->nrow = val1->nrow; |
1572 | val2->ncol = val1->ncol; |
1573 | val2->lfixed = val1->lfixed; |
1574 | val2->sfixed = val1->sfixed; |
1575 | val2->nullVal = val1->nullVal; |
1576 | val2->index = val1->index; |
1577 | val2->pIndex = val1->pIndex; |
1578 | val2->gInType = val1->gInType; |
1579 | val2->partial = NULL; |
1580 | val2->nderiv = 0; |
1581 | val2->derivs = NULL; |
1582 | if (val1->partial != NULL) { |
1583 | val2->partial = (int *) EG_alloc(val1->length*sizeof(int)); |
1584 | if (val2->partial == NULL) return EGADS_MALLOC; |
1585 | for (i = 0; i < val1->length; i++) val2->partial[i] = val1->partial[i]; |
1586 | } |
1587 | if ((val1->nderiv != 0) && (val1->derivs != NULL)) { |
1588 | val2->derivs = (capsDeriv *) EG_alloc(val1->nderiv*sizeof(capsDeriv)); |
1589 | if (val2->derivs == NULL) return EGADS_MALLOC; |
1590 | for (i = 0; i < val1->nderiv; i++) { |
1591 | val2->derivs[i].name = EG_strdup(val1->derivs[i].name); |
1592 | val2->derivs[i].len_wrt = val1->derivs[i].len_wrt; |
1593 | val2->derivs[i].deriv = NULL; |
1594 | } |
1595 | for (i = 0; i < val1->nderiv; i++) { |
1596 | if (val2->derivs[i].name == NULL) return EGADS_MALLOC; |
1597 | val2->derivs[i].deriv = (double *) EG_alloc( |
1598 | val1->length*val1->derivs[i].len_wrt*sizeof(double)); |
1599 | if (val2->derivs[i].deriv == NULL) return EGADS_MALLOC; |
1600 | for (j = 0; j < val1->length*val1->derivs[i].len_wrt; j++) |
1601 | val2->derivs[i].deriv[j] = val1->derivs[i].deriv[j]; |
1602 | } |
1603 | val2->nderiv = val1->nderiv; |
1604 | } |
1605 | |
1606 | |
1607 | switch (val1->type) { |
1608 | case Boolean: |
1609 | if (val1->length == 1) { |
1610 | val2->vals.integer = val1->vals.integer; |
1611 | } else { |
1612 | val2->vals.integers = NULL; |
1613 | if (val1->vals.integers == NULL) break; |
1614 | val2->vals.integers = (int *) EG_alloc(val1->length*sizeof(int)); |
1615 | if (val2->vals.integers == NULL) return EGADS_MALLOC; |
1616 | for (i = 0; i < val1->length; i++) |
1617 | val2->vals.integers[i] = val1->vals.integers[i]; |
1618 | } |
1619 | break; |
1620 | |
1621 | case Integer: |
1622 | if (val1->length == 1) { |
1623 | val2->vals.integer = val1->vals.integer; |
1624 | } else { |
1625 | val2->vals.integers = NULL; |
1626 | if (val1->vals.integers != NULL) { |
1627 | val2->vals.integers = (int *) EG_alloc(val1->length*sizeof(int)); |
1628 | if (val2->vals.integers == NULL) return EGADS_MALLOC; |
1629 | for (i = 0; i < val1->length; i++) |
1630 | val2->vals.integers[i] = val1->vals.integers[i]; |
1631 | } |
1632 | } |
1633 | val2->limits.ilims[0] = val1->limits.ilims[0]; |
1634 | val2->limits.ilims[1] = val1->limits.ilims[1]; |
1635 | break; |
1636 | |
1637 | case Double: |
1638 | if (val1->length == 1) { |
1639 | val2->vals.real = val1->vals.real; |
1640 | } else { |
1641 | val2->vals.reals = NULL; |
1642 | if (val1->vals.reals != NULL) { |
1643 | val2->vals.reals = (double *) EG_alloc(val1->length*sizeof(double)); |
1644 | if (val2->vals.reals == NULL) return EGADS_MALLOC; |
1645 | for (i = 0; i < val1->length; i++) |
1646 | val2->vals.reals[i] = val1->vals.reals[i]; |
1647 | } |
1648 | } |
1649 | val2->limits.dlims[0] = val1->limits.dlims[0]; |
1650 | val2->limits.dlims[1] = val1->limits.dlims[1]; |
1651 | break; |
1652 | |
1653 | case String: |
1654 | val2->vals.string = NULL; |
1655 | if ((val1->vals.string != NULL) && (strlen(val1->vals.string) > 0)) { |
1656 | j = strlen(val1->vals.string) + 1; |
1657 | val2->vals.string = (char *) EG_alloc(j*sizeof(char)); |
1658 | if (val2->vals.string == NULL) return EGADS_MALLOC; |
1659 | for (i = 0; i < j; i++) |
1660 | val2->vals.string[i] = val1->vals.string[i]; |
1661 | } |
1662 | break; |
1663 | |
1664 | case Tuple: |
1665 | val2->vals.tuple = NULL; |
1666 | if (val1->vals.tuple == NULL) |
1667 | break; |
1668 | status = caps_makeTuple(val1->length, &val2->vals.tuple); |
1669 | if (status != CAPS_SUCCESS) return status; |
1670 | if (val2->vals.tuple == NULL) return EGADS_MALLOC; |
1671 | for (i = 0; i < val1->length; i++) { |
1672 | val2->vals.tuple[i].name = EG_strdup(val1->vals.tuple[i].name); |
1673 | val2->vals.tuple[i].value = EG_strdup(val1->vals.tuple[i].value); |
1674 | if ((val1->vals.tuple[i].name != NULL) && |
1675 | (val2->vals.tuple[i].name == NULL)) return EGADS_MALLOC; |
1676 | if ((val1->vals.tuple[i].value != NULL) && |
1677 | (val2->vals.tuple[i].value == NULL)) return EGADS_MALLOC; |
1678 | } |
1679 | break; |
1680 | |
1681 | case Pointer: |
1682 | case PointerMesh: |
1683 | val2->vals.AIMptr = val1->vals.AIMptr; |
1684 | |
1685 | } |
1686 | |
1687 | |
1688 | val2->units = NULL; |
1689 | if (val1->units != NULL) { |
1690 | len = strlen(val1->units) + 1; |
1691 | val2->units = (char *) EG_alloc(len*sizeof(char)); |
1692 | if (val2->units == NULL) return EGADS_MALLOC; |
1693 | for (i = 0; i < len; i++) val2->units[i] = val1->units[i]; |
1694 | } |
1695 | |
1696 | |
1697 | val2->meshWriter = NULL; |
1698 | if (val1->meshWriter != NULL) { |
1699 | len = strlen(val1->meshWriter) + 1; |
1700 | val2->meshWriter = (char *) EG_alloc(len*sizeof(char)); |
1701 | if (val2->meshWriter == NULL) return EGADS_MALLOC; |
1702 | for (i = 0; i < len; i++) val2->meshWriter[i] = val1->meshWriter[i]; |
1703 | } |
1704 | |
1705 | |
1706 | val2->link = val1->link; |
1707 | val2->linkMethod = val1->linkMethod; |
1708 | |
1709 | return CAPS_SUCCESS; |
1710 | } |
1711 | |
1712 | |
1713 | static int |
1714 | caps_compatValues(capsValue *val1, capsValue *val2, capsProblem *problem) |
1715 | { |
1716 | int status; |
1717 | ut_unit *utunit1, *utunit2; |
1718 | |
1719 | |
1720 | if ((val1->units != NULL) && (val2->units == NULL)) return CAPS_UNITERR; |
1721 | if ((val1->units == NULL) && (val2->units != NULL)) return CAPS_UNITERR; |
1722 | if ((val1->units != NULL) && (val2->units != NULL)) { |
1723 | if (strcmp(val1->units, val2->units) != 0) { |
1724 | utunit1 = ut_parse((ut_system *) problem->utsystem, val1->units, UT_ASCII); |
1725 | utunit2 = ut_parse((ut_system *) problem->utsystem, val2->units, UT_ASCII); |
1726 | status = ut_are_convertible(utunit1, utunit2); |
1727 | ut_free(utunit1); |
1728 | ut_free(utunit2); |
1729 | if (status == 0) return CAPS_UNITERR; |
1730 | } |
1731 | } |
1732 | |
1733 | |
1734 | if (val1->type != val2->type) return CAPS_BADTYPE; |
1735 | |
1736 | |
1737 | if (val2->lfixed == Fixed) |
1738 | if (val1->length != val2->length) return CAPS_SHAPEERR; |
1739 | if (val2->sfixed == Fixed) { |
1740 | if (val2->dim > val1->dim) return CAPS_SHAPEERR; |
1741 | if (val2->nrow != val1->nrow) return CAPS_SHAPEERR; |
1742 | if (val2->ncol != val1->ncol) return CAPS_SHAPEERR; |
1743 | } else { |
1744 | if (val2->dim == Scalar) { |
1745 | if (val1->length != 1) return CAPS_SHAPEERR; |
1746 | } else if (val2->dim == Vector) { |
1747 | if ((val1->ncol != 1) && (val1->nrow != 1)) return CAPS_SHAPEERR; |
1748 | } |
1749 | } |
1750 | |
1751 | return CAPS_SUCCESS; |
1752 | } |
1753 | |
1754 | |
1755 | int |
1756 | caps_transferValueX(capsObject *source, enum capstMethod method, |
1757 | capsObject *target, int *nErr, capsErrs **errors) |
1758 | { |
1759 | int status, vlen, rank, ncol, nrow; |
1760 | char *iunits; |
1761 | double *ireals; |
1762 | const void *data; |
1763 | const int *partial; |
1764 | const char *units; |
1765 | const double *reals; |
1766 | capsValue *value, *sval; |
1767 | capsProblem *problem; |
1768 | capsObject *pobject, *last; |
1769 | enum capsvType vtype; |
1770 | |
1771 | if (nErr == NULL) return CAPS_NULLVALUE; |
1772 | if (errors == NULL) return CAPS_NULLVALUE; |
1773 | *nErr = 0; |
1774 | *errors = NULL; |
1775 | if (source == NULL) return CAPS_NULLOBJ; |
1776 | if (source->magicnumber != CAPSMAGIC) return CAPS_BADOBJECT; |
1777 | if ((source->type != VALUE) && |
1778 | (source->type != DATASET)) return CAPS_BADTYPE; |
1779 | if (source->blind == NULL) return CAPS_NULLBLIND; |
1780 | if (target == NULL) return CAPS_NULLOBJ; |
1781 | if (target->magicnumber != CAPSMAGIC) return CAPS_BADOBJECT; |
1782 | if (target->type != VALUE) return CAPS_BADTYPE; |
1783 | if (target->subtype == GEOMETRYOUT) return CAPS_BADTYPE; |
1784 | if (target->subtype == ANALYSISOUT) return CAPS_BADTYPE; |
1785 | if (target->blind == NULL) return CAPS_NULLBLIND; |
1786 | value = (capsValue *) target->blind; |
1787 | status = caps_findProblem(target, 9999, &pobject); |
1788 | if (status != CAPS_SUCCESS) return status; |
1789 | problem = (capsProblem *) pobject->blind; |
1790 | |
1791 | if (source->type == VALUE) { |
1792 | |
1793 | status = caps_getValuX(source, &vtype, &nrow, &ncol, &data, &partial, |
1794 | &units, nErr, errors); |
1795 | if (status != CAPS_SUCCESS) return status; |
1796 | last = value->link; |
1797 | value->link = NULL; |
1798 | status = caps_setValuX(target, vtype, nrow, ncol, data, partial, units, |
1799 | nErr, errors); |
1800 | value->link = last; |
1801 | if (status != CAPS_SUCCESS) return status; |
1802 | |
1803 | } else { |
1804 | |
1805 | if (method == Copy) { |
1806 | |
1807 | sval = (capsValue *) source->blind; |
1808 | if (sval->nullVal == IsNull) return CAPS_NULLVALUE; |
1809 | status = caps_getDataX(source, &vlen, &rank, &reals, &units); |
1810 | if (status != CAPS_SUCCESS) return status; |
1811 | |
1812 | status = caps_makeVal(Double, vlen*rank, reals, &sval); |
1813 | if (status != CAPS_SUCCESS) return status; |
1814 | sval->units = (char *) units; |
1815 | sval->ncol = vlen; |
1816 | sval->nrow = rank; |
1817 | if (rank != 1) sval->dim = Array2D; |
1818 | status = caps_compatValues(sval, value, problem); |
1819 | if (status != CAPS_SUCCESS) { |
1820 | if (sval->length > 1) EG_free(sval->vals.reals); |
1821 | EG_free(sval); |
1822 | return status; |
1823 | } |
1824 | value->ncol = vlen; |
1825 | value->nrow = rank; |
1826 | if (rank != 1) value->dim = Array2D; |
1827 | last = value->link; |
1828 | value->link = NULL; |
1829 | status = caps_setValuX(target, Double, rank, vlen, reals, NULL, units, |
1830 | nErr, errors); |
1831 | value->link = last; |
1832 | if (sval->length > 1) EG_free(sval->vals.reals); |
1833 | EG_free(sval); |
1834 | if (status != CAPS_SUCCESS) return status; |
1835 | |
1836 | } else { |
1837 | |
1838 | if (source->subtype == UNCONNECTED) return CAPS_BADMETHOD; |
1839 | |
1840 | |
1841 | status = caps_integrateData(source, method, &rank, &ireals, &iunits); |
1842 | if (status != CAPS_SUCCESS) return status; |
1843 | status = caps_makeVal(Double, rank, ireals, &sval); |
1844 | if (status != CAPS_SUCCESS) { |
1845 | EG_free(ireals); |
1846 | EG_free(iunits); |
1847 | return status; |
1848 | } |
1849 | sval->units = iunits; |
1850 | sval->nrow = rank; |
1851 | sval->ncol = 1; |
1852 | status = caps_compatValues(sval, value, problem); |
1853 | EG_free(sval->units); |
1854 | if (sval->length > 1) EG_free(sval->vals.reals); |
1855 | EG_free(sval); |
1856 | if (status != CAPS_SUCCESS) { |
1857 | EG_free(ireals); |
1858 | return status; |
1859 | } |
1860 | last = value->link; |
1861 | value->link = NULL; |
1862 | status = caps_setValuX(target, Double, rank, 1, ireals, NULL, iunits, |
1863 | nErr, errors); |
1864 | value->link = last; |
1865 | EG_free(ireals); |
1866 | if (status != CAPS_SUCCESS) return status; |
1867 | } |
1868 | |
1869 | } |
1870 | |
1871 | |
1872 | caps_freeOwner(&target->last); |
1873 | problem->sNum += 1; |
1874 | target->last.sNum = problem->sNum; |
1875 | status = caps_addHistory(target, problem); |
1876 | if (status != CAPS_SUCCESS) |
1877 | printf(" CAPS Warning: caps_addHistory = %d (caps_transferValues)\n", |
1878 | status); |
1879 | |
1880 | status = caps_writeValueObj(problem, target); |
1881 | if (status != CAPS_SUCCESS) |
1882 | printf(" CAPS Warning: caps_writeValueObj = %d (caps_transferValues)\n", |
1883 | status); |
1884 | |
1885 | |
1886 | value->linkMethod = Copy; |
1887 | value->link = NULL; |
1888 | |
1889 | return CAPS_SUCCESS; |
1890 | } |
1891 | |
1892 | |
1893 | int |
1894 | caps_transferValues(capsObject *source, enum capstMethod method, |
1895 | capsObject *target, int *nErr, capsErrs **errors) |
1896 | { |
1897 | int stat, ret; |
1898 | CAPSLONG sNum; |
1899 | capsObject *pobject; |
1900 | capsProblem *problem; |
1901 | capsJrnl args[2]; |
1902 | |
1903 | if (nErr == NULL) return CAPS_NULLVALUE; |
1904 | if (errors == NULL) return CAPS_NULLVALUE; |
1905 | *nErr = 0; |
1906 | *errors = NULL; |
1907 | if (source == NULL) return CAPS_NULLOBJ; |
1908 | if (source->magicnumber != CAPSMAGIC) return CAPS_BADOBJECT; |
1909 | if ((source->type != VALUE) && |
1910 | (source->type != DATASET)) return CAPS_BADTYPE; |
1911 | if (source->blind == NULL) return CAPS_NULLBLIND; |
1912 | if (target == NULL) return CAPS_NULLOBJ; |
1913 | if (target->magicnumber != CAPSMAGIC) return CAPS_BADOBJECT; |
1914 | if (target->type != VALUE) return CAPS_BADTYPE; |
1915 | if (target->subtype == GEOMETRYOUT) return CAPS_BADTYPE; |
1916 | if (target->subtype == ANALYSISOUT) return CAPS_BADTYPE; |
1917 | if (target->blind == NULL) return CAPS_NULLBLIND; |
1918 | stat = caps_findProblem(target, CAPS_TRANSFERVALUES, &pobject); |
1919 | if (stat != CAPS_SUCCESS) return stat; |
1920 | problem = (capsProblem *) pobject->blind; |
1921 | if (problem->dbFlag == 1) return CAPS_READONLYERR; |
1922 | |
1923 | args[0].type = jInteger; |
1924 | args[1].type = jErr; |
1925 | stat = caps_jrnlRead(CAPS_TRANSFERVALUES, problem, target, 2, args, |
1926 | &sNum, &ret); |
1927 | if (stat == CAPS_JOURNALERR) return stat; |
1928 | if (stat == CAPS_JOURNAL) { |
1929 | *nErr = args[0].members.integer; |
1930 | *errors = args[1].members.errs; |
1931 | return ret; |
1932 | } |
1933 | |
1934 | if (ret == CAPS_SUCCESS) { |
1935 | ret = caps_transferValueX(source, method, target, nErr, errors); |
1936 | *nErr = 0; |
1937 | if (*errors != NULL) *nErr = (*errors)->nError; |
1938 | } |
1939 | args[0].members.integer = *nErr; |
1940 | args[1].members.errs = *errors; |
1941 | caps_jrnlWrite(CAPS_TRANSFERVALUES, problem, target, ret, 2, args, sNum, |
1942 | problem->sNum); |
1943 | |
1944 | return ret; |
1945 | } |
1946 | |
1947 | |
1948 | int |
1949 | caps_linkValue( capsObject *link, enum capstMethod method, |
1950 | capsObject *target, int *nErr, capsErrs **errors) |
1951 | { |
1952 | int status, rank, vlen; |
1953 | const double *reals; |
1954 | const char *units; |
1955 | capsValue *value, *sval; |
1956 | capsObject *source, *pobject; |
1957 | capsProblem *problem; |
1958 | |
1959 | if (nErr == NULL) return CAPS_NULLVALUE; |
1960 | if (errors == NULL) return CAPS_NULLVALUE; |
1961 | *nErr = 0; |
1962 | *errors = NULL; |
1963 | if (target == NULL) return CAPS_NULLOBJ; |
1964 | if (target->magicnumber != CAPSMAGIC) return CAPS_BADOBJECT; |
1965 | if (target->type != VALUE) return CAPS_BADTYPE; |
1966 | if (target->subtype == GEOMETRYOUT) return CAPS_BADTYPE; |
1967 | if (target->subtype == ANALYSISOUT) return CAPS_BADTYPE; |
1968 | if (target->blind == NULL) return CAPS_NULLBLIND; |
1969 | value = (capsValue *) target->blind; |
1970 | status = caps_findProblem(target, CAPS_LINKVALUE, &pobject); |
1971 | if (status != CAPS_SUCCESS) return status; |
1972 | problem = (capsProblem *) pobject->blind; |
1973 | if (problem->dbFlag == 1) return CAPS_READONLYERR; |
1974 | |
1975 | if (target->type == VALUE) { |
1976 | if (target->subtype == GEOMETRYIN) { |
1977 | if (pobject->subtype == STATIC) return CAPS_READONLYERR; |
1978 | if (method != Copy) return CAPS_BADMETHOD; |
1979 | } |
1980 | } |
1981 | |
1982 | |
1983 | if (problem->stFlag == CAPS_JOURNALERR) return CAPS_JOURNALERR; |
1984 | if (problem->stFlag == 4) { |
1985 | status = caps_jrnlEnd(problem); |
1986 | if (status != CAPS_CLEAN) return CAPS_SUCCESS; |
1987 | } |
1988 | |
1989 | if (link == NULL) { |
1990 | |
1991 | caps_freeOwner(&target->last); |
1992 | problem->sNum += 1; |
1993 | target->last.sNum = problem->sNum; |
1994 | status = caps_addHistory(target, problem); |
1995 | if (status != CAPS_SUCCESS) |
1996 | printf(" CAPS Warning: caps_addHistory = %d (caps_linkValue)\n", status); |
1997 | |
1998 | value->linkMethod = Copy; |
1999 | value->link = NULL; |
2000 | status = caps_writeSerialNum(problem); |
2001 | if (status != CAPS_SUCCESS) |
2002 | printf(" CAPS Warning: caps_writePSerialNum = %d (caps_linkValue)\n", |
2003 | status); |
2004 | if (target->type == VALUE) { |
2005 | status = caps_writeValueObj(problem, target); |
2006 | if (status != CAPS_SUCCESS) |
2007 | printf(" CAPS Warning: caps_writeValueObj = %d (caps_linkValue)\n", |
2008 | status); |
2009 | } |
2010 | return CAPS_SUCCESS; |
2011 | } |
2012 | |
2013 | |
2014 | if (link->magicnumber != CAPSMAGIC) return CAPS_BADOBJECT; |
2015 | if (link->type == VALUE) { |
2016 | |
2017 | if (target->subtype == USER) return CAPS_BADTYPE; |
2018 | if (method != Copy) return CAPS_BADMETHOD; |
2019 | source = link; |
2020 | do { |
2021 | if (source->magicnumber != CAPSMAGIC) return CAPS_BADOBJECT; |
2022 | if (source->type != VALUE) return CAPS_BADTYPE; |
2023 | if (source->blind == NULL) return CAPS_NULLBLIND; |
2024 | sval = (capsValue *) source->blind; |
2025 | if (sval->link == target) return CAPS_CIRCULARLINK; |
2026 | source = sval->link; |
2027 | } while (sval->link != NULL); |
2028 | |
2029 | if ((sval->type == Pointer) || (sval->type == PointerMesh)) { |
2030 | |
2031 | if ((sval->units != NULL) || (value->units != NULL)) { |
2032 | if (sval->units == NULL) return CAPS_UNITERR; |
2033 | if (value->units == NULL) return CAPS_UNITERR; |
2034 | if (strcmp(value->units, sval->units) != 0) return CAPS_UNITERR; |
2035 | } |
2036 | } else { |
2037 | |
2038 | status = caps_compatValues(sval, value, problem); |
2039 | if (status != CAPS_SUCCESS) return status; |
2040 | } |
2041 | |
2042 | } else if (link->type == DATASET) { |
2043 | |
2044 | status = caps_getDataX(link, &vlen, &rank, &reals, &units); |
2045 | if (status != CAPS_SUCCESS) return status; |
2046 | |
2047 | |
2048 | status = caps_makeVal(Double, vlen*rank, reals, &sval); |
2049 | if (status != CAPS_SUCCESS) return status; |
2050 | sval->units = (char *) units; |
2051 | if (rank != 1) { |
2052 | sval->dim = Array2D; |
2053 | sval->nrow = rank; |
2054 | sval->ncol = vlen; |
2055 | } |
2056 | status = caps_compatValues(sval, value, problem); |
2057 | if (sval->length > 1) EG_free(sval->vals.reals); |
2058 | EG_free(sval); |
2059 | if (status != CAPS_SUCCESS) return status; |
2060 | |
2061 | } else { |
2062 | return CAPS_BADTYPE; |
2063 | } |
2064 | |
2065 | |
2066 | value->linkMethod = method; |
2067 | value->link = link; |
2068 | |
2069 | |
2070 | if (target->subtype == ANALYSISIN) { |
2071 | status = caps_circularAutoExecs(target, NULL); |
2072 | if (status != CAPS_SUCCESS) { |
2073 | value->linkMethod = Copy; |
2074 | value->link = NULL; |
2075 | return CAPS_CIRCULARLINK; |
2076 | } |
2077 | } |
2078 | |
2079 | caps_freeOwner(&target->last); |
2080 | problem->sNum += 1; |
2081 | target->last.sNum = problem->sNum; |
2082 | status = caps_addHistory(target, problem); |
2083 | if (status != CAPS_SUCCESS) |
2084 | printf(" CAPS Warning: caps_addHistory = %d (caps_linkValue)\n", status); |
2085 | status = caps_writeSerialNum(problem); |
2086 | if (status != CAPS_SUCCESS) |
2087 | printf(" CAPS Warning: caps_writeSerialNum = %d (caps_linkValue)!\n", |
2088 | status); |
2089 | status = caps_writeValueObj(problem, target); |
2090 | if (status != CAPS_SUCCESS) |
2091 | printf(" CAPS Warning: caps_writeValueObj = %d (caps_linkValue)!\n", |
2092 | status); |
2093 | |
2094 | return status; |
2095 | } |
2096 | |
2097 | |
2098 | int |
2099 | caps_hasDeriv(capsObject *vobj, int *nderiv, char ***names, |
2100 | int *nErr, capsErrs **errors) |
2101 | { |
2102 | int i, status, ret; |
2103 | char **namex, **namey; |
2104 | CAPSLONG sNum; |
2105 | capsValue *value; |
2106 | capsObject *pobject, *source, *last; |
2107 | capsProblem *problem; |
2108 | capsJrnl args[1]; |
2109 | |
2110 | *nErr = 0; |
2111 | *errors = NULL; |
2112 | *nderiv = 0; |
2113 | *names = NULL; |
2114 | if (vobj == NULL) return CAPS_NULLOBJ; |
2115 | if (vobj->magicnumber != CAPSMAGIC) return CAPS_BADOBJECT; |
2116 | if (vobj->type != VALUE) return CAPS_BADTYPE; |
2117 | if (vobj->blind == NULL) return CAPS_NULLBLIND; |
2118 | status = caps_findProblem(vobj, CAPS_HASDERIV, &pobject); |
2119 | if (status != CAPS_SUCCESS) return status; |
2120 | problem = (capsProblem *) pobject->blind; |
2121 | |
2122 | args[0].type = jStrings; |
2123 | if (problem->dbFlag == 0) { |
2124 | status = caps_jrnlRead(CAPS_HASDERIV, problem, vobj, 1, args, &sNum, |
2125 | &ret); |
2126 | if (status == CAPS_JOURNALERR) return status; |
2127 | if (status == CAPS_JOURNAL) { |
2128 | if (ret == CAPS_SUCCESS) { |
2129 | *nderiv = args[0].num; |
2130 | namey = args[0].members.strings; |
2131 | namex = (char **) EG_alloc(args[0].num*sizeof(char *)); |
2132 | if (namex == NULL) { |
2133 | ret = EGADS_MALLOC; |
2134 | } else { |
2135 | for (i = 0; i < args[0].num; i++) namex[i] = namey[i]; |
2136 | } |
2137 | *names = namex; |
2138 | } |
2139 | return ret; |
2140 | } |
2141 | } |
2142 | |
2143 | args[0].num = 0; |
2144 | args[0].members.strings = NULL; |
2145 | source = vobj; |
2146 | do { |
2147 | if (source->magicnumber != CAPSMAGIC) { |
2148 | status = CAPS_BADOBJECT; |
2149 | goto herr; |
2150 | } |
2151 | if (source->type != VALUE) { |
2152 | status = CAPS_BADTYPE; |
2153 | goto herr; |
2154 | } |
2155 | if (source->blind == NULL) { |
2156 | status = CAPS_NULLBLIND; |
2157 | goto herr; |
2158 | } |
2159 | value = (capsValue *) source->blind; |
2160 | if (value->link == vobj) { |
2161 | status = CAPS_CIRCULARLINK; |
2162 | goto herr; |
2163 | } |
2164 | last = source; |
2165 | source = value->link; |
2166 | } while (value->link != NULL); |
2167 | |
2168 | |
2169 | if (problem->dbFlag == 0) |
2170 | if (last->subtype == ANALYSISOUT) { |
2171 | status = caps_updateAnalysisOut(last, CAPS_HASDERIV, nErr, errors); |
2172 | if (status != CAPS_SUCCESS) goto herr; |
2173 | } else if (vobj->subtype == GEOMETRYOUT) { |
2174 | |
2175 | status = caps_build(pobject, nErr, errors); |
2176 | if ((status != CAPS_SUCCESS) && (status != CAPS_CLEAN)) goto herr; |
2177 | } |
2178 | |
2179 | |
2180 | value = (capsValue *) vobj->blind; |
2181 | if (value->type != DoubleDeriv) { |
2182 | status = CAPS_BADTYPE; |
2183 | goto herr; |
2184 | } |
2185 | if (value->nderiv == 0) { |
2186 | status = CAPS_SUCCESS; |
2187 | goto herr; |
2188 | } |
2189 | |
2190 | status = EGADS_MALLOC; |
2191 | namex = (char **) EG_alloc(value->nderiv*sizeof(char *)); |
2192 | if (namex != NULL) { |
2193 | status = CAPS_SUCCESS; |
2194 | for (i = 0; i < value->nderiv; i++) namex[i] = value->derivs[i].name; |
2195 | args[0].num = *nderiv = value->nderiv; |
2196 | args[0].members.strings = *names = namex; |
2197 | } |
2198 | |
2199 | herr: |
2200 | if (problem->dbFlag == 0) |
2201 | caps_jrnlWrite(CAPS_HASDERIV, problem, vobj, status, 1, args, problem->sNum, |
2202 | problem->sNum); |
2203 | |
2204 | return status; |
2205 | } |
2206 | |
2207 | |
2208 | static int |
2209 | caps_registerGIN(capsProblem *problem, const char *fullname) |
2210 | { |
2211 | int i, j, i1, i2, len, len_wrt, index, irow, icol; |
2212 | char name[MAX_NAME_LEN]; |
2213 | capsValue *value, *vout; |
2214 | capsRegGIN *regGIN; |
2215 | capsDeriv *derivs; |
2216 | |
2217 | len = strlen(fullname); |
2218 | irow = icol = 0; |
2219 | for (i = 0; i < len; i++) { |
2220 | name[i] = fullname[i]; |
2221 | if (fullname[i] == '[') break; |
2222 | } |
2223 | name[i] = '\0'; |
2224 | i1 = i2 = 0; |
2225 | if (i != len) { |
2226 | for (j = i+1; j < len; j++) |
2227 | if (fullname[j] == ',') break; |
2228 | if (j == len) { |
2229 | sscanf(&fullname[i+1], "%d", &i1); |
2230 | } else { |
2231 | sscanf(&fullname[i+1], "%d,%d", &i1, &i2); |
2232 | } |
2233 | } |
2234 | |
2235 | for (index = 1; index <= problem->nGeomIn; index++) |
2236 | if (strcmp(problem->geomIn[index-1]->name,name) == 0) break; |
2237 | if (index > problem->nGeomIn) { |
2238 | printf(" CAPS Error: Object Not Found: %s (caps_getDeriv)!\n", name); |
2239 | return CAPS_NOTFOUND; |
2240 | } |
2241 | value = (capsValue *) problem->geomIn[index-1]->blind; |
2242 | if (value == NULL) { |
2243 | printf(" CAPS Error: Object: %s has NULL pointer (caps_getDeriv)!\n", name); |
2244 | return CAPS_NULLOBJ; |
2245 | } |
2246 | |
2247 | if (i1 > 0) { |
2248 | if ((value->nrow == 1) && (value->ncol == 1)) { |
2249 | printf(" CAPS Error: Object: %s has no index (caps_getDeriv)!\n", name); |
2250 | return CAPS_BADINDEX; |
2251 | } |
2252 | if (((i1 > 0) && (i2 <= 0)) || |
2253 | ((i1 <= 0) && (i2 > 0))) { |
2254 | printf(" CAPS Error: Object: both indices in %s must be positive (caps_getDeriv)!\n", |
2255 | fullname); |
2256 | return CAPS_BADINDEX; |
2257 | } |
2258 | if (i2 != 0) { |
2259 | irow = i1; |
2260 | icol = i2; |
2261 | } else { |
2262 | if (value->nrow == 1) { |
2263 | irow = 1; |
2264 | icol = i1; |
2265 | } else { |
2266 | irow = i1; |
2267 | icol = 1; |
2268 | } |
2269 | } |
2270 | if ((irow < 1) || (irow > value->nrow)) { |
2271 | printf(" CAPS Error: Object: %s irow = %d [1-%d] (caps_getDeriv)!\n", |
2272 | name, irow, value->nrow); |
2273 | return CAPS_BADINDEX; |
2274 | } |
2275 | if ((icol < 1) || (icol > value->ncol)) { |
2276 | printf(" CAPS Error: Object: %s icol = %d [1-%d] (caps_getDeriv)!\n", |
2277 | name, icol, value->ncol); |
2278 | return CAPS_BADINDEX; |
2279 | } |
2280 | } |
2281 | |
2282 | |
2283 | for (i = 0; i < problem->nRegGIN; i++) |
2284 | if ((problem->regGIN[i].index == index) && |
2285 | (problem->regGIN[i].irow == irow) && |
2286 | (problem->regGIN[i].icol == icol)) return CAPS_SUCCESS; |
2287 | |
2288 | |
2289 | len = problem->nRegGIN + 1; |
2290 | regGIN = (capsRegGIN *) EG_reall(problem->regGIN, len*sizeof(capsRegGIN)); |
2291 | if (regGIN == NULL) { |
2292 | printf(" CAPS Error: Cant ReAlloc registry for %s (caps_getDeriv)!\n", |
2293 | fullname); |
2294 | return EGADS_MALLOC; |
2295 | } |
2296 | problem->regGIN = regGIN; |
2297 | |
2298 | len_wrt = 1; |
2299 | if (irow == 0 && icol == 0) len_wrt = value->length; |
2300 | |
2301 | for (i = 0; i < problem->nGeomOut; i++) { |
2302 | if (problem->geomOut[i] == NULL) continue; |
2303 | if (problem->geomOut[i]->magicnumber != CAPSMAGIC) continue; |
2304 | if (problem->geomOut[i]->blind == NULL) continue; |
2305 | vout = (capsValue *) problem->geomOut[i]->blind; |
2306 | |
2307 | derivs = (capsDeriv *) EG_reall(vout->derivs, len*sizeof(capsDeriv)); |
2308 | if (derivs == NULL) { |
2309 | printf(" CAPS Error: Cant Malloc dots for %s (caps_getDeriv)!\n", |
2310 | problem->geomOut[i]->name); |
2311 | return EGADS_MALLOC; |
2312 | } |
2313 | vout->derivs = derivs; |
2314 | |
2315 | vout->derivs[len-1].name = NULL; |
2316 | vout->derivs[len-1].len_wrt = len_wrt; |
2317 | vout->derivs[len-1].deriv = NULL; |
2318 | vout->nderiv = len; |
2319 | } |
2320 | for (i = 0; i < problem->nGeomOut; i++) { |
2321 | if (problem->geomOut[i] == NULL) continue; |
2322 | if (problem->geomOut[i]->magicnumber != CAPSMAGIC) continue; |
2323 | if (problem->geomOut[i]->blind == NULL) continue; |
2324 | vout = (capsValue *) problem->geomOut[i]->blind; |
2325 | vout->derivs[len-1].name = EG_strdup(fullname); |
2326 | } |
2327 | |
2328 | problem->regGIN[len-1].name = EG_strdup(fullname); |
2329 | problem->regGIN[len-1].index = index; |
2330 | problem->regGIN[len-1].irow = irow; |
2331 | problem->regGIN[len-1].icol = icol; |
2332 | problem->nRegGIN = len; |
2333 | |
2334 | return CAPS_SUCCESS; |
2335 | } |
2336 | |
2337 | |
2338 | int |
2339 | caps_getDeriv(capsObject *vobj, const char *name, int *len, int *len_wrt, |
2340 | double **deriv, int *nErr, capsErrs **errors) |
2341 | { |
2342 | int i, ret, ipmtr, irow, icol, status, nbody, buildTo, builtTo; |
2343 | int irs, ire, ics, ice, index, outLevel; |
2344 | CAPSLONG sNum; |
2345 | capsValue *valueOut, *value_wrt; |
2346 | capsProblem *problem; |
2347 | capsObject *pobject; |
2348 | capsJrnl args[5]; |
2349 | size_t length; |
2350 | modl_T *MODL; |
2351 | |
2352 | if (nErr == NULL) return CAPS_NULLVALUE; |
2353 | if (errors == NULL) return CAPS_NULLVALUE; |
2354 | if (len == NULL) return CAPS_NULLVALUE; |
2355 | if (len_wrt == NULL) return CAPS_NULLVALUE; |
2356 | if (deriv == NULL) return CAPS_NULLVALUE; |
2357 | *nErr = 0; |
2358 | *errors = NULL; |
2359 | *len = *len_wrt = 0; |
2360 | *deriv = NULL; |
2361 | if (vobj == NULL) return CAPS_NULLOBJ; |
2362 | if (vobj->magicnumber != CAPSMAGIC) return CAPS_BADOBJECT; |
2363 | if (vobj->type != VALUE) return CAPS_BADTYPE; |
2364 | if (vobj->blind == NULL) return CAPS_NULLBLIND; |
2365 | if (name == NULL) return CAPS_NULLNAME; |
2366 | status = caps_findProblem(vobj, CAPS_GETDERIV, &pobject); |
2367 | if (status != CAPS_SUCCESS) return status; |
2368 | problem = (capsProblem *) pobject->blind; |
2369 | |
2370 | args[0].type = jInteger; |
2371 | args[1].type = jInteger; |
2372 | args[2].type = jPointer; |
2373 | args[3].type = jInteger; |
2374 | args[4].type = jErr; |
2375 | if (problem->dbFlag == 0) { |
2376 | status = caps_jrnlRead(CAPS_GETDERIV, problem, vobj, 5, args, &sNum, |
2377 | &ret); |
2378 | if (status == CAPS_JOURNALERR) return status; |
2379 | if (status == CAPS_JOURNAL) { |
2380 | *len = args[0].members.integer; |
2381 | *len_wrt = args[1].members.integer; |
2382 | *deriv = (double *) args[2].members.pointer; |
2383 | *nErr = args[3].members.integer; |
2384 | *errors = args[4].members.errs; |
2385 | return ret; |
2386 | } |
2387 | } |
2388 | |
2389 | sNum = problem->sNum; |
2390 | |
2391 | |
2392 | if (problem->dbFlag == 0) |
2393 | if (vobj->subtype == ANALYSISOUT) { |
2394 | status = caps_updateAnalysisOut(vobj, CAPS_GETDERIV, nErr, errors); |
2395 | if (status != CAPS_SUCCESS) return status; |
2396 | } else if (vobj->subtype == GEOMETRYOUT) { |
2397 | |
2398 | status = caps_build(pobject, nErr, errors); |
2399 | if ((status != CAPS_SUCCESS) && (status != CAPS_CLEAN)) goto finis; |
2400 | |
2401 | status = caps_registerGIN(problem, name); |
2402 | if (status != CAPS_SUCCESS) goto finis; |
2403 | } |
2404 | |
2405 | |
2406 | valueOut = (capsValue *) vobj->blind; |
2407 | if (valueOut->type != DoubleDeriv) { |
2408 | status = CAPS_BADTYPE; |
2409 | goto finis; |
2410 | } |
2411 | |
2412 | for (i = 0; i < valueOut->nderiv; i++) { |
2413 | if (strcmp(name, valueOut->derivs[i].name) != 0) continue; |
2414 | if ((valueOut->derivs[i].deriv == NULL) && (vobj->subtype == GEOMETRYOUT)) { |
2415 | index = problem->regGIN[i].index; |
2416 | irow = problem->regGIN[i].irow; |
2417 | icol = problem->regGIN[i].icol; |
2418 | |
2419 | if (problem->geomIn[index-1] == NULL) return CAPS_NULLOBJ; |
2420 | value_wrt = (capsValue *) problem->geomIn[index-1]->blind; |
2421 | ipmtr = value_wrt->pIndex; |
2422 | |
2423 | if (irow == 0 && icol == 0) { |
2424 | irs = ics = 1; |
2425 | ire = value_wrt->nrow; ice = value_wrt->ncol; |
2426 | } else { |
2427 | irs = irow; ics = icol; |
2428 | ire = irow; ice = icol; |
2429 | } |
2430 | |
2431 | for (irow = irs; irow <= ire; irow++) { |
2432 | for (icol = ics; icol <= ice; icol++) { |
2433 | |
2434 | status = ocsmSetDtime(problem->modl, 0); |
2435 | if (status != SUCCESS) goto finis; |
2436 | status = ocsmSetVelD(problem->modl, 0, 0, 0, 0.0); |
2437 | if (status != SUCCESS) goto finis; |
2438 | status = ocsmSetVelD(problem->modl, ipmtr, irow, icol, 1.0); |
2439 | if (status != SUCCESS) goto finis; |
2440 | buildTo = 0; |
2441 | nbody = 0; |
2442 | outLevel = ocsmSetOutLevel(0); |
2443 | if (problem->outLevel > 0) |
2444 | printf(" CAPS Info: Building sensitivity information for: %s[%d,%d]\n", |
2445 | problem->geomIn[index-1]->name, irow, icol); |
2446 | status = ocsmBuild(problem->modl, buildTo, &builtTo, &nbody, NULL); |
2447 | ocsmSetOutLevel(outLevel); |
2448 | |
2449 | |
2450 | fflush(stdout); |
2451 | if (status != SUCCESS) goto finis; |
2452 | caps_geomOutSensit(problem, ipmtr, irow, icol); |
2453 | MODL = (modl_T*)problem->modl; |
2454 | if (MODL->dtime != 0 && problem->outLevel > 0) |
2455 | printf(" CAPS Info: Sensitivity finite difference used for: %s[%d,%d]\n", |
2456 | problem->geomIn[index-1]->name, irow, icol); |
2457 | } |
2458 | } |
2459 | } |
2460 | *len = valueOut->length; |
2461 | *len_wrt = valueOut->derivs[i].len_wrt; |
2462 | *deriv = valueOut->derivs[i].deriv; |
2463 | status = CAPS_SUCCESS; |
2464 | goto finis; |
2465 | } |
2466 | status = CAPS_NOTFOUND; |
2467 | |
2468 | finis: |
2469 | if (problem->dbFlag == 1) return status; |
2470 | length = *len; |
2471 | length *= *len_wrt*sizeof(double); |
2472 | args[0].members.integer = *len; |
2473 | args[1].members.integer = *len_wrt; |
2474 | args[2].members.pointer = *deriv; |
2475 | args[2].length = length; |
2476 | args[3].members.integer = *nErr; |
2477 | args[4].members.errs = *errors; |
2478 | caps_jrnlWrite(CAPS_GETDERIV, problem, vobj, status, 5, args, sNum, |
2479 | problem->sNum); |
2480 | |
2481 | return status; |
2482 | } |