Ejemplo n.º 1
0
    /** Check the filling of EigenMatrix per rows of blocks. Return true if the test succeeds.*/
    bool checkEigenMatrixBlockRowFilling()
    {
        EigenBlockSparseMatrix mb;
        FullMatrix ma;
        unsigned br=3, bc=3;
        ma.resize(br*BROWS,bc*BCOLS);
        mb.resizeBlocks(br,bc);
        for( unsigned i=0; i<br; i++ )
        {
            mb.beginBlockRow(i);
            if( i%2==0 ) // leave some rows empty
            {
                for( int j=bc-1; j>=0; j--) // set the blocs in reverse order, for fun.
                {
                    // create a block and give it some value
                    BlockMN b;
                    for( unsigned k=0; k<BROWS && k<BCOLS; k++ ){
                        b[k][k] = i+j;
                        ma.set(i*BROWS+k, j*BCOLS+k, i+j);
                    }

                    // insert the block in the matrix
                    mb.createBlock(j,b);
                }
            }
            mb.endBlockRow();
        }
        mb.compress();
        //    serr()<<"MatrixTest<Real,RN,CN>::checkEigenMatrixBlockRowFilling, ma = " << ma << endl;
        //    serr()<<"MatrixTest<Real,RN,CN>::checkEigenMatrixBlockRowFilling, mb = " << mb << endl;
        return Sofa_test<_Real>::matricesAreEqual(ma,mb);
    }
Ejemplo n.º 2
0
    /// Create the context for the matrix tests.
    TestSparseMatrices()
    {
        //std::cout<<"Matrix_test "<<NumRows<<" "<<NumCols<<" "<<BlockRows<<" "<<BlockCols<<std::endl;

        // resize and fill the matrices
        generateRandomMat( mat, true );
        copyFromMat( crs1, mat );
        copyFromMat( crs2, mat );
        copyFromMat( fullMat, mat );
        copyFromMat( mapMat, mat );
        copyFromMat( eiBlock1, mat );
        copyFromMat( eiBlock2, mat );
//        copyFromMat( eiBlock3, mat );
        copyFromMat( eiBase, mat );
        eiBlock3.copyFrom(crs1);


        // resize and fill the vectors
        fullVec_ncols.resize(NCOLS);
        fullVec_nrows_reference.resize(NROWS);
        fullVec_nrows_result.resize(NROWS);
        eiVecM.resize(NROWS);
        eiVecN.resize(NCOLS);
        for( unsigned i=0; i<NCOLS; i++)
        {
            fullVec_ncols[i] = i;
            vecN[i] = i;
            eiVecN[i] = i;
        }
        fullMat.mul(fullVec_nrows_reference,fullVec_ncols); //    cerr<<"MatrixTest: vref = " << vref << endl;

        vecM = mat * vecN;




        // matrix multiplication

        generateRandomMat( matMultiplier, true );
        copyFromMat( crsMultiplier, matMultiplier );
        copyFromMat( fullMultiplier, matMultiplier );
        copyFromMat( eiBaseMultiplier, matMultiplier );
        eiDenseMultiplier = Eigen::Map< EigenDenseMatrix >( &(matMultiplier.transposed())[0][0], NCOLS, NROWS ); // need to transpose because EigenDenseMatrix is ColMajor


        matMultiplication = mat * matMultiplier;
        crs1.mul( crsMultiplication, crsMultiplier );
        fullMat.mul( fullMultiplication, fullMultiplier );
        eiBase.mul_MT( eiBaseMultiplication, eiBaseMultiplier ); // sparse x sparse
        eiBase.mul_MT( eiDenseMultiplication, eiDenseMultiplier ); // sparse x dense

        matTransposeMultiplication = mat.multTranspose( mat );
        crs1.mulTranspose( crsTransposeMultiplication, crs1 );
        fullMat.mulT( fullTransposeMultiplication, fullMat );

    }
        void getInverseMatrix(const CellIter&                        c,
                              FullMatrix<Scalar,SP,FortranOrdering>& Binv) const
        {
            // Binv = (N*lambda*K*N'   +   t*diag(A)*(I - Q*Q')*diag(A))/vol
            //         ^                     ^^^^^^^^^^^^^^^^^^^^^^^^^^
            //         precomputed: n_       precomputed: second_term_
            // t = 6/dim * trace(lambda*K)
            int ci = c->index();
            int nf = Binv.numRows();
            ImmutableFortranMatrix n(nf, dim, &n_[ci][0]);
            ImmutableFortranMatrix t2(nf, nf, &second_term_[ci][0]);
            Binv = t2;
            ImmutableFortranMatrix lambdaK(dim, dim, lambdaK_.data());
            SharedFortranMatrix T2(nf, dim, &t2_[0]);

            // T2 <- N*lambda*K
            matMulAdd_NN(Scalar(1.0), n, lambdaK, Scalar(0.0), T2);

            // Binv <- (T2*N' + t*Binv) / vol(c)
            //      == (N*lambda*K*N' + t*(diag(A) * (I - Q*Q') * diag(A))) / vol(c)
            //
            // where t = 6/d * TRACE(lambda*K) (== 2*TRACE(lambda*K) for 3D).
            //
            Scalar t = Scalar(6.0) * trace(lambdaK) / dim;
            matMulAdd_NT(Scalar(1.0) / c->volume(), T2, n,
                         t           / c->volume(), Binv  );
        }
Ejemplo n.º 4
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.º 5
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.º 6
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");
}