示例#1
0
文件: famg_system.C 项目: rolk/ug
int FAMGSystem::ConstructSimple( FAMGMatrixAlg* stiffmat, FAMGVector* tvA, FAMGVector* tvB )
{
	#ifdef ModelP
	assert(0);	// not for parallel because of Mat/ConMat
	#endif

	FAMGMarkHeap(FAMG_FROM_BOTTOM);
    
    matrix = stiffmat;

#ifdef FAMG_REORDERCOLUMN	
    if(matrix->OrderColumns(colmap)) RETURN(1);    
#endif
	
    char *solver = FAMGGetParameter()->Getsolver();
    SolverPtr = &FAMGSystem::BiCGStab;
    if(strcmp(solver,"bicgstab") == 0)
    {
        SolverPtr = &FAMGSystem::BiCGStab;
    }
    else if(strcmp(solver,"linit") == 0)
    {
        SolverPtr = &FAMGSystem::LinIt;
    }
    else if(strcmp(solver,"gmres") == 0)
    {
        SolverPtr = &FAMGSystem::GMRES;
    }
    else
    {
        ostrstream ostr;
        ostr << __FILE__ << __LINE__ <<  "solver = bicgstab" << endl;
        FAMGWarning(ostr);
    }

    // mg0 supposed to be constructed
    FAMGMultiGrid *mg0 = mg[0];
    if(mg0 == NULL)
		RETURN(1);
#ifdef FAMG_REORDERCOLUMN	
    if(mg0->Order()) RETURN(1);
#endif
	
    return 0;
}
示例#2
0
void MarkStrongLinks(const MT &A, const FAMGGrid &grid)
{
	typedef typename MT::Vector VT;
	const typename MT::GridVector& gridvec = (typename MT::GridVector&)grid.GetGridVector();
	typename MT::MatrixEntry matij;
	typename VT::VectorEntry vi;
	typename VT::Iterator viter(gridvec);

    double rlist[20], llist[20], mij, mji, rmax, lmax;
    int z, y;
    const double sigma = FAMGGetParameter()->Getsigma();
    const int minsl = 2 - 1;

	while (viter(vi))
	{
        for(z = 0; z <= minsl; z++)
        {
            rlist[z] = llist[z] = 0.0;
        }

        typename MT::Iterator mij_iter(A,vi);
        mij_iter(matij); // skip diagonal
        while( mij_iter(matij) )
        {
            mij = Abs(A[matij]);
            mji = Abs(A.GetAdjData(matij));

            for(z = minsl; z >= 0; z--)
            {
                if (mij < rlist[z]) break;
            }
            for(y = minsl; y > z+1; y--)
            { 
                rlist[y] = rlist[y-1];
            }
            if(z+1 <= minsl) rlist[z+1] = mij;

            for(z = minsl; z >= 0; z--)
            {
                if (mji < llist[z]) break;
            }
            for(y = minsl; y > z+1; y--)
            { 
                llist[y] = llist[y-1];
            }
            if(z+1 <= minsl) llist[z+1] = mji;            
        }

        rmax = rlist[minsl]*sigma; 
        lmax = llist[minsl]*sigma; 

        mij_iter.reset();
        mij_iter(matij);
        matij.set_strong(1);
        while( mij_iter(matij) )
        {
            mij = Abs(A[matij]);
            mji = Abs(A.GetAdjData(matij));
            if((mij > rmax) || (mji > lmax)) 
            {
                matij.set_strong(1);
            }
            else matij.set_strong(0);
        }

    }
    
	return;
}
示例#3
0
文件: famg_multigrid.C 项目: rolk/ug
int FAMGMultiGrid::Step(int level)
{    
    // Input:  right hand side, initial guess and defect
    // Output: right hand side, new solution and new defect
    
    FAMGGrid *g, *cg;
    int i,n1,n2,gamma;

    n1 = FAMGGetParameter()->Getn1();
    n2 = FAMGGetParameter()->Getn2();
    gamma = FAMGGetParameter()->Getgamma();
	g = grid[level];
	
    if(gamma < 1)
    {

        for(i = 0; i < n1; i++)
        {
            g->PreSmooth();
            // not necessary any more: g->AddVector(FAMGDEFECT,FAMGUNKNOWN);
            g->Defect();
        }        

        for(i = 0; i < n2; i++)
        {
            g->PostSmooth();
            // not necessary any more: g->AddVector(FAMGDEFECT,FAMGUNKNOWN);
            g->Defect();
        }

        return 0;
    }

    if(level == (n-1))
    { 
        if(g->SolveCoarseGrid())
			RETURN(1);
    }
    else
    {
        cg = grid[level+1];

        for(i = 0; i < n1; i++)
        {
            g->PreSmooth();
            // not necessary any more: g->AddVector(FAMGDEFECT,FAMGUNKNOWN);
            g->Defect();
        }        

        // g->DevideFGDefect(); included in the new restriction
        g->Restriction(*(g->GetVector(FAMGUNKNOWN)), *(g->GetVector(FAMGDEFECT)), *(cg->GetVector(FAMGDEFECT)), *(g->GetVector(FAMGUNKNOWN))/*only as dummy!*/ );
        *(cg->GetVector(FAMGUNKNOWN)) = 0.0;
        *(cg->GetVector(FAMGRHS)) = *(cg->GetVector(FAMGDEFECT));
		for(i = 0; i < gamma; i++) 
			if(Step(level+1)) 
				RETURN(1);
        g->Prolongation(cg, *(cg->GetVector(FAMGUNKNOWN)), *(g->GetVector(FAMGUNKNOWN)), *(g->GetVector(FAMGDEFECT)), NULL);
        // g->Defect(); included in the new restriction

        for(i = 0; i < n2; i++)
        {
            g->PostSmooth();
            // not necessary any more: g->AddVector(FAMGDEFECT,FAMGUNKNOWN);
            g->Defect();
        }

    }
	
    return 0;
}
示例#4
0
文件: famg_multigrid.C 项目: rolk/ug
int FAMGMultiGrid::Construct()
{
    FAMGGrid *g, *cg;
    int level, nnc, nn, ilu, cgilu, leave;
	DOUBLE coarsefrac = 0.0, t, time, cgtime;
	FAMGLeaveInfo myleaveinfo;

    // read parameter
    const int cgnodes = FAMGGetParameter()->Getcgnodes();
#ifdef ModelP
    const int cgminnodespe = FAMGGetParameter()->Getcgminnodespe();
#endif
    const int cglevels = FAMGGetParameter()->Getcglevels();
    const double mincoarse = FAMGGetParameter()->Getmincoarse();
    const int gamma = FAMGGetParameter()->Getgamma();
	if ((strcmp("ilut",FAMGGetParameter()->Getpresmoother()) == 0)
		|| (strcmp("ilut",FAMGGetParameter()->Getpostsmoother()) == 0))  
	{
		ilu = 1; 
	}
	else ilu = 0;
	if (strcmp("ilut",FAMGGetParameter()->Getcgsmoother()) == 0)
	{
		cgilu = 1;
	}
	else cgilu = 0;

	g = grid[0];
#ifdef FAMG_SPARSE_BLOCK
    g->SmoothTV(); 
#else
    g->SmoothTV();
#endif
    FAMGMarkHeap(FAMG_FROM_TOP); // release in Deconstruct
    for(level = 0; level < FAMGMAXGRIDS-1; level++)
    {
		time = CURRENT_TIME;
        // g->SmoothTV();
#ifdef ModelP
		nn  = g->GetNrMasterVectors();	// we are interested only in the master vectors
#else
        nn = g->GetN();
#endif
	
		leave = 0;

		myleaveinfo.coarsefrac = coarsefrac;
		myleaveinfo.cgnodes = nn;
#ifdef ModelP
		myleaveinfo.cgminnodespe = nn;
		GlobalLeave( &myleaveinfo );
#endif

#ifdef XFERTIMING
		XFERTIMING_algtime = 0.0;
		XFERTIMING_algtime_start = CURRENT_TIME;
#endif

		if( myleaveinfo.coarsefrac > mincoarse )
		{
			leave = 1;
			#ifdef ModelP
			if( me==master )	
			#endif
				cout << "FAMG finished; coarsening rate " << 1.0/myleaveinfo.coarsefrac << " < " << 1.0/mincoarse << endl; 
		}

		if( level >= cglevels )
		{
			leave = 1;
			#ifdef ModelP
			if( me==master )	
			#endif
				cout << "FAMG finished; levels " << level << " >= " << cglevels << endl; 
		}

		if( myleaveinfo.cgnodes <= cgnodes )
		{
			leave = 1;
			#ifdef ModelP
			if( me==master )	
			#endif
				cout << "FAMG finished; cg nodes " << myleaveinfo.cgnodes << " <= " << cgnodes << endl; 
		}

#ifdef ModelP
		if( myleaveinfo.cgminnodespe < cgminnodespe )
		{
			leave = 1;
			if( me==master )	
				cout << "FAMG finished; min cg nodes per PE " << myleaveinfo.cgminnodespe << " <= " << cgminnodespe << endl; 
		}
#endif

        if (leave)
			break;

        if (gamma < 1) return 0;	// ModelP: simple return because gamma is known to all processors
#ifdef ModelP
//prv(-level,0);
		g->ConstructOverlap();
//prv(-level,0);
		assert(g->GetNrMasterVectors() == nn );
#endif
        g->Stencil();

#ifdef FAMG_ILU
        if(ilu)
        {
            if (g->ILUTDecomp(0)) 
				RETURN(1);
        }
#endif


#ifdef FAMG_SPARSE_BLOCK
        if (g->ConstructDiagonalInverse()) 
			RETURN(1);       
#endif
        if (g->ConstructTransfer()) 
			RETURN(1);       

#ifdef FAMG_SPARSE_BLOCK
        //        if (g->ConstructDiagonalLump()) 
		// 	RETURN(1);       
#endif

		cgtime = CURRENT_TIME;

        nnc = (g->GetN())-(g->GetNF());
        cg = (FAMGGrid *) FAMGGetMem(sizeof(FAMGGrid),FAMG_FROM_TOP);
        if(cg == NULL)
			RETURN(1);
        if(cg->Init(nnc,*g))
			RETURN(1);
        if(cg->Construct(g))
			RETURN(1);
        grid[n] = cg;
        g = cg;
        n++;
//printf("after Galerkin:\n");
//prm(0,0);prm(0,1); prim(0);
//prm(-1,0);
//prv(-level-1,0);

// for debugging: print some consistent and inconsistent matrices:
//GRID *tmpgrid = cg->GetugGrid();
//int tmplevel = GLEVEL(tmpgrid);
//MATDATA_DESC *tmpA = ((FAMGugMatrix*)cg->GetMatrix())->GetMatDesc();
//MATDATA_DESC *tmpACons = ((FAMGugMatrix*)cg->GetConsMatrix())->GetMatDesc();
//prvGeom(tmplevel,0); primGeom(tmplevel+1); prmGeom(tmplevel,MD_SCALCMP(tmpA));
//if (dmatcopy(MYMG(tmpgrid),tmplevel,tmplevel,ALL_VECTORS,tmpACons,tmpA) != NUM_OK) assert(0);
//if (l_matrix_consistent(tmpgrid,tmpACons,MAT_CONS) != NUM_OK) assert(0);
//prvGeom(tmplevel,0); primGeom(tmplevel+1); prmGeom(tmplevel,MD_SCALCMP(tmpACons));

		t = CURRENT_TIME;
		time = t - time;
		cgtime = t - cgtime;
#ifdef XFERTIMING
		XFERTIMING_algtime += t - XFERTIMING_algtime_start;
#endif

#ifdef ModelP
		cout << me << ": ";
		nnc = cg->GetNrMasterVectors();	// we are interested only in the master vectors
#endif
		coarsefrac = (double)nnc/nn;
		if( nnc <= 0 )
			coarsefrac = 0.000000999;	// dummy
		cout << "amglevel " << -level << " coarsening rate " << 1.0/coarsefrac << " time "<<time<<' '<<cgtime;
#ifdef XFERTIMING
		cout << ' '<<XFERTIMING_algtime;
#endif
		cout << endl;
    }


    if(level == FAMGMAXGRIDS-1)
    {
        ostrstream ostr; ostr << __FILE__ << ", line " << __LINE__ << ": maximum number of levels reached. " << endl;
        FAMGWarning(ostr);
    }
	
    g->Stencil();
#ifdef FAMG_ILU	
    if(cgilu)
    {
        if (g->ILUTDecomp(1)) RETURN(1);
    }
#endif
	
    return 0;
}
示例#5
0
文件: famg_system.C 项目: rolk/ug
int FAMGSystem::Construct( FAMGGridVector *gridvector, FAMGMatrixAlg* stiffmat, FAMGMatrixAlg* Consstiffmat,  FAMGMatrixAlg* diagmatrix, FAMGVector *vectors[FAMGMAXVECTORS] )
{
    FAMGMarkHeap(FAMG_FROM_TOP);
    FAMGMarkHeap(FAMG_FROM_BOTTOM);
	int i;
	
	SetGridVector(gridvector);
    if (mygridvector == NULL)
	{
        ostrstream ostr;
        ostr << __FILE__ << __LINE__ <<  "you must provide a gridvector" << endl;
        FAMGError(ostr);
		RETURN(1);
    }
 
#ifdef USE_UG_DS
	SetFineGrid(((FAMGugGridVector*)gridvector)->GetGrid());
#endif
	
    SetMatrix(stiffmat);
    if (GetMatrix() == NULL)
	{
        ostrstream ostr;
        ostr << __FILE__ << __LINE__ <<  "you must provide a matrix" << endl;
        FAMGError(ostr);
		RETURN(1);
    }

#ifdef FAMG_SPARSE_BLOCK 
    SetDiagMatrix(diagmatrix);
    if (GetDiagMatrix() == NULL)
	{
        ostrstream ostr;
        ostr << __FILE__ << __LINE__ <<  "you must provide a diagonal help matrix" << endl;
        FAMGError(ostr);
		RETURN(1);
    }
#endif
 
    SetConsMatrix(Consstiffmat);
    if (GetConsMatrix() == NULL)
	{
        ostrstream ostr;
        ostr << __FILE__ << __LINE__ <<  "you must provide a consistent matrix" << endl;
        FAMGError(ostr);
		RETURN(1);
    }
 
#ifdef FAMG_REORDERCOLUMN	
    // only for reorder column
    colmap = (int*) FAMGGetMem(famg_interface->n*sizeof(int),FAMG_FROM_TOP);
    if (colmap == NULL) RETURN(1);
    if(GetMatrix()->OrderColumns(colmap)) RETURN(1);
#endif
        
	for ( i=0; i<FAMGMAXVECTORS; i++ )
	{
	    if(vectors[i] == NULL)
    	{
        	ostrstream ostr;
	        ostr << __FILE__ << __LINE__ <<  "you must provide vector " << i << endl;
    	    FAMGError(ostr);
			RETURN(1);
	    }
		vector[i] = vectors[i];
	}
	
    char *solver = FAMGGetParameter()->Getsolver();
    SolverPtr = &FAMGSystem::BiCGStab;
    if(strcmp(solver,"bicgstab") == 0)
    {
        SolverPtr = &FAMGSystem::BiCGStab;
    }
    else if(strcmp(solver,"linit") == 0)
    {
        SolverPtr = &FAMGSystem::LinIt;
    }
    else if(strcmp(solver,"gmres") == 0)
    {
        SolverPtr = &FAMGSystem::GMRES;
    }
    else
    {
        ostrstream ostr;
        ostr << __FILE__ << __LINE__ <<  "solver = bicgstab" << endl;
        FAMGWarning(ostr);
    }

    FAMGMultiGrid *mg0 = CreateMultiGrid();
    if(mg0 == NULL)
		RETURN(1);
    if (mg0->Init(*this))
		RETURN(1);
    if (mg0->Construct())
		RETURN(1);

    return 0;
}