Ejemplo n.º 1
0
void MatMult(const FullMatrix& A,
        const dTensor1& invec,
        dTensor1& outvec)
{


    for (int i=1; i<=A.get_NumRows(); i++)
    {
        int jmax = A.get_NZrow(i);
        double tmp = 0.0;

        for (int j=1; j<=jmax; j++)
        {
            int ind    = A.get_Index(i,j);
            double val = A.get_Value(i,j);

            tmp = tmp + val*invec.get(ind);
        }
        outvec.set(i, tmp );
    }

}
Ejemplo n.º 2
0
void ConstructA_CG2(const mesh& Mesh, FullMatrix& A)
{
  const int NumPhysElems = Mesh.get_NumPhysElems();
  const int NumBndNodes  = Mesh.get_SubNumBndNodes();
  const int Asize = Mesh.get_SubNumPhysNodes();

  assert_eq(Asize,A.get_NumRows());
  assert_eq(Asize,A.get_NumCols());
  
  dTensor1 A1(6);
  dTensor1 A2(6);
  dTensor1 A3(6);
  dTensor1 A4(6);
  dTensor1 A5(6);
  dTensor1 A6(6);

  A1.set(1, -oneninth     );
  A1.set(2,  4.0*oneninth );
  A1.set(3, -oneninth     );
  A1.set(4,  4.0*oneninth );
  A1.set(5,  4.0*oneninth );
  A1.set(6, -oneninth     );
  
  A2.set(1, -onethird     );
  A2.set(2,  0.0          );
  A2.set(3,  onethird     );
  A2.set(4, -4.0*onethird );
  A2.set(5,  4.0*onethird );
  A2.set(6,  0.0          );
  
  A3.set(1, -onethird     );
  A3.set(2, -4.0*onethird );
  A3.set(3,  0.0          );
  A3.set(4,  0.0          );
  A3.set(5,  4.0*onethird );
  A3.set(6,  onethird     );
  
  A4.set(1,  4.0          );
  A4.set(2, -4.0          );
  A4.set(3,  0.0          );
  A4.set(4, -4.0          );
  A4.set(5,  4.0          );
  A4.set(6,  0.0          );

  A5.set(1,  2.0          );
  A5.set(2, -4.0          );
  A5.set(3,  2.0          );
  A5.set(4,  0.0          );
  A5.set(5,  0.0          );
  A5.set(6,  0.0          );
  
  A6.set(1,  2.0          );
  A6.set(2,  0.0          );
  A6.set(3,  0.0          );
  A6.set(4, -4.0          );
  A6.set(5,  0.0          );
  A6.set(6,  2.0          );

  dTensor2 spts(3,2);
  spts.set(1,1,  1.0/3.0 );
  spts.set(1,2, -1.0/6.0 );
  
  spts.set(2,1, -1.0/6.0 );
  spts.set(2,2, -1.0/6.0 );
  
  spts.set(3,1, -1.0/6.0 );
  spts.set(3,2,  1.0/3.0 );
  
  dTensor1 wgts(3);
  wgts.set(1, 1.0/6.0 );
  wgts.set(2, 1.0/6.0 );
  wgts.set(3, 1.0/6.0 );
  
  // Loop over all elements in the mesh
  for (int i=1; i<=NumPhysElems; i++)
    {
      // Information for element i
      iTensor1 tt(6);
      for (int k=1; k<=6; k++)
	{  tt.set(k, Mesh.get_node_subs(i,k) );  }
      
      // Evaluate gradients of the Lagrange polynomials on Gauss quadrature points      
      dTensor2 gpx(6,3);
      dTensor2 gpy(6,3);
      
      for (int m=1; m<=3; m++)
	{
	  double  xi = spts.get(m,1);
	  double eta = spts.get(m,2);
	  
	  for (int k=1; k<=6; k++)
	    {
	      double gp_xi  = A2.get(k) + 2.0*A5.get(k)*xi + A4.get(k)*eta;
	      double gp_eta = A3.get(k) + A4.get(k)*xi + 2.0*A6.get(k)*eta;

	      gpx.set(k,m, Mesh.get_jmat(i,1,1)*gp_xi
		         + Mesh.get_jmat(i,1,2)*gp_eta );
	      gpy.set(k,m, Mesh.get_jmat(i,2,1)*gp_xi
		         + Mesh.get_jmat(i,2,2)*gp_eta );
	    }
	}

      // Entries of the stiffness matrix A
      double Area = Mesh.get_area_prim(i);
      for (int j=1; j<=6; j++)
	for (int k=1; k<=6; k++)
	  {
	    double tmp = A.get(tt.get(j),tt.get(k));
	    for (int m=1; m<=3; m++)
	      {
		tmp = tmp + 2.0*Area*wgts.get(m)*(gpx.get(j,m)*gpx.get(k,m)+gpy.get(j,m)*gpy.get(k,m));
	      }
	    A.set(tt.get(j),tt.get(k), tmp );
	  }
    }

  // Replace boundary node equations by Dirichlet boundary condition enforcement
  for (int i=1; i<=NumBndNodes; i++)
    {
      const int j=Mesh.get_sub_bnd_node(i);
      
      for (int k=1; k<=A.get_NumCols(); k++)
	{
	  A.set(j,k, 0.0 );	  
	}
      for (int k=1; k<=A.get_NumRows(); k++)
	{
	  A.set(k,j, 0.0 );
	}
      A.set(j,j, 1.0 );
    }

  // Get sparse structure representation
  A.Sparsify();
  
}
Ejemplo n.º 3
0
void ConjugateGradient(const int MaxIters,
        const double TOL,
        const FullMatrix& A,
        const dTensor1& rhs,
        dTensor1& phi)
{
    double DotProd(const dTensor1& avec,
            const dTensor1& bvec);
    void MatMult(const FullMatrix& A,
            const dTensor1& invec,
            dTensor1& outvec);
    const int size = A.get_NumRows();
    int NumIters  = 0;
    int mflag = 0;

    dTensor1 r(size);
    dTensor1 d(size);
    dTensor1 Ad(size);

    for (int i=1; i<=size; i++)
    {  phi.set(i, 0.0 );  }

    MatMult(A,phi,r);

    for (int i=1; i<=size; i++)
    {  r.set(i, rhs.get(i)-r.get(i) );  }

    for (int i=1; i<=size; i++)
    {  d.set(i, r.get(i) );  }

    double rhs_norm = sqrt(DotProd(rhs,rhs));
    if (fabs(rhs_norm)<=1.0e-12)
    { rhs_norm = 1.0; }
    //printf(" rhs_norm = %e\n",rhs_norm);

    double rdotr = DotProd(r,r);
    //printf(" sqrt(rdotr) = %e\n",sqrt(rdotr));

    double rel_res_norm = sqrt(rdotr)/rhs_norm;
    if(rel_res_norm < TOL)
    {  mflag = 1; }

    NumIters = 1;
    while(mflag==0)
    {
        MatMult(A,d,Ad);
        double alpha = rdotr/DotProd(d,Ad);

        for (int i=1; i<=size; i++)
        {  phi.set(i, phi.get(i)+alpha*d.get(i) );  }

        for (int i=1; i<=size; i++)
        {  r.set(i, r.get(i)-alpha*Ad.get(i) );  }

        double rdotr_old = rdotr;
        rdotr = DotProd(r,r);

        rel_res_norm = sqrt(rdotr)/rhs_norm;
        if(rel_res_norm < TOL)
        {  mflag = 1;  }

        //printf("   NumIters = %i,   rel_res_norm = %e\n",NumIters,rel_res_norm);

        if (NumIters==MaxIters)
        {  mflag = 1;  }

        if (mflag==0)
        {
            double beta = rdotr/rdotr_old;

            for (int i=1; i<=size; i++)
            {  d.set(i, r.get(i)+beta*d.get(i) );  }

            NumIters = NumIters+1;
        }
    }

    printf("  |----------------------------\n");
    printf("  | Conjugate Gradient Results:\n");
    printf("  |----------------------------\n");
    printf("  |  MaxIters = %i\n",MaxIters);
    printf("  |       TOL = %e\n",TOL);
    printf("  |  NumIters = %i\n",NumIters);
    printf("  |  residual = %e\n",rel_res_norm);
    printf("  |----------------------------\n");
    printf("\n");
}