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

📄 emap4.c

📁 计算电磁学的3维矢量有限元方法通用的原程序
💻 C
📖 第 1 页 / 共 5 页
字号:
complex *XVec,*AVec,**RIDat;

{
int II,JJ,KK;

for(II=0;II<Size;II++) 
   {
   AVec[II]=COMplex_Null();
   }

if(S==' ') /* Multiply matrix with vector */
   {
   for(II=0;II<Size;II++)
      {
      for(KK=0;KK<RIIndex[II];KK++) 
         {
         JJ = RICol[II][KK];
         AVec[II] = COMplex_Add(AVec[II],COMplex_Mul(RIDat[II][KK],XVec[JJ]));
         }
      }
   }
else /* Multiply hermitian of matrix with vector */
     /* Here the matrix is symmetric, so we don't need to transpose */
     /* Only conjugate */
   {
   for(II=0;II<Size;II++)
      {
      for(KK=0;KK<RIIndex[II];KK++) 
         {
         JJ = RICol[II][KK];
         AVec[II] = COMplex_Add(AVec[II],COMplex_Mul(
				COMplex_Conjg(RIDat[II][KK]),XVec[JJ]));
         }
      }
   }
}

/****************************Main routine************************************/

void ConjugateSolver(MatrixSize,RowIIndex,RowICol,RowIDat,RHSVec,ITmax,TOL)

int ITmax,MatrixSize,**RowICol,*RowIIndex; 
complex *RHSVec,**RowIDat; 
double TOL;

{
int      II,JJ,IterIndex;
double   Residue,Vnrm;

printf("\n %d ",freq_step);
if(freq_step == 0) /* Only for the first frequency step */
   {
   X     = CMPLX_Vector(MatrixSize);
   P     = CMPLX_Vector(MatrixSize);
   PP    = CMPLX_Vector(MatrixSize);
   R     = CMPLX_Vector(MatrixSize);
   RR    = CMPLX_Vector(MatrixSize);
   A_P   = CMPLX_Vector(MatrixSize);
   AH_PP = CMPLX_Vector(MatrixSize);
   }

for(II=0;II<MatrixSize;II++) 
   {
   X[II]     = COMplex_Null();
   P[II]     = COMplex_Null();
   PP[II]    = COMplex_Null();
   R[II]     = COMplex_Null();
   RR[II]    = COMplex_Null();
   A_P[II]   = COMplex_Null();
   AH_PP[II] = COMplex_Null();
   } 
/* for debugging */
/* for (II=0;II<MatrixSize;II++) */
/*    { */
/*    for(JJ=0;JJ<RowIIndex[II];JJ++) */
/*      { */
/*printf("%d %f %f \n",RowICol[II][JJ],RowIDat[II][JJ].x,RowIDat[II][JJ].y); */
/*      } */
/*    printf("\n %d %d\n",InnerEdgeStat[II], II); */
/*    } */


/* Initialization */

MatrixVectorProd(' ',MatrixSize,X,R,RowIIndex,RowICol,RowIDat);

for(II=0;II<MatrixSize;II++) 
   {
   R[II]  = COMplex_Sub(RHSVec[II],R[II]);
   P[II]  = R[II];
   RR[II] = COMplex_Conjg(R[II]);
   PP[II] = RR[II];
   } 
/*for(II=0;II<MatrixSize;II++) 
   {
   printf(" R = %f %f",R[II].x,R[II].y);
   printf(" RR = %f %f \n ",RR[II].x,RR[II].y);
   printf(" P = %f %f",P[II].x,P[II].y);
   printf(" PP = %f %f \n",PP[II].x,PP[II].y);
   } 
*/
Vnrm = Vnorm(RHSVec,MatrixSize);

IterIndex = 0;

/* Actual Iteration */

for(;;)
   {

   MatrixVectorProd(' ',MatrixSize,P,A_P,RowIIndex,RowICol,RowIDat);
  
   for(II=0;II<MatrixSize;II++)
      {
      AH_PP[II] = COMplex_Conjg(A_P[II]); 
      }

   Alpha = Inner_Prod(RR,R,MatrixSize);
   temp_var = Inner_Prod(PP,A_P,MatrixSize);
   Alpha = COMplex_Div(Alpha,temp_var);  
   /* Alpha is the step length parameter */

   
   for(II=0;II<MatrixSize;II++)  
      {
      /* New Solution Estimate */
      X[II]  = COMplex_Add(X[II],COMplex_Mul(Alpha,P[II]));   
      R[II]  = COMplex_Sub(R[II],COMplex_Mul(Alpha,A_P[II])); /* Residual */
      RR[II] = COMplex_Sub(RR[II],COMplex_Mul(COMplex_Conjg(Alpha),AH_PP[II]));
      /* Bi-residual */
      }
      
   Beta = Inner_Prod(AH_PP,R,MatrixSize);
   Beta = COMplex_Div(Beta,temp_var);
   Beta = Real_Mul(-1.0,Beta);   /* Beta is the Bi-Conjugacy coefficient  */


   for(II=0;II<MatrixSize;II++)  
      {
      P[II]  = COMplex_Add(R[II],COMplex_Mul(Beta,P[II]));   /* Direction */
      PP[II] = COMplex_Add(RR[II],COMplex_Mul(COMplex_Conjg(Beta),PP[II])); 
      /* Bi-Direction */
      }

   IterIndex = IterIndex + 1; /* Next iteration */
   Residue = sqrt(Vnorm(R,MatrixSize)/Vnrm);
   /* printf("Iteration = %d Residue = %e TOL = %e\n",IterIndex,Residue,TOL); */
/*    fflush(stdout); */
   if(Residue<=TOL)  /* Test termination condition */
      {
      printf("Convergence achieved\n");
      printf("Iteration = %d Residue = %e TOL = %e\n",IterIndex,Residue,TOL);
      fflush(stdout);
      break;
      }
   else if(IterIndex==ITmax)  /* No. of iterations has exceeded the limit */
      { 
      printf("Iteration Exceeds\n"); 
      fflush(stdout);
      break;
      }
   else 
      { 
      continue ; 
      }
   }/* End of for loop*/
for(II=0;II<MatrixSize;II++) 
   {
   RHSVec[II] = X[II];
   Old_Solution[II] = X[II]; /* Starting point for next iteration */
   }
}


