⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jacobi.c

📁 工程中有限元程序,采用C语言编制,包括所有经典的有限元问题!
💻 C
字号:
/*****       program jacobi        *****/
/*    generalized jacobi's method      */
/*       for symmetric matrices        */
/*  t.r.chandrupatla and a.d.belegundu */
/***************************************/
#include <stdio.h>
#include <math.h>
main()
{
   FILE *fptr1, *fptr2;
   float *s,*gm,*evl,*evc,c,c1,c2,tols,tolm,aa,bb,cc;
   float cab,bet,alp,sqc,si,sj,emi,emj,sii,sij,sjj,eii,eij,ejj;
   float evi,evj,gm2,omega,freq;
   int *nord,nq,nbw,i,j,k,n,jn,nswmax,k1,i1,nsw,ii,jj,j1,ij,ifl;
   float pi = 3.14159, tol = 0.000001;  
   char dummy[81], file1[81], file2[81];
   printf("\n");
   puts("Input file name < dr:fn.ext >: ");
   gets(file1);
   puts("Output file name < dr:fn.ext >: ");
   gets(file2);
   fptr1 = fopen(file1, "r");
   fptr2 = fopen(file2, "w");
   fgets(dummy,80,fptr1);
   fgets(dummy,80,fptr1);
/* --- read in number of equations and bandwidth --- */
   fscanf(fptr1,"%d %d\n", &nq, &nbw);
   printf("default tolerance is  1e-6\n");      
/* -----         memory allocation         ----- */
   s = (float *) calloc(nq*nq, sizeof(float));
   gm = (float *) calloc(nq*nq, sizeof(float));
   evl = (float *) calloc(nq, sizeof(float));
   evc = (float *) calloc(nq*nq, sizeof(float));
   nord = (int *) calloc(nq, sizeof(int));
/* --------------------------------------------- */

   for (i = 0; i < nq; i++) {
           nord[i] = i;
          }
/* ----- banded stiffness matrix into s(nq,nq) ----- */
   fgets(dummy,80,fptr1);
   for (i = 1; i <= nq; i++) {
         for (jn = 1; jn <= nbw; jn++) {
         fscanf(fptr1, "%f\n", &c);
            j = i + jn - 1;
        if (j <= nq) {
           s[nq*(i-1)+j-1] = c;
               s[nq*(j-1)+i-1] = c;
           }
         }
           }
/* ----- banded mass matrix into gm(nq,nq) ----- */
   fgets(dummy,80,fptr1);
   for (i = 1; i <= nq; i++) {
         for (jn = 1; jn <= nbw; jn++) {
         fscanf(fptr1, "%f\n", &c);
            j = i + jn - 1;
        if (j <= nq) {
           gm[nq*(i-1)+j-1] = c;
               gm[nq*(j-1)+i-1] = c;
           }
         }
           }
     fclose(fptr1);     
  /* ----- initialize eigenvector matrix ----- */
     for (i = 0; i < nq; i++) {
             for (j = 0; j < nq; j++) {
                evc[nq*i+j] = 0;
           }
             evc[nq*i+i] = 1;
            }
         c1 = s[0];
         c2 = gm[0];
     for (i = 0; i < nq; i++) {
        if (c1 > s[nq*i+i])
            c1 = s[nq*i+i];
        if (c2 < gm[nq*i+i])
            c2 = gm[nq*i+i];
        }
     tols = tol * c1;
         tolm = tol * c2;
         nswmax = 50;
     printf("maximum number of sweeps nswmax = 50  ");
     k1 = 1;
         i1 = 1;
         nsw = 0;
  do {
     nsw = nsw + 1;
     if (nsw > nswmax) {
        printf ("no convergence after %d sweeps.", nswmax);
        fprintf (fptr2, "no convergence after %d sweeps.", nswmax);
        fclose(fptr2);
        exit(1);
        }
     printf( "------  sweep number   %d\n", nsw);
     for (k = k1; k < nq; k++) {
         for (i = i1; i <= k; i++) {
         ii = i - 1;
         j = nq - k + i;
         jj = nq - k + i - 1;
       if (fabs(s[nq*ii+jj]) > tols || fabs(gm[nq*ii+jj]) > tolm) {
         aa = s[nq*ii+ii] * gm[nq*ii+jj] - gm[nq*ii+ii] * s[nq*ii+jj];
         bb = s[nq*jj+jj] * gm[nq*ii+jj] - gm[nq*jj+jj] * s[nq*ii+jj];
         cc = s[nq*ii+ii] * gm[nq*jj+jj] - gm[nq*ii+ii] * s[nq*jj+jj];
         cab = .25 * cc * cc + aa * bb;
     if (cab < 0) {
         printf("square root of negative term -- check matrices");
         fprintf(fptr2, "square root of negative term -- check matrices");
         fclose(fptr2);
         exit(2);
        }
     if (aa == 0) {
        bet = 0;
            alp = -s[nq*ii+jj] / s[nq*ii+ii];
        } else if (bb == 0) {
            alp = 0;
                bet = -s[nq*ii+jj] / s[nq*jj+jj];
            } else {
               sqc = sqrt((double) cab);
                   if (cc < 0)
                      sqc = -sqc;
               alp = (-.5 * cc + sqc) / aa;
               bet = -aa * alp / bb;
               }
   /* ----- only upper triangular part is used in diagonalization ----- */
     if (i > 1) {
        for (n = 1; n < i; n++) {
            si = s[nq*(n-1)+ii];
            sj = s[nq*(n-1)+jj];
            emi = gm[nq*(n-1)+ii];
            emj = gm[nq*(n-1)+jj];
            s[nq*(n-1)+ii] = si + bet * sj;
            s[nq*(n-1)+jj] = sj + alp * si;
            gm[nq*(n-1)+ii] = emi + bet * emj;
            gm[nq*(n-1)+jj] = emj + alp * emi;
           }
        }
     if (j < nq) {
        for (n = j + 1; n <= nq; n++) {
           si = s[nq*ii+n-1];
           sj = s[nq*jj+n-1];
           emi = gm[nq*ii+n-1];
           emj = gm[nq*jj+n-1];
           s[nq*ii+n-1] = si + bet * sj;
           s[nq*jj+n-1] = sj + alp * si;
           gm[nq*ii+n-1] = emi + bet * emj;
           gm[nq*jj+n-1] = emj + alp * emi;
           }
        }
     if (i < j) {
        for (n = i + 1; n < j; n++) {
           si = s[nq*ii+n-1];
           sj = s[nq*(n-1)+jj];
           emi = gm[nq*ii+n-1];
           emj = gm[nq*(n-1)+jj];
           s[nq*ii+n-1] = si + bet * sj;
           s[nq*(n-1)+jj] = sj + alp * si;
           gm[nq*ii+n-1] = emi + bet * emj;
           gm[nq*(n-1)+jj] = emj + alp * emi;
           }
         }
     sii = s[nq*ii+ii];
     sij = s[nq*ii+jj];
     sjj = s[nq*jj+jj];
     s[nq*ii+jj] = 0;
     s[nq*ii+ii] = sii + 2 * bet * sij + bet * bet * sjj;
     s[nq*jj+jj] = sjj + 2 * alp * sij + alp * alp * sii;
     eii = gm[nq*ii+ii];
     eij = gm[nq*ii+jj];
     ejj = gm[nq*jj+jj];
     gm[nq*ii+jj] = 0;
     gm[nq*ii+ii] = eii + 2 * bet * eij + bet * bet * ejj;
     gm[nq*jj+jj] = ejj + 2 * alp * eij + alp * alp * eii;
 /* ----- eigenvectors ----- */
     for (n = 0; n < nq; n++) {
         evi = evc[nq*n+ii];
         evj = evc[nq*n+jj];
         evc[nq*n+ii] = evi + bet * evj;
         evc[nq*n+jj] = evj + alp * evi;
        }
             }
          }
         }
     for (k = 1; k < nq; k++) {
         for (i = 1; i <= k; i++) {
             ii = i - 1;
             j = nq - k + i - 1;
         ifl = 0;
        if (fabs(s[nq*ii+j]) > tols || fabs(gm[nq*ii+j]) > tolm) {
           k1 = k;
           i1 = i;
           ifl = 1;
           }
           if (ifl == 1)
             break;
             }
           if (ifl == 1)
             break;
         }
     } while (ifl == 1);
  /* -----  calculation of eigenvalues ----- */
     for (i = 0; i < nq; i++) {
        if (fabs(gm[nq*i+i]) < tolm)
           gm[nq*i+i] = tolm;
        evl[i] = s[nq*i+i] / gm[nq*i+i];
        }
  /* ----- scaling of eigenvectors ----- */
     for (i = 0; i < nq; i++) {
        gm2 = sqrt((double) fabs(gm[nq*i+i]));
        for (j = 0; j < nq; j++) {
           evc[nq*j+i] = evc[nq*j+i] / gm2;
           }
        }
   /* -----   results   ----- */
   /* --- ascending order of eigenvalues --- */
     for (i = 0; i < nq-1; i++) {
        ii = nord[i];
        i1 = ii;
        c1 = evl[ii];
            j1 = i;
        for (j = i+1; j < nq; j++) {
           ij = nord[j];
           if (c1 > evl[ij]) {
              c1 = evl[ij];
                  i1 = ij;
                  j1 = j;
             }
           }
           nord[i] = i1;
           nord[j1] = ii;
        }
 printf("eigenvalues and eigenvectors for data in file %s\n)", file1);
 fprintf(fptr2, "eigenvalues and eigenvectors for data in file %s\n", file1);
     for (i = 0; i < nq; i++) {
        ii = nord[i];
        printf( "eigenvalue number  %d\n ", i+1);
        fprintf(fptr2, "eigenvalue number  %d\n ", i+1);
        c = evl[ii];
            omega = sqrt((double) c);
            freq = .5 * omega / pi;
        printf("eigenvalue = %11.4e",  c);
        fprintf(fptr2, "eigenvalue = %11.4e",  c);
        printf("   omega = %10.3e", omega);
        fprintf(fptr2, "   omega = %10.3e", omega);
        printf("   freq = %10.3e hz\n", freq);
        fprintf(fptr2, "   freq = %10.3e hz\n", freq);
        printf( "eigenvector \n");
        fprintf(fptr2, "eigenvector \n");
        ifl = 0;
        for (j = 0; j < nq; j++) {
           printf( "%10.3e ", evc[nq*j+ii]);
           fprintf(fptr2, "%10.3e ", evc[nq*j+ii]);
           ifl = ifl + 1;
           if (ifl > 5)
              ifl = 0;
           if (ifl == 0) {
             printf( "\n");
                 fprintf(fptr2, "\n");
                 }
           }
        printf("\n");
            fprintf(fptr2, "\n");
        }
        fclose(fptr2);
     return(0);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -