/*****************************************************************************1*2* Elmer, A Finite Element Software for Multiphysical Problems3*4* Copyright 1st April 1995 - , CSC - IT Center for Science Ltd., Finland5*6* This library is free software; you can redistribute it and/or7* modify it under the terms of the GNU Lesser General Public8* License as published by the Free Software Foundation; either9* version 2.1 of the License, or (at your option) any later version.10*11* This library is distributed in the hope that it will be useful,12* but WITHOUT ANY WARRANTY; without even the implied warranty of13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU14* Lesser General Public License for more details.15*16* You should have received a copy of the GNU Lesser General Public17* License along with this library (in file ../LGPL-2.1); if not, write18* to the Free Software Foundation, Inc., 51 Franklin Street,19* Fifth Floor, Boston, MA 02110-1301 USA20*21*****************************************************************************/2223/*******************************************************************************24*25* MATC variable manipulation.26*27*******************************************************************************28*29* Author: Juha Ruokolainen30*31* Address: CSC - IT Center for Science Ltd.32* Keilaranta 14, P.O. BOX 40533* 02101 Espoo, Finland34* Tel. +358 0 457 272335* Telefax: +358 0 457 230236* EMail: [email protected]37*38* Date: 30 May 199639*40* Modified by:41*42* Date of modification:43*44******************************************************************************/45/*********************************************************************46|47| VARIABLE.C - Last Edited 9. 8. 198848|49***********************************************************************/5051/*======================================================================52|Syntax of the manual pages:53|54|FUNCTION NAME(...) params ...55|56$ usage of the function and type of the parameters57? explain the effects of the function58= return value and the type of value if not of type int59@ globals effected directly by this routine60! current known bugs or limitations61& functions called by this function62~ these functions may interest you as an alternative function or63| because they control this function somehow64^=====================================================================*/656667/*68* $Id: variable.c,v 1.6 2007/05/11 07:53:32 jpr Exp $69*70* $Log: variable.c,v $71* Revision 1.6 2007/05/11 07:53:32 jpr72* *** empty log message ***73*74* Revision 1.5 2006/02/07 10:21:42 jpr75* Changed visibility of some variables to local scope.76*77* Revision 1.4 2006/02/02 06:54:44 jpr78* small formatting changes.79*80* Revision 1.2 2005/05/27 12:26:22 vierinen81* changed header install location82*83* Revision 1.1.1.1 2005/04/14 13:29:14 vierinen84* initial matc automake package85*86* Revision 1.2 1998/08/01 12:34:58 jpr87* Added Id, started Log.88*89*90*/9192#include "elmer/matc.h"9394VARIABLE *const_new(char *name, int type, int nrow, int ncol)95/*======================================================================96? return a new global VARIABLE given name, type, and matrix size.97| VARIABLE is linked to CONSTANTS lists.98|99= pointer to a new VARIABLE100& mat_new(), lst_add(), ALLOCMEM, FREEMEM, STRCOPY101^=====================================================================*/102{103VARIABLE *ptr;104105/*106Allocate the structure and link to global list of VARIABLES.107*/108109ptr = (VARIABLE *)ALLOCMEM(VARIABLESIZE); /* list entry */110ptr->this = mat_new(type, nrow, ncol); /* allocate new MATRIX */111REFCNT(ptr) = 1; /* one reference */112NAME(ptr) = STRCOPY(name); /* name as given */113114lst_add(CONSTANTS, (LIST *)ptr); /* add to list */115116return ptr;117}118119VARIABLE *var_new(char *name, int type, int nrow, int ncol)120/*======================================================================121? return a new global VARIABLE given name, type, and matrix size.122| VARIABLE is linked to VARIABLES list.123|124= pointer to a new VARIABLE125& var_check(), lst_add(), ALLOCMEM, FREEMEM, STRCOPY126^=====================================================================*/127{128VARIABLE *ptr;129130/*131* Delete old definition of name if any...132*/133var_delete(name);134135/*136* Allocate the structure and link to global list of VARIABLES.137*/138ptr = (VARIABLE *)ALLOCMEM(VARIABLESIZE); /* list entry */139ptr->this = mat_new(type, nrow, ncol); /* allocate new MATRIX */140REFCNT(ptr) = 1; /* one reference */141NAME(ptr) = STRCOPY(name); /* name as given */142143lst_addhead(VARIABLES, (LIST *)ptr); /* add to list */144145return ptr;146}147148void var_create_vector( char *name, int ntime, int ncol, double *data )149{150VARIABLE *var = var_new( name,TYPE_DOUBLE, ntime, ncol );151int i;152153FREEMEM( MATR(var) );154MATR(var) = data;155}156157VARIABLE *var_rename(VARIABLE *ptr, char *str)158{159VARIABLE *res;160161if (ptr == (VARIABLE *)NULL) return NULL;162163res = (VARIABLE *)lst_find( VARIABLES, str );164165if (res == NULL && REFCNT(ptr) > 1)166{167res = (VARIABLE *)ALLOCMEM(VARIABLESIZE);168NAME(res) = STRCOPY(str);169res->this = mat_copy(ptr->this);170REFCNT(res) = 1;171lst_addhead(VARIABLES, (LIST *)res);172}173else if (res == NULL)174{175res = (VARIABLE *)ALLOCMEM(VARIABLESIZE);176NAME(res) = STRCOPY(str);177res->this = ptr->this;178REFCNT(res)++;179lst_addhead(VARIABLES, (LIST *)res);180}181else182{183if ( res != ptr )184{185#if 1186if ( NROW(res) == NROW(ptr) && NCOL(res) == NCOL(ptr) )187{188memcpy( MATR(res),MATR(ptr), NROW(res)*NCOL(res)*sizeof(double) );189}190else191#endif192{193if (--REFCNT(res) == 0)194{195FREEMEM( (char *)MATR(res) );196FREEMEM( (char *)res->this );197}198res->this = ptr->this;199REFCNT(res)++;200}201}202}203204if ( res != ptr ) var_delete_temp(ptr);205206return res;207}208209static int var_pprec = 3,210var_pinp = FALSE, var_rowintime = FALSE;211#pragma omp threadprivate (var_pprec, var_pinp, var_rowintime)212213VARIABLE *var_format(VARIABLE *var)214{215if (*MATR(var) > 0 && *MATR(var) < 20)216{217var_pprec = *MATR(var);218}219220if (NEXT(var) != NULL)221{222char *frm = var_to_string(NEXT(var));223224if (strcmp(frm,"input") == 0)225{226var_pinp = TRUE;227}228else229{230var_pinp = FALSE;231if ( strcmp(frm,"rowform") == 0)232var_rowintime = TRUE;233else234var_rowintime = FALSE;235}236FREEMEM(frm);237}238239return (VARIABLE *)NULL;240}241242void var_print(VARIABLE *ptr)243{244double maxp, minp, maxx;245int i, j, k;246char fmt[80];247248if (ptr == (VARIABLE *)NULL) return;249250if (TYPE(ptr) == TYPE_STRING)251{252if (var_pinp)253PrintOut( "%d %d %% \"",NROW(ptr),NCOL(ptr) );254255for(i = 0; i < NROW(ptr); i++)256{257for(j = 0; j < NCOL(ptr); j++)258PrintOut( "%c", (char)M(ptr,i,j));259if (var_pinp)260{261if (i < NROW(ptr)-1)262PrintOut("\"\\");263else264PrintOut("\"");265}266PrintOut( "\n");267}268return;269}270271k = 0;272do273{274if (var_pinp)275PrintOut("%d %d %% ", NROW(ptr), NCOL(ptr));276else if (NCOL(ptr) > 8 && !var_rowintime )277PrintOut( "\nColumns %d trough %d\n\n",278k, min(NCOL(ptr) - 1, k + 7));279280if (var_pinp || var_rowintime )281sprintf(fmt, "%%.%dg",var_pprec );282else283sprintf(fmt, "%% %d.%dg",var_pprec+7,var_pprec);284285for(i = 0; i < NROW(ptr); i++)286{287if ( var_rowintime ) {288for( j=0; j<NCOL(ptr); j++ ) {289if ( j>0 ) PrintOut(" ");290PrintOut( fmt, M(ptr,i,j));291}292} else {293for(j = 0; j < 80/(var_pprec+7) && k + j < NCOL(ptr); j++)294PrintOut( fmt, M(ptr,i,j+k));295296if (var_pinp)297if (i < NROW(ptr)-1) PrintOut("\\");298}299300PrintOut("\n");301}302303k += j;304} while(k < NCOL(ptr));305}306307void var_delete(char *str)308{309VARIABLE *ptr;310311ptr = var_check(str);312313if ( ptr != (VARIABLE *)NULL )314{315if ( --REFCNT(ptr) == 0 )316{317FREEMEM((char *)MATR(ptr));318FREEMEM((char *)ptr->this);319}320lst_free(VARIABLES, (LIST *)ptr);321}322323return;324}325326VARIABLE *var_vdelete(VARIABLE *var)327{328var_delete( var_to_string( var ) );329return (VARIABLE *)NULL;330}331332333void var_free(void)334{335VARIABLE *ptr;336337for( ptr = (VARIABLE *)VAR_HEAD; ptr; ptr = NEXT(ptr) )338{339if ( --REFCNT(ptr) == 0 )340{341FREEMEM((char *)MATR(ptr));342FREEMEM((char *)ptr->this);343}344}345346lst_purge(VARIABLES);347348return;349}350351void const_free(void)352{353VARIABLE *ptr;354355for( ptr = (VARIABLE *)CONST_HEAD; ptr; ptr = NEXT(ptr) )356{357if ( --REFCNT(ptr) == 0 )358{359FREEMEM((char *)MATR(ptr));360FREEMEM((char *)ptr->this);361}362}363364lst_purge(CONSTANTS);365366return;367}368369VARIABLE *var_varlist(void)370/*======================================================================371? print a list of VARIABLES for the user372|373= (VARIABLE *)NULL374& lst_print()375^=====================================================================*/376{377lst_print(CONSTANTS); lst_print(VARIABLES);378379return NULL;380}381382VARIABLE *var_ccheck(VARIABLE *var)383/*======================================================================384? look for a VARIABLE from the global list of VARIABLES and return385| it or (VARIABLE *)NULL if not found.386|387= VARIABLE *388& var_check(), var_to_string()389^=====================================================================*/390{391VARIABLE *res;392char *str;393int i, n;394395for(n = 0, res = var; res != NULL; n++, res=NEXT(res));396res = var_temp_new(TYPE_DOUBLE, 1, n);397398for( i=0; i<n; i++, var=NEXT(var) )399{400str = var_to_string(var);401402if ( var_check(str) == NULL )403M(res,0,i) = FALSE;404else405M(res,0,i) = TRUE;406407FREEMEM(str);408}409410return res;411}412413VARIABLE *var_check(char *str)414/*======================================================================415? look for a VARIABLE from the global list of VARIABLES and return416| it or (VARIABLE *)NULL if not found.417|418= VARIABLE *419& lst_find()420^=====================================================================*/421{422VARIABLE *res;423424if ( (res = (VARIABLE *)lst_find(VARIABLES, str)) == NULL )425{426res = (VARIABLE *)lst_find(CONSTANTS, str);427}428429return res;430}431432VARIABLE *var_temp_copy(VARIABLE *from)433/*======================================================================434? Make a temporary (not linked to global list of VARIABLES)435| copy of a VARIABLE *from and.436|437= pointer to new VARIABLE438& ALLOCMEM439^=====================================================================*/440{441VARIABLE *to;442443/*444* if there's nothing to copy return.445*/446if ( from == NULL ) return NULL;447448to = (VARIABLE *)ALLOCMEM(VARIABLESIZE); /* list entry */449to->this = mat_copy(from->this);450REFCNT(to) = 1;451452return to;453}454455VARIABLE *var_temp_new(int type, int nrow, int ncol)456/*======================================================================457? Make a new temporary (not linked to global list of VARIABLES)458| VARIABLE, type and matrix dimensions from function parameters.459|460= pointer to new VARIABLE entry461& ALLOCMEM462^=====================================================================*/463{464VARIABLE *ptr;465466ptr = (VARIABLE *)ALLOCMEM(VARIABLESIZE); /* list entry */467ptr->this = mat_new(type, nrow, ncol);468REFCNT( ptr ) = 1;469470return ptr;471}472473474void var_copy_transpose(char *name, double *values, int nrows, int ncols)475{476VARIABLE *var;477int i,j;478479var = var_check(name);480if(!var) return;481482for(i=0; i<min(nrows,NROW(var)); i++)483for(j=0; j<min(ncols,NCOL(var)); j++)484values[nrows*i+j] = M(var,j,i);485}486487488void var_delete_temp_el( VARIABLE *ptr )489{490if ( ptr != NULL )491{492if ( --REFCNT(ptr) == 0 )493{494FREEMEM((char *)MATR(ptr));495FREEMEM((char *)ptr->this);496}497FREEMEM((char *)ptr);498}499return;500}501502void var_delete_temp( VARIABLE *head )503{504VARIABLE *ptr, *ptr1;505506for( ptr = head; ptr; )507{508ptr1 = NEXT(ptr);509var_delete_temp_el(ptr);510ptr = ptr1;511}512return;513}514515char *var_to_string(VARIABLE *ptr)516{517char *str;518int i;519520str = ALLOCMEM(NCOL(ptr)+1);521522for( i=0; i<NCOL(ptr); i++ )523{524str[i] = (char)M(ptr, 0, i);525}526527return str;528}529530void var_reset_status(char *name)531{532VARIABLE *ptr = var_check(name);533534if ( ptr ) ptr->changed = 0;535}536537VARIABLE *var_com_free()538{539VARIABLE *ptr;540541var_free();542return NULL;543}544545546int var_get_status(char *name)547{548VARIABLE *ptr = var_check(name);549550if ( ptr )551return ptr->changed;552else553return 0;554}555556void var_com_init(void)557{558static char *existsHelp =559{560"exists(name)\n"561"Return TRUE if variable by given name exists otherwise return FALSE.\n"562};563564static char *whoHelp =565{566"who\n"567"Gives list of currently defined variables.\n"568};569570static char *formatHelp =571{572"format(precision)\n"573"Set number of digits used in printing values in MATC.\n\n"574};575576static char *deleteHelp =577{578"delete(name)\n"579"Delete a variable with given name.\n"580};581582static char *clearHelp =583{584"clear()\n"585"Clear all variables.\n"586};587588com_init( "exists", FALSE, FALSE, var_ccheck , 1, 1000, existsHelp );589com_init( "who" , FALSE, FALSE, var_varlist, 0, 0, whoHelp );590com_init( "format" , FALSE, FALSE, var_format, 1, 2, formatHelp );591com_init( "delete", FALSE, FALSE, var_vdelete, 1, 1, deleteHelp );592com_init( "clear", FALSE, FALSE, var_com_free, 0, 0, clearHelp );593}594595596