dolfin team mailing list archive
-
dolfin team
-
Mailing list archive
-
Message #00010
Re: patch till dolfin
Great, I will apply the patch when I get back from my vacation.
What about GMRES?
/Anders
On Thu, Jul 01, 2004 at 12:22:25PM +0200, Erik Svensson wrote:
> Här kommer en patch.
>
> Gjorda tillägg i: FGMRES, GaussSeidle och LinearSolver.
>
> /Erik
>
> ? Makefile
> ? config.log
> ? config.status
> ? dolfin-erik-2004-07-01.patch
> ? src/Makefile
> ? src/config/Makefile
> ? src/config/dolfin-config
> ? src/config/var.tmp
> ? src/demo/Makefile
> ? src/demo/bench/dolfin-bench
> ? src/demo/elementfunction/dolfin-elementfunction
> ? src/demo/fem/dolfin-fem
> ? src/demo/la/generic_matrix/dolfin-la-generic_matrix
> ? src/demo/la/test/dolfin-test
> ? src/demo/mesh/dolfin-mesh
> ? src/demo/ode/dolfin-tanganyika
> ? src/demo/quadrature/dolfin-quadrature
> ? src/demo/solvers/Makefile
> ? src/demo/solvers/convdiff/dolfin-convdiff
> ? src/demo/solvers/elasticity/dolfin-elasticity
> ? src/demo/solvers/elasticity-stationary/dolfin-elasticity-stationary
> ? src/demo/solvers/euler/dolfin-euler
> ? src/demo/solvers/heat/dolfin-heat
> ? src/demo/solvers/navierstokes/Makefile
> ? src/demo/solvers/navierstokes/benchmark/dolfin-navierstokes-benchmark
> ? src/demo/solvers/ode/Makefile
> ? src/demo/solvers/ode/bench/dolfin-ode-bench
> ? src/demo/solvers/ode/bistable/dolfin-ode-bistable
> ? src/demo/solvers/ode/lorenz/dolfin-lorenz
> ? src/demo/solvers/ode/mechanical/Makefile
> ? src/demo/solvers/ode/mechanical/spring/dolfin-ode-spring
> ? src/demo/solvers/ode/modeling/Makefile
> ? src/demo/solvers/ode/modeling/lattice/dolfin-ode-modeling-lattice
> ? src/demo/solvers/ode/modeling/simple/dolfin-ode-modeling-simple
> ? src/demo/solvers/ode/newton/dolfin-ode-newton
> ? src/demo/solvers/ode/performance/dolfin-ode-perf-test
> ? src/demo/solvers/ode/stiff/stabilization/dolfin-ode-stiff-stabilization
> ? src/demo/solvers/ode/stiff/testproblems/dolfin-ode-stiff-testproblems
> ? src/demo/solvers/ode/test/dolfin-ode-test
> ? src/demo/solvers/poisson/dolfin-poisson
> ? src/demo/solvers/poisson-multigrid/dolfin-poisson-multigrid
> ? src/demo/solvers/template/dolfin-template
> ? src/demo/solvers/wave/dolfin-wave
> ? src/demo/solvers/wave-vector/dolfin-wavevector
> ? src/demo/test/dolfin-test
> ? src/greeting/Makefile
> ? src/greeting/var.tmp
> ? src/kernel/Makefile
> ? src/kernel/common/.deps
> ? src/kernel/common/Makefile
> ? src/kernel/common/dolfin/Makefile
> ? src/kernel/element/.deps
> ? src/kernel/element/Makefile
> ? src/kernel/element/dolfin/Makefile
> ? src/kernel/fem/.deps
> ? src/kernel/fem/dolfin/Makefile
> ? src/kernel/form/.deps
> ? src/kernel/form/Makefile
> ? src/kernel/form/dolfin/Makefile
> ? src/kernel/function/.deps
> ? src/kernel/function/Makefile
> ? src/kernel/function/dolfin/Makefile
> ? src/kernel/io/.deps
> ? src/kernel/io/Makefile
> ? src/kernel/io/dolfin/Makefile
> ? src/kernel/la/.deps
> ? src/kernel/la/Makefile
> ? src/kernel/la/dolfin/Makefile
> ? src/kernel/log/.deps
> ? src/kernel/log/Makefile
> ? src/kernel/log/dolfin/Makefile
> ? src/kernel/main/.deps
> ? src/kernel/main/Makefile
> ? src/kernel/main/dolfin_modules.h
> ? src/kernel/main/dolfin/Makefile
> ? src/kernel/map/.deps
> ? src/kernel/map/Makefile
> ? src/kernel/map/dolfin/Makefile
> ? src/kernel/math/.deps
> ? src/kernel/math/Makefile
> ? src/kernel/math/dolfin/Makefile
> ? src/kernel/mesh/.deps
> ? src/kernel/mesh/Makefile
> ? src/kernel/mesh/dolfin/Makefile
> ? src/kernel/ode/.deps
> ? src/kernel/ode/Makefile
> ? src/kernel/ode/dolfin/Makefile
> ? src/kernel/quadrature/.deps
> ? src/kernel/quadrature/Makefile
> ? src/kernel/quadrature/dolfin/Makefile
> ? src/kernel/settings/.deps
> ? src/kernel/settings/Makefile
> ? src/kernel/settings/dolfin/Makefile
> ? src/modules/Makefile
> ? src/modules/modules.list
> ? src/modules/convdiff/.deps
> ? src/modules/convdiff/Makefile
> ? src/modules/elasticity/.deps
> ? src/modules/elasticity/Makefile
> ? src/modules/elasticity-stationary/.deps
> ? src/modules/elasticity-stationary/Makefile
> ? src/modules/euler/.deps
> ? src/modules/euler/Makefile
> ? src/modules/heat/.deps
> ? src/modules/heat/Makefile
> ? src/modules/navierstokes/.deps
> ? src/modules/navierstokes/Makefile
> ? src/modules/odesolver/.deps
> ? src/modules/odesolver/Makefile
> ? src/modules/poisson/.deps
> ? src/modules/poisson/Makefile
> ? src/modules/poisson-multigrid/.deps
> ? src/modules/poisson-multigrid/Makefile
> ? src/modules/template/.deps
> ? src/modules/template/Makefile
> ? src/modules/wave/.deps
> ? src/modules/wave/Makefile
> ? src/modules/wave-vector/.deps
> ? src/modules/wave-vector/Makefile
> ? src/post/Makefile
> ? src/pre/Makefile
> ? src/utils/Makefile
> ? src/utils/inp2dx/.deps
> ? src/utils/inp2dx/Makefile
> ? src/utils/inp2dx/inp2dx
> ? src/utils/inp2dx/inp2dxanim
> Index: src/demo/la/Makefile
> ===================================================================
> RCS file: /cvs/dolfin/src/demo/la/Makefile,v
> retrieving revision 1.128
> diff -r1.128 Makefile
> 19c19
> < prefix = /usr/local
> > prefix = /home/erik/local
> 65c65
> < CXXFLAGS = -g -O2
> > CXXFLAGS = -DDEBUG=1 -g -O2 -Wall -Werror -pedantic -ansi -std=c++98
> Index: src/demo/solvers/ode/stiff/Makefile
> ===================================================================
> RCS file: /cvs/dolfin/src/demo/solvers/ode/stiff/Makefile,v
> retrieving revision 1.83
> diff -r1.83 Makefile
> 19c19
> < prefix = /usr/local
> > prefix = /home/erik/local
> 65c65
> < CXXFLAGS = -g -O2
> > CXXFLAGS = -DDEBUG=1 -g -O2 -Wall -Werror -pedantic -ansi -std=c++98
> Index: src/kernel/fem/Makefile
> ===================================================================
> RCS file: /cvs/dolfin/src/kernel/fem/Makefile,v
> retrieving revision 1.131
> diff -r1.131 Makefile
> 19c19
> < prefix = /usr/local
> > prefix = /home/erik/local
> 65c65
> < CXXFLAGS = -g -O2
> > CXXFLAGS = -DDEBUG=1 -g -O2 -Wall -Werror -pedantic -ansi -std=c++98
> Index: src/kernel/la/FGMRES.cpp
> ===================================================================
> RCS file: /cvs/dolfin/src/kernel/la/FGMRES.cpp,v
> retrieving revision 1.1
> diff -r1.1 FGMRES.cpp
> 4a5,6
> > #include <dolfin/dolfin_math.h>
> > #include <dolfin/dolfin_settings.h>
> 5a8,9
> > #include <dolfin/Matrix.h>
> > #include <dolfin/Vector.h>
> 10,11c14,16
> < FGMRES::FGMRES(const Matrix& A, real tol, unsigned int maxiter)
> < : A(A), tol(tol), maxiter(maxiter)
> > FGMRES::FGMRES(const Matrix& A, unsigned int restarts, unsigned int maxiter,
> > real tol, Preconditioner& pc)
> > : Preconditioner(), A(A), pc(pc)
> 13c18,21
> < dolfin_error("Not implemented.");
> > this -> restarts = restarts;
> > this -> maxiter = maxiter;
> > this -> tol = tol;
> > solve2convergence = true;
> 16c24,26
> < FGMRES::~FGMRES()
> > FGMRES::FGMRES(const Matrix& A, unsigned int maxiter,
> > real tol, Preconditioner& pc)
> > : Preconditioner(), A(A), pc(pc)
> 18c28,31
> < dolfin_error("Not implemented.");
> > restarts = 1;
> > this -> maxiter = maxiter;
> > this -> tol = tol;
> > solve2convergence = false;
> 21c34
> < void FGMRES::solve(Vector& x, const Vector& b)
> > FGMRES::~FGMRES()
> 23c36
> < dolfin_error("Not implemented.");
> >
> 27c40,41
> < real tol, unsigned int maxiter)
> > unsigned int restarts, unsigned int maxiter, real tol,
> > Preconditioner& pc)
> 30,31c44,45
> < FGMRES fgmres(A, tol, maxiter);
> <
> > FGMRES fgmres(A, restarts, maxiter, tol, pc);
> >
> 35a50,227
> > void FGMRES::solve(Vector& x, const Vector& b)
> > {
> > // Check compatibility in the matrix and vectors.
> > check(A, x, b);
> >
> > bnorm = b.norm();
> > // Check if b=0 => x=0.
> > if ( bnorm < DOLFIN_EPS ){
> > x = 0.0;
> > return;
> > }
> >
> > // Compute residual
> > Vector r(b.size());
> > real rnorm = residual(A,x,b,r);
> >
> > // Restarted GMRES
> > for ( unsigned int i = 0; i < restarts; i++ ){
> >
> > // Krylov iterations
> > unsigned int noiter = iterator(x,b,r);
> >
> > // Check stopping criterion
> > if ( solve2convergence ) {
> >
> > // Evaluate residual
> > rnorm = residual(A,x,b,r);
> >
> > // Check residual
> > if ( rnorm < tol*bnorm ){
> > dolfin_info("Restarted FGMRES converged after %i iterations (residual %1.5e)",
> > i*maxiter+noiter, rnorm);
> > break;
> > }
> > if ( i == restarts-1 )
> > dolfin_error2("Restarted FGMRES did not converge (%i iterations, residual %1.5e)",
> > i*maxiter+noiter, rnorm);
> > }
> > }
> > }
> > //-----------------------------------------------------------------------------
> > unsigned int FGMRES::iterator(Vector& x, const Vector& b, Vector& r)
> > {
> > // Number of unknowns
> > unsigned int n = x.size();
> >
> > // Initialization of temporary variables
> > Matrix mat_h(maxiter+1,maxiter+1, Matrix::dense);
> > Matrix mat_v(1,n, Matrix::dense);
> > Matrix mat_z(1,n, Matrix::dense);
> >
> > Vector vec_s(maxiter+1);
> > Vector vec_c(maxiter+1);
> > Vector vec_g(maxiter+1);
> > Vector vec_z(n);
> > Vector vec_v(n);
> >
> > real tmp1, tmp2, nu;
> > real htmp = 0.0;
> >
> > // Compute start residual = b - Ax.
> > real rnorm = residual(A,x,b,r);
> >
> > // Set start values for v.
> > for (unsigned int i = 0; i < n; i++)
> > mat_v[0][i] = vec_v(i) = r(i)/rnorm;
> >
> > vec_g = 0.0;
> > vec_g(0) = rnorm;
> >
> > unsigned int k = 0;
> > unsigned int k_end = 0;
> >
> > for (k = 0; k < maxiter; k++) {
> >
> > // Use the modified Gram-Schmidt process with reorthogonalization to
> > // find orthogonal Krylov vectors.
> > if (k != 0) mat_v.addrow(vec_v);
> >
> > pc.solve(vec_z,vec_v);
> > A.mult(vec_z,vec_v);
> >
> > if (k == 0)
> > for (unsigned int i=0;i<n;i++) mat_z[0][i] = vec_z(i);
> > else
> > mat_z.addrow(vec_z);
> >
> > // Modified Gram-Schmit orthogonalization.
> > for (unsigned int j = 0; j < k+1; j++) {
> > htmp = 0.0;
> > for (unsigned int i = 0; i < n; i++) htmp += vec_v(i) * mat_v[j][i];
> > mat_h[j][k] = htmp;
> > for (unsigned int i = 0; i < n; i++) vec_v(i) -= htmp * mat_v[j][i];
> > }
> > mat_h[k+1][k] = vec_v.norm();
> >
> > // Test for non orthogonality and reorthogonalise if necessary.
> > if ( reorthog(mat_v,vec_v,k) ){
> > for (unsigned int j = 0; j < k+1; j++) {
> > for (unsigned int i = 0; i < n; i++) htmp = vec_v(i)*mat_v[j][i];
> > mat_h(j,k) += htmp;
> > for (unsigned int i = 0; i < n; i++) vec_v(i) -= htmp*mat_v[j][i];
> > }
> > mat_h[k+1][k] = vec_v.norm();
> > }
> >
> > // Normalize
> > vec_v *= 1.0/mat_h[k+1][k];
> >
> > // If k > 0, solve least squares problem using QR factorization
> > // and Givens rotations.
> > if (k>0) {
> > for (unsigned int j = 0; j < k; j++) {
> > tmp1 = mat_h[j][k];
> > tmp2 = mat_h[j+1][k];
> > mat_h[j][k] = vec_c(j)*tmp1 - vec_s(j)*tmp2;
> > mat_h[j+1][k] = vec_s(j)*tmp1 + vec_c(j)*tmp2;
> > }
> > }
> >
> > nu = sqrt( sqr(mat_h[k][k]) + sqr(mat_h[k+1][k]) );
> >
> > vec_c(k) = mat_h[k][k] / nu;
> > vec_s(k) = - mat_h[k+1][k] / nu;
> >
> > mat_h[k][k] = vec_c(k)*mat_h[k][k] - vec_s(k)*mat_h[k+1][k];
> > mat_h[k+1][k] = 0.0;
> >
> > tmp1 = vec_c(k)*vec_g(k) - vec_s(k)*vec_g(k+1);
> > vec_g(k+1) = vec_s(k)*vec_g(k) + vec_c(k)*vec_g(k+1);
> > vec_g(k) = tmp1;
> >
> > // If residual rho = Ax-b less than tolerance (normalized with ||b||)
> > // we are done.
> >
> > if ( (fabs(vec_g(k+1)) < tol*bnorm) || (k == maxiter-1) ){
> > k_end = k;
> > break;
> > }
> > }
> > k = k_end;
> >
> > // Postprocess to obtain solution by solving system Ry=w.
> > Vector vec_w(vec_g);
> > Vector vec_y(k_end+1);
> >
> > // solve triangular system ry = w
> > vec_y(k) = vec_w(k)/mat_h[k][k];
> > for (unsigned int i = 1; i < k+1; i++) {
> > vec_y(k-i) = vec_w(k-i);
> > for (unsigned int j = 0; j < i; j++) vec_y(k-i) -= mat_h[k-i][k-j]*vec_y(k-j);
> > vec_y(k-i) /= mat_h[k-i][k-i];
> > }
> >
> > vec_z = 0.0;
> > mat_z.multt(vec_y,vec_z);
> > x += vec_z;
> >
> > return k_end;
> > }
> > //-----------------------------------------------------------------------------
> > bool FGMRES::reorthog(Matrix& v, Vector &x, int k)
> > {
> > // reorthogonalize if ||Av_k||+delta*||v_k+1||=||Av_k|| to working precision
> > // with delta \approx 10^-3
> > Vector Av(v.size(1));
> > Vector w(v.size(1));
> >
> > w = v(k,all);
> >
> > A.mult(w,Av);
> >
> > real delta = 1.0e-3;
> > real Avnorm = Av.norm();
> >
> > return ((Avnorm + delta*x.norm()) - Avnorm) < DOLFIN_EPS;
> > }
> > //-----------------------------------------------------------------------------
> Index: src/kernel/la/GaussSeidel.cpp
> ===================================================================
> RCS file: /cvs/dolfin/src/kernel/la/GaussSeidel.cpp,v
> retrieving revision 1.1
> diff -r1.1 GaussSeidel.cpp
> 12c12
> < : Preconditioner(), A(A), tol(tol), maxiter(maxiter)
> > : Preconditioner(), A(A)
> 14c14,15
> < // Do nothing
> > this -> tol = tol;
> > this -> maxiter = maxiter;
> 60a62
> >
> Index: src/kernel/la/LinearSolver.cpp
> ===================================================================
> RCS file: /cvs/dolfin/src/kernel/la/LinearSolver.cpp,v
> retrieving revision 1.2
> diff -r1.2 LinearSolver.cpp
> 33a34,50
> > real LinearSolver::residual(const Matrix& A, Vector& x, const Vector& b,
> > Vector& r) const
> > {
> > int n = b.size();
> >
> > r.init(n);
> > A.mult(x,r);
> >
> > real sum = 0.0;
> > for (int i = 0; i < n; i++) {
> > r(i) = b(i) - r(i);
> > sum += r(i)*r(i);
> > }
> >
> > return sqrt(sum);
> > }
> > //-----------------------------------------------------------------------------
> Index: src/kernel/la/dolfin/FGMRES.h
> ===================================================================
> RCS file: /cvs/dolfin/src/kernel/la/dolfin/FGMRES.h,v
> retrieving revision 1.1
> diff -r1.1 FGMRES.h
> 16,17d15
> <
> < /// This is just a template. Write documentation here.
> 19,24c17,33
> < class FGMRES : public Preconditioner, public LinearSolver
> < {
> < public:
> <
> < /// Create GMRES preconditioner/solver for a given matrix
> < FGMRES(const Matrix& A, real tol, unsigned int maxiter);
> > /// This is a flexible GMRES with right preconditioning,
> > /// due to Y. Saad, SIAM J. Sci. Comput., 14 (1993), 461-469.
> >
> > class FGMRES : public Preconditioner, public LinearSolver
> > {
> > public:
> >
> > /// Creates a FGMRES solver for a given matrix. Return an error
> > /// message if convergence is not obtained.
> > FGMRES(const Matrix& A, unsigned int restarts, unsigned int maxiter,
> > real tol, Preconditioner& pc);
> >
> > /// Creates a FGMRES solver/preconditioner for a given matrix.
> > /// Does not return an error message if convergence is not
> > /// obtained. Recommended for preconditioning.
> > FGMRES(const Matrix& A, unsigned int restarts, real tol,
> > Preconditioner& pc);
> 28c37
> <
> >
> 31c40
> <
> >
> 34,38c43,54
> < real tol, unsigned int maxiter);
> <
> < private:
> <
> < // The matrix
> > unsigned int restarts, unsigned int maxiter, real tol,
> > Preconditioner& pc);
> >
> > private:
> >
> > // Main FGMRES iterator.
> > unsigned int iterator(Vector& x, const Vector& b, Vector& r);
> >
> > // Reorthogonalize.
> > bool reorthog(Matrix& v, Vector &x, int k);
> >
> > // The matrix.
> 40,42d55
> <
> < // Tolerance
> < real tol;
> 44c57,60
> < // Maximum number of iterations
> > // Maximum number of restarts.
> > unsigned int restarts;
> >
> > // Number of iterations per restart.
> 47c63,64
> < };
> > // Tolerance
> > real tol;
> 48a66,75
> > // The preconditioner.
> > Preconditioner& pc;
> >
> > // Switch, solve to convergence.
> > bool solve2convergence;
> >
> > // Norm of right hand side.
> > real bnorm;
> >
> > };
> 51a79
> >
> Index: src/kernel/la/dolfin/GaussSeidel.h
> ===================================================================
> RCS file: /cvs/dolfin/src/kernel/la/dolfin/GaussSeidel.h,v
> retrieving revision 1.1
> diff -r1.1 GaussSeidel.h
> 29a30,32
> > /// Create Gauss-Seidel preconditioner/solver for a given matrix
> > GaussSeidel(const Matrix& A, unsigned int maxiter);
> >
> Index: src/kernel/la/dolfin/LinearSolver.h
> ===================================================================
> RCS file: /cvs/dolfin/src/kernel/la/dolfin/LinearSolver.h,v
> retrieving revision 1.1
> diff -r1.1 LinearSolver.h
> 28a29,31
> > /// Compute l2-norm of residual and the residual vector
> > real residual(const Matrix& A, Vector& x, const Vector& b,
> > Vector& r) const;
References