/***************************************************************************
*   FUNCTION        : Read_Input_Pass_1()
****************************************************************************/

void Read_Input_Pass_1()
{
 int    x1, y1, z1, x2, y2, z2, p, p1, p2, OutF_Count=0, output_flag=0;
 char   type[20], att1[20], att2[18], att3[18], att4[18];
 float  tmp1, tmp2;
 double freq = 0;
 char   buffer[80];

 Min_X = 10000; Min_Y=10000; Min_Z=10000;
 Max_X = 0;     Max_Y=0;     Max_Z=0;

   while (fgets(buffer, 80, InF))
   {
        if (buffer[0] == '#') continue; /* Comment statement */
	if(!strncmp(buffer, "freqstep",8)) /* freqstep keyword */
        	   {
		   sscanf(buffer, "%s%d%s",type, &NUM_OF_STEPS, att1);
		   FREQ_INC = atof(att1); /* Convert from string to float */
		   printf("N0. of steps%d inc%f\n",NUM_OF_STEPS,FREQ_INC);
		   continue;
 		   }
        if(!strncmp(buffer, "default_output",14))/*keyword for default output*/
                   {
                   sscanf(buffer, "%s%s", type, Out_FileName0);
                   OutF_0=fopen(Out_FileName0, "w");
                   if (OutF_0 == NULL) 
		     {
		     fprintf(stderr, 
		     " Error: Can't create default output file %s\n",
		     Out_FileName0); 
		     exit(1);
		     }
                   output_flag=1;
                   continue;
                   }
        if(!strncmp(buffer, "celldim", 7)) { /* celldim keyword */
                                              continue;
                                            }


        if(sscanf(buffer, "%s%d%d%d%d%d%d%s%s%s%s", 
		  type, &x1, &y1, &z1, &x2, &y2, &z2, 
		  att1, att2, att3, att4)>2)
           {
              if(!strcmp(type,"boundary")) {
		fprintf(stderr, 
"\n\nERROR: boundary keyword is not allowed by EMAP4 \n"); 
		exit(1);}
              if(!strcmp(type, "dielectric"))/* dielectric block */
              {
               if (x1<Min_X) Min_X=x1; 
	       if (x2<Min_X) Min_X=x2; 
	       if (x1>Max_X) Max_X=x1; 
	       if (x2>Max_X) Max_X=x2;
               if (y1<Min_Y) Min_Y=y1; 
	       if (y2<Min_Y) Min_Y=y2; 
	       if (y1>Max_Y) Max_Y=y1; 
	       if (y2>Max_Y) Max_Y=y2;
               if (z1<Min_Z) Min_Z=z1; 
	       if (z2<Min_Z) Min_Z=z2; 
	       if (z1>Max_Z) Max_Z=z1; 
	       if (z2>Max_Z) Max_Z=z2;
               if((x1==x2)||(y1==y2)||(z1==z2)) 
		 {fprintf(stderr, "ERROR:  diel thickness is not finite./n");
               exit(1); } continue;
              }
              if(!strcmp(type, "PML")) /* Perfectly matched layer */
              {
               if (x1<Min_X) Min_X=x1; 
	       if (x2<Min_X) Min_X=x2; 
	       if (x1>Max_X) Max_X=x1; 
	       if (x2>Max_X) Max_X=x2;
               if (y1<Min_Y) Min_Y=y1; 
	       if (y2<Min_Y) Min_Y=y2; 
	       if (y1>Max_Y) Max_Y=y1; 
	       if (y2>Max_Y) Max_Y=y2;
               if (z1<Min_Z) Min_Z=z1; 
	       if (z2<Min_Z) Min_Z=z2; 
	       if (z1>Max_Z) Max_Z=z1; 
	       if (z2>Max_Z) Max_Z=z2;
               if((x1==x2)||(y1==y2)||(z1==z2)) 
		 {
		 fprintf(stderr, "ERROR:  PML thickness is not finite./n");
                 exit(1); 
	         } continue;
              }
              if(!strcmp(type, "box")) /* rectangular conducting box */
              {
                   if((x1==x2)||(y1==y2)||(z1==z2)){ 
		     fprintf(stderr, "ERROR: box dimension is invalid.");
                   exit(1);}
                   if (x1<Min_X) Min_X=x1; 
		   if (x2<Min_X) Min_X=x2; 
		   if (x1>Max_X) Max_X=x1; 
		   if (x2>Max_X) Max_X=x2;
                   if (y1<Min_Y) Min_Y=y1; 
		   if (y2<Min_Y) Min_Y=y2; 
		   if (y1>Max_Y) Max_Y=y1; 
		   if (y2>Max_Y) Max_Y=y2;
                   if (z1<Min_Z) Min_Z=z1; 
		   if (z2<Min_Z) Min_Z=z2; 
		   if (z1>Max_Z) Max_Z=z1; 
		   if (z2>Max_Z) Max_Z=z2;
                   continue;
              }
              if(!strcmp(type,"conductor")) /* PEC */
              {
                   if (x1<Min_X) Min_X=x1; 
		   if (x2<Min_X) Min_X=x2; 
		   if (x1>Max_X) Max_X=x1; 
		   if (x2>Max_X) Max_X=x2;
                   if (y1<Min_Y) Min_Y=y1; 
		   if (y2<Min_Y) Min_Y=y2; 
		   if (y1>Max_Y) Max_Y=y1; 
		   if (y2>Max_Y) Max_Y=y2;
                   if (z1<Min_Z) Min_Z=z1; 
		   if (z2<Min_Z) Min_Z=z2; 
		   if (z1>Max_Z) Max_Z=z1; 
		   if (z2>Max_Z) Max_Z=z2;
                   continue;
              }
              if(!strcmp(type,"resistor")) /* resistor */
              {
		if (x1<Min_X) Min_X=x1; 
		if (x2<Min_X) Min_X=x2; 
		if (x1>Max_X) Max_X=x1; 
		if (x2>Max_X) Max_X=x2;
                if (y1<Min_Y) Min_Y=y1; 
		if (y2<Min_Y) Min_Y=y2; 
		if (y1>Max_Y) Max_Y=y1; 
		if (y2>Max_Y) Max_Y=y2;
                if (z1<Min_Z) Min_Z=z1; 
		if (z2<Min_Z) Min_Z=z2; 
		if (z1>Max_Z) Max_Z=z1; 
		if (z2>Max_Z) Max_Z=z2;
                   continue;
              }
              if(!strcmp(type, "aperture")) /* aperture */
              {
                   if((x1!=x2) & (y1!=y2) & (z1!=z2))
		     {
		     fprintf(stderr,"ERROR: aperture dimension is invalid.\n");
                     exit(1); 
		     }
                   if(((x1==x2)&&(y1==y2))||((x1==x2)&&(z1==z2))
		                          ||((z1==z2)&&(y1==y2)))
                   {
		   fprintf(stderr, "ERROR: aperture dimension is invalid.\n"); 
		   exit(1); }
                   continue;
              }
              if(!strcmp(type, "seam")) continue; /* Not available */
              if(!strcmp(type,"esource")) /* electric field source */
              {
                   if (x1<Min_X) Min_X=x1; 
		   if (x2<Min_X) Min_X=x2; 
		   if (x1>Max_X) Max_X=x1; 
		   if (x2>Max_X) Max_X=x2;
                   if (y1<Min_Y) Min_Y=y1; 
		   if (y2<Min_Y) Min_Y=y2; 
		   if (y1>Max_Y

⌨️ 快捷键说明

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