source: trunk/LMDZ.TITAN/libf/chimtitan/solve.c @ 201

Last change on this file since 201 was 3, checked in by slebonnois, 14 years ago

Creation de repertoires:

  • chantiers : pour communiquer sur nos projets de modifs
  • documentation : pour stocker les docs

Ajout de:

  • libf/phytitan : physique de Titan
  • libf/chimtitan: chimie de Titan
  • libf/phyvenus : physique de Venus
File size: 3.6 KB
Line 
1/* matrix inversion */
2/* cf Numerical Recipes LU Method for equations numbers */
3/* GCCM */
4/* une seule cellule concernee */
5/* la matrice a est inversee seulement sur le bloc [n0;n1][n0;n1] */
6/* la matrice f ressort les dy */
7
8#include "titan.h"
9
10void solve( double **a, double *f, int n0, int n1 )
11{
12   int    i,ii,imax,k,l,ll;
13   double aamax,dum,*indx,sum,*vv,tmp;
14   FILE   *out;
15
16   indx = dm1d( n0, n1 );
17   vv   = dm1d( n0, n1 );
18   imax = n0;
19
20   for( i = n0; i <= n1; i++ )
21   {
22      aamax = 0.0e0;
23      for( k = n0; k <= n1; k++ )
24         if( (tmp=fabs(a[i][k])) > aamax ) aamax = tmp;
25      if( aamax < 1.0e-20 )
26      {
27         out = fopen( "err.log", "a" );
28         fprintf( out, "Singular matrix. n0=%ld k=%ld aamax=%le\n",
29                        n0,k,aamax);
30         fclose( out );
31         exit(0);   
32/*         aamax = 1.e-30; */
33      }
34      vv[i] = 1.0e0 / aamax;   /* Save the scaling */
35/*
36      if( (aamax > 1.0e100)||(aamax < 1.0e-100) )
37      {
38         out = fopen( "err.log", "a" );
39         fprintf( out, "ATTENTION aamax = %le\n", aamax );
40         fclose( out );
41         exit( 0 );
42      }
43*/
44   }
45   for( k = n0; k <= n1; k++ )
46   {
47      for( i = n0; i < k; i++ )      /* This is equation 2.3.12 except for i = j */
48      {
49         sum = a[i][k];
50         for( l = n0; l < i; l++ )
51            sum -= ( a[i][l] * a[l][k] );
52         a[i][k] = sum;
53      }
54      aamax = 0.0e0;                 /* Initialize for the search for largest pivot element */
55      for( i = k; i <= n1; i++ )     /* This is i = j of equation 2.3.12 and */
56      {
57         sum = a[i][k];              /* i = J + 1,...,N of equation 2.3.13 */
58         for( l = n0; l < k; l++ )
59            sum -= ( a[i][l] * a[l][k] );
60         a[i][k] = sum;
61         dum        = vv[i] * fabs(sum);   /* Figure of merit for the pivot */
62         if( dum >= aamax )          /* Is it better than the best so far ? */
63         {
64            imax  = i;
65            aamax = dum;
66         }
67      }
68      if( k != imax )                /* Do we need to interchange rows ? */
69      {
70         for( l = n0; l <= n1; l++ ) /* Yes, do so... */
71         {
72            dum        = a[imax][l];
73            a[imax][l] = a[k][l];
74            a[k][l]    = dum;
75         }
76         vv[imax] = vv[k];    /* Also interchange the scale factor */
77      }
78      indx[k] = imax;
79      if( fabs(a[k][k]) < 1.0e-20 )
80      {
81         out = fopen( "err.log", "a" );
82         fprintf( out, "Pivot too small. n0=%ld k=%ld fabs(a[k][k])=%le\n",
83                        n0,k,fabs(a[k][k]) );
84         fclose( out );
85         exit(0);   
86/*         a[k][k] = 1.e-20; */
87      }
88      if( k != n1 )                   /* If the pivot element is less than 1.0d-20 we */
89      {                               /* assume that the matrix is singular */
90          dum = a[k][k];              /* ( at least to the precision of the algorithm and the machine ) */
91         for( i = k+1; i <= n1; i++ ) /* Now, finally devide by the pivot element */
92            a[i][k] /= dum;
93      }
94   }                                  /* Go back to the next column in the reduction */
95
96      ii = n0-1;
97      for( i = n0; i <= n1; i++ )
98      {
99         ll    = indx[i];
100         sum   = f[ll];
101         f[ll] = f[i];
102         if( ii != (n0-1) )
103            for( k = ii; k < i; k++ )
104               sum -= ( a[i][k] * f[k] );
105         else if( sum != 0.0e0 ) ii = i;
106         f[i] = sum;
107      }
108      for( i = n1; i >= n0; i-- )
109      {
110         sum = f[i];
111         if( i < n1 )
112            for( k = i+1; k <= n1; k++ )
113               sum -= ( a[i][k] * f[k] );
114         f[i] = sum / a[i][i];
115      }
116         
117   fdm1d( indx, n0 );
118   fdm1d(   vv, n0 );
119}
Note: See TracBrowser for help on using the repository browser.