alg.c

Go to the documentation of this file.
00001 /*
00002 %M This module contains the funtions to manipulate the solution algorithm
00003    for the Relax program.
00004 %a Joao Luiz Elias Campos.
00005 %d September 3rd, 1998.
00006 %r $Id: alg.c,v 1.1 2004/06/22 05:29:58 joaoluiz Exp $
00007 %w (C) COPYRIGHT 1995-1996, Eduardo Nobre Lajes.
00008    (C) COPYRIGHT 1997-1999, Joao Luiz Elias Campos.
00009    All Rights Reserved
00010    Duplication of this program or any part thereof without the express
00011    written consent of the author is prohibited.
00012  *
00013  *   Modified:    08-Aug-05    Alexandre A. Del Savio
00014  *     Modificada a funcao DRSolver, onde adicionou-se "_count_it".
00015  *
00016  *   Modified:    13-Sep-05    Alexandre A. Del Savio
00017  *     Criada a funcao AlgReset.
00018  *
00019  *   Modified:    08-Dec-05    Juan Pablo Ibañez
00020  *     Criadas as variaveis locais vetError e delta para controle de 
00021  *     convergencia.
00022  *     Criada a funcão ConvergeError, para controle de convergencia.
00023  *     Modificada a funcão NeedIteration, que carrega o vetor de 
00024  *     forcas desequilibradas e chama a funcão ConvergeError.
00025  *     Modificada a funcão DRSolver, onde incluiu-se a alocacão
00026  *     dinamica de vetError, assim como sua liberacão.
00027  *     Acrescentou-se o parâmetro delta na funcão _count_it.
00028  *
00029  *   Modified:    29-Mar-06    Juan Pablo Ibañez
00030  *     Modificada a funcão DRSolver, onde a variável delta é zerada no 
00031  *     final do processo de calculo. Também é chamada a funcão 
00032  *     ConstrainFree para liberar memória da lista ConstList.
00033  *     
00034  *   Modified:    Dez-06       André Luis Muller
00035  *     Modificação na função DRSolver, possibilitando uma primeira
00036  *     solução, linear elástica.
00037  *
00038  *   Modified:    07       André Luis Muller
00039  *     Modificação na função DRSolver, possibilitando uma 
00040  *     solução híbrida.
00041  *
00042  *     Novo critério de convergência.
00043  *
00044  *     Passos de carga.
00045  *
00046  *     Adição do um novo item para verificar parada da análise
00047  *     função (stop).
00048  */
00049 
00050 /*
00051 ** ------------------------------------------------------------------------
00052 ** Global variables and symbols:
00053 */
00054 #include <stdio.h>
00055 #include <stdlib.h>
00056 #include <string.h>
00057 #include <math.h>
00058 #include <time.h>
00059 
00060 #include "load.h"
00061 #include "elm.h"
00062 #include "node.h"
00063 #include "fem.h"
00064 #include "alg.h"
00065 #include "nfi.h"
00066 #include "rio.h"
00067 #include "drv.h"
00068 #include "damp.h"
00069 #include "constrain.h"
00070 #include "csr.h"
00071 
00072 /*
00073 ** ------------------------------------------------------------------------
00074 **definitions of minimum and maximus
00075 */
00076 #ifndef MAX
00077 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
00078 #endif
00079 
00080 #ifndef MIN
00081 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
00082 #endif
00083 
00084 /*
00085 %V Configuration parameters
00086 */
00087 sConfig Config = { 0, 0, 0, 1, 0, 0, 0.0, 0, 0.0, 0.0, 0.0, 0 }; 
00088 
00089 
00090 /*
00091 %V Flag to see if is a coupled problem
00092 */
00093 eCoupState State = UNCOUPLED;
00094 
00095 
00096 /*
00097 ** ------------------------------------------------------------------------
00098 ** Local variables and symbols:
00099 */
00100 
00101 #ifndef PI
00102 #define PI 3.141592654
00103 #endif
00104 
00105 /* local variables for convergence control */
00106 double *vetError;   
00107 double delta = 0.0;  
00108 
00109 /*
00110 ** ------------------------------------------------------------------------
00111 ** Local functions:
00112 */
00113 static double _TimeIncrement ( void );
00114 static void   _UpdateGeometry( double, double * );
00115 static int    _ConvergeError ( );
00116 static double InitialError( double, double *, double *, double *, double *);
00117 /*
00118 %F
00119 */
00120 static double _TimeIncrement( void )
00121 {
00122  double dt  = 1.0e6;
00123  double edt = 1.0e6;
00124  int    i;
00125 
00126 /* For each element computes the time step
00127  */
00128  for( i = 0; i < NumElements; i++ )
00129  {
00130  /* Check to see if the element was rezoned
00131   */
00132   if( ElmList[i]->rezone != NONE )
00133    continue;
00134 
00135  /* Compute the time step for the element
00136   */
00137   ElmTimeStep( ElmList[i], &edt );
00138 
00139  /* Get the minimum time step
00140   */
00141   if( edt < dt )
00142    dt = edt;
00143  }
00144 
00145  return( dt );
00146 
00147 } /* End of _TimeIncrement */
00148 
00149 
00150 static int _ConvergeError ( )
00151 {
00152  int i;
00153  int flag = 1;
00154  int dimVetError = Config.numsteptol;   
00155  
00156  for(i = 0; i < dimVetError; i++)
00157  {
00158    if(vetError[i] >= Config.tolerance)
00159     flag = 0;   
00160  }
00161 
00162  return( flag );
00163         
00164 } /* End of _ConvergeError */
00165 
00166 
00167 /*
00168 %F This function updates the model geometry for the larger displaments case.
00169 */
00170 static void _UpdateGeometry( double dtime, double *VVector )
00171 {
00172  int i;
00173 
00174 /* Update geometry
00175  */
00176  for( i = 0; i < NumNodes; i++ )
00177  {
00178   NodeVector[i].coord.x += dtime * VVector[NDof*i];
00179   NodeVector[i].coord.y += dtime * VVector[NDof*i+1];
00180   if( NDof == 3 )
00181    NodeVector[i].coord.z += dtime * VVector[NDof*i+2];
00182  }
00183 
00184 } /* End of _UpdateGeometry */
00185 
00186 
00187 static double InitialError( double dtime, double *F, double *U, double *V, double *U0)
00188 {
00189  int       i, j;
00190  double    error;
00191  double vp[3];
00192  eRestType dof[3]; 
00193  
00194  for( i = 0; i < NumNodes; i++ ) {
00195   dof[0] = NodeVector[i].dof.x;
00196   dof[1] = NodeVector[i].dof.y;
00197   dof[2] = NodeVector[i].dof.z;
00198   vp[0]  = NodeVector[i].dof.vpx;
00199   vp[1]  = NodeVector[i].dof.vpy;
00200   vp[2]  = NodeVector[i].dof.vpz;
00201   for( j = 0; j < NDof; j++ ) {
00202   /* Verifica a condição de contorno de deslocamento
00203    */
00204    if(dof[j] == DISPLACEMENT){
00205     U[NDof*i+j] = vp[j] * Config.loadfactor;
00206    }
00207   }
00208  }
00209  
00210  /* Compute the internal forces
00211  */
00212  InternalForces( dtime, F, U, V );
00213  
00214 /* Initialize error
00215  */
00216  error = 0.0;
00217 
00218 /* Loop over the nodes
00219  */
00220  for( i = 0; i < NumNodes; i++ )
00221  {
00222  /* Check to see if the node was rezoned
00223   */
00224   if( NodeVector[i].rezone != NONE )
00225    continue;
00226 
00227  /* Loop over the degree of freedown
00228   */
00229   for( j = 0; j < NDof; j++ )
00230   {
00231    /* Compute the error for this dof
00232     */
00233    error += fabs(F[NDof*i+j]);
00234   }
00235  }
00236  
00237  for( i = 0; i < NumNodes; i++ ) {
00238   for( j = 0; j < NDof; j++ ) {
00239    U[NDof*i+j] = U0[NDof*i+j];
00240   }
00241  }
00242  
00243  return (error);
00244 }
00245 
00246 /*
00247 ** ------------------------------------------------------------------------
00248 ** Public functions:
00249 */
00250 
00251 
00252 /*
00253 %F
00254 */
00255 double ComputeError( double *FVector, double *UVector, double error0 )
00256 {
00257  int       i, j;
00258  double    err;
00259  
00260 /* Initialize error
00261  */
00262  err = 0.0;
00263 
00264 /* Loop over the nodes
00265  */
00266  for( i = 0; i < NumNodes; i++ )
00267  {
00268  /* Check to see if the node was rezoned
00269   */
00270   if( NodeVector[i].rezone != NONE )
00271    continue;
00272 
00273  /* Loop over the degree of freedown
00274   */
00275   for( j = 0; j < NDof; j++ )
00276   {
00277    /* Compute the error for this dof
00278     */
00279    err += fabs(FVector[NDof*i+j] * UVector[NDof*i+j]);
00280   }
00281  }
00282 
00283  return( err/error0 );
00284 
00285 } /* End of ComputeError */
00286 
00287 /*
00288 %F
00289 */
00290 void _dUVector( double *UVector, double *UVector0, double *dUVector )
00291 {
00292  int       i, j;
00293 
00294 /* Loop over the nodes
00295  */
00296  for( i = 0; i < NumNodes; i++ )
00297  {
00298  /* Check to see if the node was rezoned
00299   */
00300   if( NodeVector[i].rezone != NONE )
00301    continue;
00302 
00303  /* Loop over the degree of freedown
00304   */
00305   for( j = 0; j < NDof; j++ )
00306   {
00307    /* Compute the dUVector and UVector0
00308     */
00309    dUVector[NDof*i+j] = UVector[NDof*i+j] - UVector0[NDof*i+j]; 
00310    UVector0[NDof*i+j] = UVector[NDof*i+j];
00311   }
00312  }
00313 
00314 } /* End of _dUVector */
00315 
00316 /*
00317 %F
00318 */
00319 int NeedIteration( double *error, int *iteration, int stop )
00320 {
00321  int i;
00322  int flag;
00323  int dimVetError = Config.numsteptol;
00324     
00325  /* load error vector (iteration < dimVetError) */
00326  if ( (*iteration < dimVetError)  && (stop == 0) )
00327  {
00328    vetError[*iteration] = *error;
00329    flag = 1;
00330    (*iteration)++; 
00331    return( flag );
00332  }  
00333     
00334  /* load error vector (iteration > dimVetError) */
00335  for(i = 0; i < dimVetError-1; i++)
00336  {
00337    vetError[i] = vetError[i+1];
00338  } 
00339  vetError[dimVetError-1] = *error;
00340 
00341  /* convergence control */
00342  if( (_ConvergeError( ) != 0) || ((*iteration + 1) > Config.max_iter) ||
00343      (stop == 1)) 
00344  {
00345   flag = 0;
00346  }
00347  else
00348  {
00349   flag = 1;
00350   (*iteration)++;
00351  }
00352 
00353  return( flag );
00354 
00355 } /* End of NeedIteration */
00356 
00357 /*
00358 %F
00359 */
00360 int DRSolver(UI_State *R, double *FVector, double *UVector, double *VVector,
00361                           double *MVector, int loadstep)
00362 {
00363  int    iteration, needite;
00364  double dtime, alpha, CinEng, error;
00365  double *dUVector, *UVector0;
00366  double error0;
00367  int    stop = 0;
00368  unsigned long int i_time = time( NULL );
00369 
00370 /* Initialize variables
00371  */
00372  iteration = 0;
00373  needite   = 0;
00374  dtime     = 0.0;
00375  alpha     = 0.0;
00376  error     = 0.0;
00377  CinEng    = 0.0;
00378  error0    = 1.0;
00379  
00380  dUVector  = (double *)calloc( NDof*NumNodes, sizeof(double) );
00381  UVector0  = (double *)calloc( NDof*NumNodes, sizeof(double) );
00382 
00383  if(R)
00384   UISetDisplacement(R, NDof, UVector);
00385 
00386 /* Compute the time increment according Cundall (1989)
00387  */
00388  dtime  = Config.dtfrac * _TimeIncrement();
00389 
00390 /* Mount the mass vector
00391  */
00392  MassVector( MVector );
00393  
00394 /* allocate error vector */ 
00395  vetError = (double*)malloc(Config.numsteptol*sizeof(double));
00396 
00397  /* Faz analise para cada passo de carga
00398   */
00399 
00400  iteration = 0;
00401  
00402  Config.loadfactor = (loadstep + 1.0) / Config.num_load_step;
00403  
00404  /* Compute the initial error
00405  */
00406  error0 = InitialError(dtime, FVector, UVector, VVector, UVector0);
00407  
00408  /* Process iteration until convergence or maximum iteration number
00409  */
00410  do {
00411   
00412   /* Compute the rigidity coefficient
00413   */
00414   DampCalcCoeff(DampObj,iteration,dtime,MVector,VVector,&alpha,&CinEng);
00415   
00416   /* Compute displacements and veclocities
00417   */
00418   if( !DisplacementVelocity( iteration, alpha, dtime, 
00419                             FVector, VVector, UVector, MVector ) ) 
00420    return 0;
00421   /*
00422   */
00423   if( R && (iteration%Config.draw_step) )
00424    UIDraw(R);
00425   
00426   /* Update geometry for the larger displacements case
00427   */
00428   if( IsGeomNonLinear )
00429    _UpdateGeometry( dtime, VVector );
00430   
00431   /* Compute the percolation forces
00432   */
00433   if( IsCoupled )
00434    PercolationForces( FVector );
00435   
00436   /* Compute the internal forces
00437   */
00438   InternalForces( dtime, FVector, UVector, VVector );
00439   
00440   /* Compute the dUVector
00441   */
00442   _dUVector(UVector, UVector0, dUVector);
00443    
00444   /* Compute the error
00445   */
00446   error = ComputeError( FVector , dUVector, error0);
00447   
00448   /* For larger displaments correct the time step and compute a new
00449   * mass vector for the model
00450   */
00451   if( IsGeomNonLinear ) {
00452    if( error > 1.0 ) {
00453     dtime = Config.dtfrac * _TimeIncrement();
00454     MassVector( MVector );
00455    }
00456   }
00457   
00458   if( _count_it != NULL )
00459     (*_count_it) ( iteration, error, loadstep);
00460     
00461   if( _fstop != NULL )
00462     (*_fstop) ( &stop );  
00463     
00464   /* Check for another iteration
00465   */
00466   needite = NeedIteration( &error, &iteration, stop );    
00467   
00468   fprintf( stdout, "\tStep: %d\tError: %3.3e\r", iteration+1, error);
00469 
00470   fflush( stdout );
00471   
00472   if(Config.num_load_step == 1){
00473    /* Save results on a temporary file
00474    */
00475    DrvPrintResult( DrvObj, iteration, UVector, VVector );
00476   }
00477  } while( needite );
00478 
00479  if(Config.num_load_step > 1){
00480   /* Save results on a temporary file
00481   */
00482   DrvPrintResult( DrvObj, loadstep, UVector, VVector );
00483  }
00484  
00485 
00486  /* free error vector */
00487  free ( vetError );
00488 
00489  fprintf( stdout, "\n\tTotal solver time....................: %lu segs\n\n", (time(NULL)-i_time) );
00490 
00491  free( dUVector );
00492  free( UVector0 );
00493  
00494  return( 1 );
00495 
00496 } /* End of DRSolver */
00497 
00498 /*
00499 %F
00500 */
00501 int IMPLINEARSolver(UI_State *R, double *FVector, double *UVector, double *VVector,
00502                     double *MVector, int loadstep)
00503 {
00504  int    iteration, needite;
00505  double dtime, alpha, CinEng, error;
00506  double *dUVector, *UVector0;
00507  double error0;
00508  int    stop = 0;
00509  unsigned long int i_time = time( NULL );
00510  int i;
00511  int    *ia;
00512  int    *ja = NULL;
00513  double *avector;
00514  int    nna = 0;
00515  int    nnu = 0;
00516  CsrNode   *node_list = 0L;      /* lista de nós Csr*/
00517 
00518 /* Initialize variables
00519  */
00520  iteration = 0;
00521  needite   = 0;
00522  dtime     = 0.0;
00523  alpha     = 0.0;
00524  error     = 0.0;
00525  CinEng    = 0.0;
00526  error0    = 1.0;
00527  Config.numsteptol    = 1;
00528  
00529  dUVector  = (double *)calloc( NDof*NumNodes, sizeof(double) );
00530  UVector0  = (double *)calloc( NDof*NumNodes, sizeof(double) );
00531  
00532  nnu = NDof*NumNodes;
00533 
00534  /* aloca memória para lista de nós
00535  */
00536  node_list = (CsrNode*) calloc(NumNodes + 1, sizeof(CsrNode));
00537  
00538  /* constroi a lista de nós
00539  */
00540  BuildNodeList(node_list);
00541 
00542  /* constroi a lista de nós
00543  */
00544  BuildNodeList(node_list);
00545  
00546  /* aloca memória para ia*/
00547  ia  = (int*)calloc( nnu + 1, sizeof(int) );
00548  
00549  /* cria o vetor ia*/
00550  BuildIaVec( node_list, ia, nnu, &nna );
00551 
00552  /* aloca memória para ia*/
00553  avector  = (double*)calloc( nna, sizeof(double) );
00554  
00555  /* aloca memória para ja*/
00556  ja  = (int*)calloc( nna, sizeof(int) );
00557  
00558  /* cria o vetor ia*/
00559  BuildJaVec( node_list, ja );
00560  
00561  /* libera memória da lista de nós
00562  */
00563  FreeNodeList(node_list);
00564  
00565  /* cria o vetor avector*/
00566  BuildAVector( ia, ja, avector );
00567  
00568  if(Config.solver == 1){
00569  
00570  /* Mudança de índices necessárias
00571     para utilização do solver SAMG*/
00572   for( i = 0; i < nnu+1; i++ ) {
00573    ia[i] += 1;
00574   }
00575   for( i = 0; i < nna; i++ ) {
00576    ja[i] += 1;
00577   }
00578   
00579  }
00580  
00581  if(R)
00582   UISetDisplacement(R, NDof, UVector);
00583 
00584 /* Compute the time increment according Cundall (1989)
00585  */
00586  dtime  = Config.dtfrac * _TimeIncrement();
00587 
00588 /* Mount the mass vector
00589  */
00590  MassVector( MVector );
00591  
00592 /* allocate error vector */ 
00593  vetError = (double*)malloc(Config.numsteptol*sizeof(double));
00594 
00595  /* Faz analise para cada passo de carga
00596   */
00597 
00598  iteration = 0;
00599  
00600  Config.loadfactor = (loadstep + 1.0) / Config.num_load_step;
00601  
00602  /* Compute the initial error
00603  */
00604  error0 = InitialError(dtime, FVector, UVector, VVector, UVector0);
00605  
00606  do {
00607         
00608   LINEAR( dtime, FVector, UVector, VVector, &iteration, &error, error0, loadstep, nna, nnu, ia, ja, avector );
00609    
00610   if( _count_it != NULL )
00611     (*_count_it) ( iteration, error, loadstep);
00612     
00613   if( _fstop != NULL )
00614     (*_fstop) ( &stop );  
00615     
00616   needite = 0;
00617   
00618   fprintf( stdout, "\tStep: %d             Error: %3.3e\r", iteration+1, error );
00619   fflush( stdout );
00620   
00621   if(Config.num_load_step == 1){
00622    /* Save results on a temporary file
00623    */
00624    DrvPrintResult( DrvObj, iteration, UVector, VVector );
00625   }
00626  } while( needite );
00627 
00628  if(Config.num_load_step > 1){
00629   /* Save results on a temporary file
00630   */
00631   DrvPrintResult( DrvObj, loadstep, UVector, VVector );
00632  }
00633  
00634 
00635  /* free error vector */
00636  free ( vetError );
00637 
00638  fprintf( stdout, "\n\tTotal solver time....................: %lu segs\n\n", (time(NULL)-i_time) );
00639 
00640  free( dUVector );
00641  free( UVector0 );
00642  free( ia );
00643  free( ja );
00644  free( avector );
00645  
00646  return( 1 );
00647 
00648 } /* End of IMPLINEARSolver */
00649 
00650 /*
00651 %F
00652 */
00653 int IMPBFGSSolver(UI_State *R, double *FVector, double *UVector, double *VVector,
00654                double *MVector, int loadstep)
00655 {
00656  int    iteration, needite;
00657  double dtime, alpha, CinEng, error;
00658  double *dUVector, *UVector0;
00659  double error0;
00660  int    stop = 0;
00661  unsigned long int i_time = time( NULL );
00662  int i;
00663  int    *ia;
00664  int    *ja;
00665  double *avector;
00666  int    nna = 0;
00667  int    nnu = 0;
00668  CsrNode   *node_list = 0L;      /* lista de nós Csr*/
00669  
00670 /* Initialize variables
00671  */
00672  iteration = 0;
00673  needite   = 0;
00674  dtime     = 0.0;
00675  alpha     = 0.0;
00676  error     = 0.0;
00677  CinEng    = 0.0;
00678  error0    = 1.0;
00679  Config.numsteptol    = 1;
00680  
00681  dUVector  = (double *)calloc( NDof*NumNodes, sizeof(double) );
00682  UVector0  = (double *)calloc( NDof*NumNodes, sizeof(double) );
00683  
00684  nnu = NDof*NumNodes;
00685  
00686  /* aloca memória para lista de nós
00687  */
00688  node_list = (CsrNode*) calloc(NumNodes + 1, sizeof(CsrNode));
00689  
00690  /* constroi a lista de nós
00691  */
00692  BuildNodeList(node_list);
00693 
00694  /* constroi a lista de nós
00695  */
00696  BuildNodeList(node_list);
00697  
00698  /* aloca memória para ia*/
00699  ia  = (int*)calloc( nnu + 1, sizeof(int) );
00700  
00701  /* cria o vetor ia*/
00702  BuildIaVec( node_list, ia, nnu, &nna );
00703  
00704  /* aloca memória para ja*/
00705  ja  = (int*)calloc( nna, sizeof(int) );
00706  
00707  /* cria o vetor ia*/
00708  BuildJaVec( node_list, ja );
00709  
00710  /* libera memória da lista de nós
00711  */
00712  FreeNodeList(node_list);
00713  
00714  /* aloca memória para ia*/
00715  avector  = (double*)calloc( nna, sizeof(double) );
00716  
00717  /* cria o vetor avector*/
00718  BuildAVector( ia, ja, avector );
00719  
00720  if(Config.solver == 1){
00721  
00722  /* Mudança de índices necessárias
00723     para utilização do solver SAMG*/
00724   for( i = 0; i < nnu+1; i++ ) {
00725    ia[i] += 1;
00726   }
00727   for( i = 0; i < nna; i++ ) {
00728    ja[i] += 1;
00729   }
00730   
00731  }
00732  
00733  if(R)
00734   UISetDisplacement(R, NDof, UVector);
00735 
00736 /* Compute the time increment according Cundall (1989)
00737  */
00738  dtime  = Config.dtfrac * _TimeIncrement();
00739 
00740 /* Mount the mass vector
00741  */
00742  MassVector( MVector );
00743  
00744 /* allocate error vector */ 
00745  vetError = (double*)malloc(Config.numsteptol*sizeof(double));
00746 
00747  /* Faz analise para cada passo de carga
00748   */
00749 
00750  iteration = 0;
00751  
00752  Config.loadfactor = (loadstep + 1.0) / Config.num_load_step;
00753  
00754  /* Compute the initial error
00755  */
00756  error0 = InitialError(dtime, FVector, UVector, VVector, UVector0);
00757  
00758  do {
00759   
00760   BFGS( dtime, FVector, UVector, VVector, &iteration, &error, error0, loadstep, nna, nnu, ia, ja, avector );
00761   
00762   if( _count_it != NULL )
00763     (*_count_it) ( iteration, error, loadstep);
00764     
00765   if( _fstop != NULL )
00766     (*_fstop) ( &stop );  
00767     
00768   /* Check for another iteration
00769   */
00770   needite = NeedIteration( &error, &iteration, stop );
00771   
00772   if(Config.num_load_step == 1){
00773    /* Save results on a temporary file
00774    */
00775    DrvPrintResult( DrvObj, iteration, UVector, VVector );
00776   }
00777  } while( needite );
00778 
00779  if(Config.num_load_step > 1){
00780   /* Save results on a temporary file
00781   */
00782   DrvPrintResult( DrvObj, loadstep, UVector, VVector );
00783  }
00784 
00785  /* free error vector */
00786  free ( vetError );
00787 
00788  fprintf( stdout, "\n\tTotal solver time....................: %lu segs\n\n", (time(NULL)-i_time) );
00789 
00790  printf( "\n" );
00791 
00792  free( dUVector );
00793  free( UVector0 );
00794  free( ia );
00795  free( ja );
00796  free( avector );
00797  
00798  return( 1 );
00799 
00800 } /* End of BFGSSolver */
00801 
00802 /*
00803 %F
00804 */
00805 int IMPNRMSolver(UI_State *R, double *FVector, double *UVector, double *VVector,
00806               double *MVector, int loadstep)
00807 {
00808  int    iteration, needite;
00809  double dtime, alpha, CinEng, error;
00810  double *dUVector, *UVector0;
00811  double error0;
00812  int    stop = 0;
00813  unsigned long int i_time = time( NULL );
00814  int i;
00815  int    *ia;
00816  int    *ja;
00817  double *avector;
00818  int    nna = 0;
00819  int    nnu = 0;
00820  CsrNode   *node_list = 0L;      /* lista de nós Csr*/
00821  
00822 /* Initialize variables
00823  */
00824  iteration = 0;
00825  needite   = 0;
00826  dtime     = 0.0;
00827  alpha     = 0.0;
00828  error     = 0.0;
00829  CinEng    = 0.0;
00830  error0    = 1.0;
00831  Config.numsteptol    = 1;
00832  
00833  dUVector  = (double *)calloc( NDof*NumNodes, sizeof(double) );
00834  UVector0  = (double *)calloc( NDof*NumNodes, sizeof(double) );
00835  
00836  nnu = NDof*NumNodes;
00837  
00838  /* aloca memória para lista de nós
00839  */
00840  node_list = (CsrNode*) calloc(NumNodes + 1, sizeof(CsrNode));
00841  
00842  /* constroi a lista de nós
00843  */
00844  BuildNodeList(node_list);
00845 
00846  /* constroi a lista de nós
00847  */
00848  BuildNodeList(node_list);
00849  
00850  /* aloca memória para ia*/
00851  ia  = (int*)calloc( nnu + 1, sizeof(int) );
00852  
00853  /* cria o vetor ia*/
00854  BuildIaVec( node_list, ia, nnu, &nna );
00855  
00856  /* aloca memória para ja*/
00857  ja  = (int*)calloc( nna, sizeof(int) );
00858  
00859  /* cria o vetor ia*/
00860  BuildJaVec( node_list, ja );
00861  
00862  /* libera memória da lista de nós
00863  */
00864  FreeNodeList(node_list);
00865  
00866  /* aloca memória para ia*/
00867  avector  = (double*)calloc( nna, sizeof(double) );
00868  
00869  /* cria o vetor avector*/
00870  BuildAVector( ia, ja, avector );
00871  
00872  if(Config.solver == 1){
00873  
00874  /* Mudança de índices necessárias
00875     para utilização do solver SAMG*/
00876   for( i = 0; i < nnu+1; i++ ) {
00877    ia[i] += 1;
00878   }
00879   for( i = 0; i < nna; i++ ) {
00880    ja[i] += 1;
00881   }
00882   
00883  }
00884 
00885  if(R)
00886   UISetDisplacement(R, NDof, UVector);
00887 
00888 /* Compute the time increment according Cundall (1989)
00889  */
00890  dtime  = Config.dtfrac * _TimeIncrement();
00891 
00892 /* Mount the mass vector
00893  */
00894  MassVector( MVector );
00895  
00896 /* allocate error vector */ 
00897  vetError = (double*)malloc(Config.numsteptol*sizeof(double));
00898 
00899  /* Faz analise para cada passo de carga
00900   */
00901 
00902  iteration = 0;
00903  
00904  Config.loadfactor = (loadstep + 1.0) / Config.num_load_step;
00905  
00906  /* Compute the initial error
00907  */
00908  error0 = InitialError(dtime, FVector, UVector, VVector, UVector0);
00909  
00910  do {
00911   
00912   NRM( dtime, FVector, UVector, VVector, &iteration, &error, error0, loadstep, nna, nnu, ia, ja, avector );
00913   
00914   if( _count_it != NULL )
00915     (*_count_it) ( iteration, error, loadstep);
00916     
00917   if( _fstop != NULL )
00918     (*_fstop) ( &stop );  
00919     
00920   /* Check for another iteration
00921   */
00922   needite = NeedIteration( &error, &iteration, stop );
00923   
00924   if(Config.num_load_step == 1){
00925    /* Save results on a temporary file
00926    */
00927    DrvPrintResult( DrvObj, iteration, UVector, VVector );
00928   }
00929  } while( needite );
00930 
00931  if(Config.num_load_step > 1){
00932   /* Save results on a temporary file
00933   */
00934   DrvPrintResult( DrvObj, loadstep, UVector, VVector );
00935  }
00936 
00937  /* free error vector */
00938  free ( vetError );
00939 
00940  fprintf( stdout, "\n\tTotal solver time....................: %lu segs\n\n", (time(NULL)-i_time) );
00941 
00942  printf( "\n" );
00943 
00944  free( dUVector );
00945  free( UVector0 );
00946  free( ia );
00947  free( ja );
00948  free( avector );
00949  
00950  return( 1 );
00951 
00952 } /* End of NRMSolver */
00953 
00954 /*
00955 %F
00956 */
00957 int HYBRIDSolver(UI_State *R, double *FVector, double *UVector, double *VVector,
00958                double *MVector, int loadstep)
00959 {
00960  int    iteration, needite;
00961  double dtime, alpha, CinEng, error;
00962  double *dUVector, *UVector0;
00963  double error0;
00964  int    stop = 0;
00965  int    hs = 1;
00966  unsigned long int i_time = time( NULL );
00967  int i;
00968  int    *ia;
00969  int    *ja;
00970  double *avector;
00971  int    nna = 0;
00972  int    nnu = 0;
00973  CsrNode   *node_list = 0L;      /* lista de nós Csr*/
00974  
00975 /* Initialize variables
00976  */
00977  iteration = 0;
00978  needite   = 0;
00979  dtime     = 0.0;
00980  alpha     = 0.0;
00981  error     = 0.0;
00982  CinEng    = 0.0;
00983  error0    = 1.0;
00984  Config.max_iter      = 20;
00985  Config.numsteptol    = 1;
00986  
00987  dUVector  = (double *)calloc( NDof*NumNodes, sizeof(double) );
00988  UVector0  = (double *)calloc( NDof*NumNodes, sizeof(double) );
00989  
00990  nnu = NDof*NumNodes;
00991  
00992  /* aloca memória para lista de nós
00993  */
00994  node_list = (CsrNode*) calloc(NumNodes + 1, sizeof(CsrNode));
00995  
00996  /* constroi a lista de nós
00997  */
00998  BuildNodeList(node_list);
00999 
01000  /* constroi a lista de nós
01001  */
01002  BuildNodeList(node_list);
01003  
01004  /* aloca memória para ia*/
01005  ia  = (int*)calloc( nnu + 1, sizeof(int) );
01006  
01007  /* cria o vetor ia*/
01008  BuildIaVec( node_list, ia, nnu, &nna );
01009  
01010  /* aloca memória para ja*/
01011  ja  = (int*)calloc( nna, sizeof(int) );
01012  
01013  /* cria o vetor ia*/
01014  BuildJaVec( node_list, ja );
01015  
01016  /* libera memória da lista de nós
01017  */
01018  FreeNodeList(node_list);
01019  
01020  /* aloca memória para ia*/
01021  avector  = (double*)calloc( nna, sizeof(double) );
01022  
01023  /* cria o vetor avector*/
01024  BuildAVector( ia, ja, avector );
01025  
01026  if(Config.solver == 1){
01027  
01028  /* Mudança de índices necessárias
01029     para utilização do solver SAMG*/
01030   for( i = 0; i < nnu+1; i++ ) {
01031    ia[i] += 1;
01032   }
01033   for( i = 0; i < nna; i++ ) {
01034    ja[i] += 1;
01035   }
01036   
01037  }
01038 
01039 
01040  if(R)
01041   UISetDisplacement(R, NDof, UVector);
01042 
01043 /* Compute the time increment according Cundall (1989)
01044  */
01045  dtime  = Config.dtfrac * _TimeIncrement();
01046 
01047 /* Mount the mass vector
01048  */
01049  MassVector( MVector );
01050  
01051 /* allocate error vector */ 
01052  vetError = (double*)malloc(Config.numsteptol*sizeof(double));
01053 
01054  /* Faz analise para cada passo de carga
01055   */
01056 
01057  iteration = 0;
01058  
01059  Config.loadfactor = (loadstep + 1.0) / Config.num_load_step;
01060  
01061  /* Compute the initial error
01062  */
01063  error0 = InitialError(dtime, FVector, UVector, VVector, UVector0);
01064  
01065  do {
01066   
01067   if(hs){
01068    BFGS( dtime, FVector, UVector, VVector, &iteration, &error, error0, loadstep, nna, nnu, ia, ja, avector );
01069    if(error >= Config.tolerance ){
01070     /* nao convergiu com BFGS, passa para RD */
01071     hs = 0;      
01072     Config.max_iter   = 10000;
01073     Config.numsteptol = 50;
01074     iteration = 0;
01075     free ( vetError );
01076     /* allocate error vector */                                   
01077     vetError = (double*)malloc(Config.numsteptol*sizeof(double));
01078    }
01079   }
01080   if(!hs){   
01081   
01082    /* Compute the rigidity coefficient
01083    */
01084    DampCalcCoeff(DampObj,iteration,dtime,MVector,VVector,&alpha,&CinEng);
01085    
01086    /* Compute displacements and veclocities
01087    */
01088    if( !DisplacementVelocity( iteration, alpha, dtime, 
01089                              FVector, VVector, UVector, MVector ) ) 
01090     return 0;
01091    /*
01092    */
01093    if( R && (iteration%Config.draw_step) )
01094     UIDraw(R);
01095    
01096    /* Update geometry for the larger displacements case
01097    */
01098    if( IsGeomNonLinear )
01099     _UpdateGeometry( dtime, VVector );
01100    
01101    /* Compute the percolation forces
01102    */
01103    if( IsCoupled )
01104     PercolationForces( FVector );
01105    
01106    /* Compute the internal forces
01107    */
01108    InternalForces( dtime, FVector, UVector, VVector );
01109    
01110    /* Compute the dUVector
01111    */
01112    _dUVector(UVector, UVector0, dUVector);
01113     
01114    /* Compute the error
01115    */
01116    error = ComputeError( FVector , dUVector, error0);
01117    
01118    /* For larger displaments correct the time step and compute a new
01119    * mass vector for the model
01120    */
01121    if( IsGeomNonLinear ) {
01122     if( error > 1.0 ) {
01123      dtime = Config.dtfrac * _TimeIncrement();
01124      MassVector( MVector );
01125     }
01126    }
01127    
01128    if( _count_it != NULL )
01129      (*_count_it) ( iteration, error, loadstep);
01130      
01131    if( _fstop != NULL )
01132      (*_fstop) ( &stop );  
01133      
01134    /* Check for another iteration
01135    */
01136    needite = NeedIteration( &error, &iteration, stop );
01137    
01138    fprintf( stdout, "\tStep: %d             Error: %3.3e\r", iteration+1, error );
01139    fflush( stdout );
01140    
01141    if(Config.num_load_step == 1){
01142     /* Save results on a temporary file
01143     */
01144     DrvPrintResult( DrvObj, iteration, UVector, VVector );
01145    }
01146   }
01147  } while( needite );
01148 
01149  if(Config.num_load_step > 1){
01150   /* Save results on a temporary file
01151   */
01152   DrvPrintResult( DrvObj, loadstep, UVector, VVector );
01153  }
01154 
01155  /* free error vector */
01156  free ( vetError );
01157 
01158  fprintf( stdout, "\n\tTotal solver time....................: %lu segs\n\n", (time(NULL)-i_time) );
01159 
01160  printf( "\n" );
01161 
01162  free( dUVector );
01163  free( UVector0 );
01164  free( ia );
01165  free( ja );
01166  free( avector );
01167  
01168  return( 1 );
01169 
01170 } /* End of HSSolver */
01171 
01172 
01173 /*
01174 %F This function reset this packtage.
01175 */
01176 void AlgReset( void )
01177 {
01178   Config.max_iter        = 0;
01179   Config.nonlinear       = 0;
01180   Config.print_step      = 0;
01181   Config.draw_step       = 1;
01182   Config.num_step        = 0;
01183   Config.num_time_step   = 0;
01184   Config.tolerance       = 0.0;
01185   Config.numsteptol      = 50;
01186   Config.dtfrac          = 0.0;
01187   Config.totalTime       = 0.0;
01188   Config.timeStep        = 0.0;  
01189   Config.num_load_step   = 1;
01190   Config.loadfactor      = 1;
01191   Config.algtype         = 0;
01192   Config.numgaussresults =-1;
01193   Config.gaussresults    = NULL;
01194   Config.solver          = 0;
01195 
01196 } /* End of AlgReset */
01197 
01198 
01199 /* =======================================================  End of File  */
01200 

Generated on Tue Oct 23 11:23:28 2007 for Relax by  doxygen 1.5.3