1 /*****************************************************************************
2 *
3 * Elmer, A Finite Element Software for Multiphysical Problems
4 *
5 * Copyright 1st April 1995 - , CSC - IT Center for Science Ltd., Finland
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library (in file ../LGPL-2.1); if not, write
19 * to the Free Software Foundation, Inc., 51 Franklin Street,
20 * Fifth Floor, Boston, MA 02110-1301 USA
21 *
22 *****************************************************************************/
23
24 /*******************************************************************************
25 *
26 * MATC variable manipulation.
27 *
28 *******************************************************************************
29 *
30 * Author: Juha Ruokolainen
31 *
32 * Address: CSC - IT Center for Science Ltd.
33 * Keilaranta 14, P.O. BOX 405
34 * 02101 Espoo, Finland
35 * Tel. +358 0 457 2723
36 * Telefax: +358 0 457 2302
37 * EMail: Juha.Ruokolainen@csc.fi
38 *
39 * Date: 30 May 1996
40 *
41 * Modified by:
42 *
43 * Date of modification:
44 *
45 ******************************************************************************/
46 /*********************************************************************
47 |
48 | VARIABLE.C - Last Edited 9. 8. 1988
49 |
50 ***********************************************************************/
51
52 /*======================================================================
53 |Syntax of the manual pages:
54 |
55 |FUNCTION NAME(...) params ...
56 |
57 $ usage of the function and type of the parameters
58 ? explane the effects of the function
59 = return value and the type of value if not of type int
60 @ globals effected directly by this routine
61 ! current known bugs or limitations
62 & functions called by this function
63 ~ these functions may interest you as an alternative function or
64 | because they control this function somehow
65 ^=====================================================================*/
66
67
68 /*
69 * $Id: variable.c,v 1.6 2007/05/11 07:53:32 jpr Exp $
70 *
71 * $Log: variable.c,v $
72 * Revision 1.6 2007/05/11 07:53:32 jpr
73 * *** empty log message ***
74 *
75 * Revision 1.5 2006/02/07 10:21:42 jpr
76 * Changed visibility of some variables to local scope.
77 *
78 * Revision 1.4 2006/02/02 06:54:44 jpr
79 * small formatting changes.
80 *
81 * Revision 1.2 2005/05/27 12:26:22 vierinen
82 * changed header install location
83 *
84 * Revision 1.1.1.1 2005/04/14 13:29:14 vierinen
85 * initial matc automake package
86 *
87 * Revision 1.2 1998/08/01 12:34:58 jpr
88 * Added Id, started Log.
89 *
90 *
91 */
92
93 #include "elmer/matc.h"
94
const_new(name,type,nrow,ncol)95 VARIABLE *const_new(name, type, nrow, ncol) int type, ncol, nrow; char *name;
96 /*======================================================================
97 ? return a new global VARIABLE given name, type, and matrix size.
98 | VARIABLE is linked to CONSTANTS lists.
99 |
100 = pointer to a new VARIABLE
101 & mat_new(), lst_add(), ALLOCMEM, FREEMEM, STRCOPY
102 ^=====================================================================*/
103 {
104 VARIABLE *ptr;
105
106 /*
107 Allocate the structure and link to global list of VARIABLES.
108 */
109
110 ptr = (VARIABLE *)ALLOCMEM(VARIABLESIZE); /* list entry */
111 ptr->this = mat_new(type, nrow, ncol); /* allocate new MATRIX */
112 REFCNT(ptr) = 1; /* one reference */
113 NAME(ptr) = STRCOPY(name); /* name as given */
114
115 lst_add(CONSTANTS, (LIST *)ptr); /* add to list */
116
117 return ptr;
118 }
119
var_new(name,type,nrow,ncol)120 VARIABLE *var_new(name, type, nrow, ncol) int type, ncol, nrow; char *name;
121 /*======================================================================
122 ? return a new global VARIABLE given name, type, and matrix size.
123 | VARIABLE is linked to VARIABLES list.
124 |
125 = pointer to a new VARIABLE
126 & var_check(), lst_add(), ALLOCMEM, FREEMEM, STRCOPY
127 ^=====================================================================*/
128 {
129 VARIABLE *ptr;
130
131 /*
132 * Delete old definition of name if any...
133 */
134 var_delete(name);
135
136 /*
137 * Allocate the structure and link to global list of VARIABLES.
138 */
139 ptr = (VARIABLE *)ALLOCMEM(VARIABLESIZE); /* list entry */
140 ptr->this = mat_new(type, nrow, ncol); /* allocate new MATRIX */
141 REFCNT(ptr) = 1; /* one reference */
142 NAME(ptr) = STRCOPY(name); /* name as given */
143
144 lst_addhead(VARIABLES, (LIST *)ptr); /* add to list */
145
146 return ptr;
147 }
148
var_create_vector(char * name,int ntime,int ncol,double * data)149 void var_create_vector( char *name, int ntime, int ncol, double *data )
150 {
151 VARIABLE *var = var_new( name,TYPE_DOUBLE, ntime, ncol );
152 int i;
153
154 FREEMEM( MATR(var) );
155 MATR(var) = data;
156 }
157
var_rename(ptr,str)158 VARIABLE *var_rename(ptr, str) VARIABLE *ptr; char *str;
159 {
160 VARIABLE *res;
161
162 if (ptr == (VARIABLE *)NULL) return NULL;
163
164 res = (VARIABLE *)lst_find( VARIABLES, str );
165
166 if (res == NULL && REFCNT(ptr) > 1)
167 {
168 res = (VARIABLE *)ALLOCMEM(VARIABLESIZE);
169 NAME(res) = STRCOPY(str);
170 res->this = mat_copy(ptr->this);
171 REFCNT(res) = 1;
172 lst_addhead(VARIABLES, (LIST *)res);
173 }
174 else if (res == NULL)
175 {
176 res = (VARIABLE *)ALLOCMEM(VARIABLESIZE);
177 NAME(res) = STRCOPY(str);
178 res->this = ptr->this;
179 REFCNT(res)++;
180 lst_addhead(VARIABLES, (LIST *)res);
181 }
182 else
183 {
184 if ( res != ptr )
185 {
186 #if 1
187 if ( NROW(res) == NROW(ptr) && NCOL(res) == NCOL(ptr) )
188 {
189 memcpy( MATR(res),MATR(ptr), NROW(res)*NCOL(res)*sizeof(double) );
190 }
191 else
192 #endif
193 {
194 if (--REFCNT(res) == 0)
195 {
196 FREEMEM( (char *)MATR(res) );
197 FREEMEM( (char *)res->this );
198 }
199 res->this = ptr->this;
200 REFCNT(res)++;
201 }
202 }
203 }
204
205 if ( res != ptr ) var_delete_temp(ptr);
206
207 return res;
208 }
209
210 static int var_pprec = 3,
211 var_pinp = FALSE, var_rowintime = FALSE;
212 #pragma omp threadprivate (var_pprec, var_pinp, var_rowintime)
213
var_format(var)214 VARIABLE *var_format(var) VARIABLE *var;
215 {
216 if (*MATR(var) > 0 && *MATR(var) < 20)
217 {
218 var_pprec = *MATR(var);
219 }
220
221 if (NEXT(var) != NULL)
222 {
223 char *frm = var_to_string(NEXT(var));
224
225 if (strcmp(frm,"input") == 0)
226 {
227 var_pinp = TRUE;
228 }
229 else
230 {
231 var_pinp = FALSE;
232 if ( strcmp(frm,"rowform") == 0)
233 var_rowintime = TRUE;
234 else
235 var_rowintime = FALSE;
236 }
237 FREEMEM(frm);
238 }
239
240 return (VARIABLE *)NULL;
241 }
242
var_print(ptr)243 void var_print(ptr) VARIABLE *ptr;
244 {
245 double maxp, minp, maxx;
246 int i, j, k;
247 char fmt[80];
248
249 if (ptr == (VARIABLE *)NULL) return;
250
251 if (TYPE(ptr) == TYPE_STRING)
252 {
253 if (var_pinp)
254 PrintOut( "%d %d %% \"",NROW(ptr),NCOL(ptr) );
255
256 for(i = 0; i < NROW(ptr); i++)
257 {
258 for(j = 0; j < NCOL(ptr); j++)
259 PrintOut( "%c", (char)M(ptr,i,j));
260 if (var_pinp)
261 {
262 if (i < NROW(ptr)-1)
263 PrintOut("\"\\");
264 else
265 PrintOut("\"");
266 }
267 PrintOut( "\n");
268 }
269 return;
270 }
271
272 k = 0;
273 do
274 {
275 if (var_pinp)
276 PrintOut("%d %d %% ", NROW(ptr), NCOL(ptr));
277 else if (NCOL(ptr) > 8 && !var_rowintime )
278 PrintOut( "\nColumns %d trough %d\n\n",
279 k, min(NCOL(ptr) - 1, k + 7));
280
281 if (var_pinp || var_rowintime )
282 sprintf(fmt, "%%.%dg",var_pprec );
283 else
284 sprintf(fmt, "%% %d.%dg",var_pprec+7,var_pprec);
285
286 for(i = 0; i < NROW(ptr); i++)
287 {
288 if ( var_rowintime ) {
289 for( j=0; j<NCOL(ptr); j++ ) {
290 if ( j>0 ) PrintOut(" ");
291 PrintOut( fmt, M(ptr,i,j));
292 }
293 } else {
294 for(j = 0; j < 80/(var_pprec+7) && k + j < NCOL(ptr); j++)
295 PrintOut( fmt, M(ptr,i,j+k));
296
297 if (var_pinp)
298 if (i < NROW(ptr)-1) PrintOut("\\");
299 }
300
301 PrintOut("\n");
302 }
303
304 k += j;
305 } while(k < NCOL(ptr));
306 }
307
var_delete(str)308 void var_delete(str) char *str;
309 {
310 VARIABLE *ptr;
311
312 ptr = var_check(str);
313
314 if ( ptr != (VARIABLE *)NULL )
315 {
316 if ( --REFCNT(ptr) == 0 )
317 {
318 FREEMEM((char *)MATR(ptr));
319 FREEMEM((char *)ptr->this);
320 }
321 lst_free(VARIABLES, (LIST *)ptr);
322 }
323
324 return;
325 }
326
var_vdelete(var)327 VARIABLE *var_vdelete( var ) VARIABLE *var;
328 {
329 var_delete( var_to_string( var ) );
330 return (VARIABLE *)NULL;
331 }
332
333
var_free()334 void var_free()
335 {
336 VARIABLE *ptr;
337
338 for( ptr = (VARIABLE *)VAR_HEAD; ptr; ptr = NEXT(ptr) )
339 {
340 if ( --REFCNT(ptr) == 0 )
341 {
342 FREEMEM((char *)MATR(ptr));
343 FREEMEM((char *)ptr->this);
344 }
345 }
346
347 lst_purge(VARIABLES);
348
349 return;
350 }
351
const_free()352 void const_free()
353 {
354 VARIABLE *ptr;
355
356 for( ptr = (VARIABLE *)CONST_HEAD; ptr; ptr = NEXT(ptr) )
357 {
358 if ( --REFCNT(ptr) == 0 )
359 {
360 FREEMEM((char *)MATR(ptr));
361 FREEMEM((char *)ptr->this);
362 }
363 }
364
365 lst_purge(CONSTANTS);
366
367 return;
368 }
369
var_varlist()370 VARIABLE *var_varlist()
371 /*======================================================================
372 ? print a list of VARIABLES for the user
373 |
374 = (VARIABLE *)NULL
375 & lst_print()
376 ^=====================================================================*/
377 {
378 lst_print(CONSTANTS); lst_print(VARIABLES);
379
380 return NULL;
381 }
382
var_ccheck(var)383 VARIABLE *var_ccheck(var) VARIABLE *var;
384 /*======================================================================
385 ? look for a VARIABLE from the global list of VARIABLES and return
386 | it or (VARIABLE *)NULL if not found.
387 |
388 = VARIABLE *
389 & var_check(), var_to_string()
390 ^=====================================================================*/
391 {
392 VARIABLE *res;
393 char *str;
394 int i, n;
395
396 for(n = 0, res = var; res != NULL; n++, res=NEXT(res));
397 res = var_temp_new(TYPE_DOUBLE, 1, n);
398
399 for( i=0; i<n; i++, var=NEXT(var) )
400 {
401 str = var_to_string(var);
402
403 if ( var_check(str) == NULL )
404 M(res,0,i) = FALSE;
405 else
406 M(res,0,i) = TRUE;
407
408 FREEMEM(str);
409 }
410
411 return res;
412 }
413
var_check(str)414 VARIABLE *var_check(str) char *str;
415 /*======================================================================
416 ? look for a VARIABLE from the global list of VARIABLES and return
417 | it or (VARIABLE *)NULL if not found.
418 |
419 = VARIABLE *
420 & lst_find()
421 ^=====================================================================*/
422 {
423 VARIABLE *res;
424
425 if ( (res = (VARIABLE *)lst_find(VARIABLES, str)) == NULL )
426 {
427 res = (VARIABLE *)lst_find(CONSTANTS, str);
428 }
429
430 return res;
431 }
432
var_temp_copy(from)433 VARIABLE *var_temp_copy(from) VARIABLE *from;
434 /*======================================================================
435 ? Make a temporary (not linked to global list of VARIABLES)
436 | copy of a VARIABLE *from and.
437 |
438 = pointer to new VARIABLE
439 & ALLOCMEM
440 ^=====================================================================*/
441 {
442 VARIABLE *to;
443
444 /*
445 * if there's nothing to copy return.
446 */
447 if ( from == NULL ) return NULL;
448
449 to = (VARIABLE *)ALLOCMEM(VARIABLESIZE); /* list entry */
450 to->this = mat_copy(from->this);
451 REFCNT(to) = 1;
452
453 return to;
454 }
455
var_temp_new(type,nrow,ncol)456 VARIABLE *var_temp_new(type,nrow,ncol) int type, nrow, ncol;
457 /*======================================================================
458 ? Make a new temporary (not linked to global list of VARIABLES)
459 | VARIABLE, type and matrix dimensions from function parameters.
460 |
461 = pointer to new VARIABLE entry
462 & ALLOCMEM
463 ^=====================================================================*/
464 {
465 VARIABLE *ptr;
466
467 ptr = (VARIABLE *)ALLOCMEM(VARIABLESIZE); /* list entry */
468 ptr->this = mat_new(type, nrow, ncol);
469 REFCNT( ptr ) = 1;
470
471 return ptr;
472 }
473
474
var_copy_transpose(char * name,double * values,int nrows,int ncols)475 void var_copy_transpose(char *name,double *values,int nrows,int ncols)
476 {
477 VARIABLE *var;
478 int i,j;
479
480 var = var_check(name);
481 if(!var) return;
482
483 for(i=0; i<min(nrows,NROW(var)); i++)
484 for(j=0; j<min(ncols,NCOL(var)); j++)
485 values[nrows*i+j] = M(var,j,i);
486 }
487
488
var_delete_temp_el(VARIABLE * ptr)489 void var_delete_temp_el( VARIABLE *ptr )
490 {
491 if ( ptr != NULL )
492 {
493 if ( --REFCNT(ptr) == 0 )
494 {
495 FREEMEM((char *)MATR(ptr));
496 FREEMEM((char *)ptr->this);
497 }
498 FREEMEM((char *)ptr);
499 }
500 return;
501 }
502
var_delete_temp(VARIABLE * head)503 void var_delete_temp( VARIABLE *head )
504 {
505 VARIABLE *ptr, *ptr1;
506
507 for( ptr = head; ptr; )
508 {
509 ptr1 = NEXT(ptr);
510 var_delete_temp_el(ptr);
511 ptr = ptr1;
512 }
513 return;
514 }
515
var_to_string(ptr)516 char *var_to_string(ptr) VARIABLE *ptr;
517 {
518 char *str;
519 int i;
520
521 str = ALLOCMEM(NCOL(ptr)+1);
522
523 for( i=0; i<NCOL(ptr); i++ )
524 {
525 str[i] = (char)M(ptr, 0, i);
526 }
527
528 return str;
529 }
530
var_reset_status(char * name)531 void var_reset_status(char *name)
532 {
533 VARIABLE *ptr = var_check(name);
534
535 if ( ptr ) ptr->changed = 0;
536 }
537
var_com_free()538 VARIABLE *var_com_free()
539 {
540 VARIABLE *ptr;
541
542 var_free();
543 return NULL;
544 }
545
546
var_get_status(char * name)547 int var_get_status(char *name)
548 {
549 VARIABLE *ptr = var_check(name);
550
551 if ( ptr )
552 return ptr->changed;
553 else
554 return 0;
555 }
556
var_com_init()557 void var_com_init()
558 {
559 static char *existsHelp =
560 {
561 "exists(name)\n"
562 "Return TRUE if variable by given name exists otherwise return FALSE.\n"
563 };
564
565 static char *whoHelp =
566 {
567 "who\n"
568 "Gives list of currently defined variables.\n"
569 };
570
571 static char *formatHelp =
572 {
573 "format(precision)\n"
574 "Set number of digits used in printing values in MATC.\n\n"
575 };
576
577 static char *deleteHelp =
578 {
579 "delete(name)\n"
580 "Delete a variable with given name.\n"
581 };
582
583 static char *clearHelp =
584 {
585 "clear()\n"
586 "Clear all variables.\n"
587 };
588
589 com_init( "exists", FALSE, FALSE, var_ccheck , 1, 1000, existsHelp );
590 com_init( "who" , FALSE, FALSE, var_varlist, 0, 0, whoHelp );
591 com_init( "format" , FALSE, FALSE, var_format, 1, 2, formatHelp );
592 com_init( "delete", FALSE, FALSE, var_vdelete, 1, 1, deleteHelp );
593 com_init( "clear", FALSE, FALSE, var_com_free, 0, 0, clearHelp );
594 }
595