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