Ejemplo n.º 1
0
void SGSSmoother( VT &sol, const MT &M, VT &def )
// backward Gauss-Seidel
// result in sol_vec; def_vec: correct defect before call, after call destroyed
{
	typename VT::Iterator viter(def); 
	typename VT::RevIterator vReviter(def); 
	typename VT::VectorEntry row, col; 
	typename MT::MatrixEntry me; 
	register double sum, diag;
	int row_index;

    /* symmetric Gauss-Seidel */

	while(viter(row))
	{
		typename MT::Iterator miter(M,row);
		
		row_index = row.GetIndex();
		sum = def[row];
		miter(me);
		diag = M[me];
		while(miter(me))
		{
			col = me.dest();
			if( col.GetIndex() < row_index )
				sum -= M[me] * def[col];
		}
		def[row] = sum / diag;
	}

	viter.reset();
	while(viter(row))
		def[row] *= M.DiagValue(row);
	
	while(vReviter(row))
	{
		typename MT::Iterator miter(M,row);
		
		row_index = row.GetIndex();
		sum = def[row];
		miter(me);
		diag = M[me];
		while(miter(me))
		{
			col = me.dest();
			if( col.GetIndex() > row_index )
				sum -= M[me] * def[col];
		}
		def[row] = sum / diag;
	}

	sol += def;	// update solution
	
	return;
}
Ejemplo n.º 2
0
void JacobiSmoother( VT &sol, const MT &M, const VT &def )
// result in sol_vec; def_vec: correct defect before call, after call destroyed
{
	typename VT::Iterator viter(sol); 
	typename VT::VectorEntry ve; 

	while(viter(ve))
		sol[ve] += def[ve] / M.DiagValue(ve);

	return;
}
Ejemplo n.º 3
0
void JacobiSmoothFG( VT &sol, const MT &M, const VT &def )
// changes only the fine unknowns
// result in sol_vec; def_vec: correct defect before call, after call destroyed
{
	typename VT::Iterator viter(sol); 
	typename VT::VectorEntry ve; 

#ifdef USE_UG_DS
	while(viter(ve))
		if( sol.IsFG(ve) )
			sol[ve] = def[ve] / M.DiagValue(ve);
		else
			sol[ve] = 0;	// init other components
#else
	while(viter(ve))
		if( sol.IsFG(ve) )
			sol[ve] += def[ve] / M.DiagValue(ve);
#endif

	return;
}
Ejemplo n.º 4
0
void dampedJacobiSmoother( VT &sol, const MT &M, const VT &def )
// result in sol_vec; def_vec: correct defect before call, after call destroyed
{
    static const double omega = 2.0/3.0;

	typename VT::Iterator viter(sol); 
	typename VT::VectorEntry ve; 

	while(viter(ve))
		sol[ve] += omega * def[ve] / M.DiagValue(ve);

	return;
}