OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
petscsolver.C
Go to the documentation of this file.
1 /*
2  *
3  * ##### ##### ###### ###### ### ###
4  * ## ## ## ## ## ## ## ### ##
5  * ## ## ## ## #### #### ## # ##
6  * ## ## ## ## ## ## ## ##
7  * ## ## ## ## ## ## ## ##
8  * ##### ##### ## ###### ## ##
9  *
10  *
11  * OOFEM : Object Oriented Finite Element Code
12  *
13  * Copyright (C) 1993 - 2013 Borek Patzak
14  *
15  *
16  *
17  * Czech Technical University, Faculty of Civil Engineering,
18  * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19  *
20  * This library is free software; you can redistribute it and/or
21  * modify it under the terms of the GNU Lesser General Public
22  * License as published by the Free Software Foundation; either
23  * version 2.1 of the License, or (at your option) any later version.
24  *
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28  * Lesser General Public License for more details.
29  *
30  * You should have received a copy of the GNU Lesser General Public
31  * License along with this library; if not, write to the Free Software
32  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33  */
34 
35 #include "petscsolver.h"
36 
37 #include "petscsparsemtrx.h"
38 #include "engngm.h"
39 #include "floatarray.h"
40 #include "verbose.h"
41 #include "timer.h"
42 #include "error.h"
43 #include "classfactory.h"
44 
45 #include <petscksp.h>
46 
47 namespace oofem {
49 
51 
53 
55 {
56  int neqs = b.giveSize();
57  if ( x.giveSize() != neqs )
58  x.resize(neqs);
59 
60  PetscSparseMtrx *Lhs = dynamic_cast< PetscSparseMtrx * >(&A);
61  if ( !Lhs ) {
62  OOFEM_ERROR("PetscSparseMtrx Expected");
63  }
64 
65  Vec globRhsVec;
66  Vec globSolVec;
67 
68  /*
69  * scatter and gather rhs to global representation (automatically detects sequential/parallel modes)
70  */
71  Lhs->createVecGlobal(& globRhsVec);
72  Lhs->scatterL2G(b, globRhsVec);
73 
74  Lhs->createVecGlobal(& globSolVec);
75  Lhs->scatterL2G(x, globSolVec);
76 
77  //VecView(globRhsVec,PETSC_VIEWER_STDOUT_WORLD);
78  NM_Status s = this->petsc_solve(*Lhs, globRhsVec, globSolVec);
79  //VecView(globSolVec,PETSC_VIEWER_STDOUT_WORLD);
80 
81  Lhs->scatterG2L(globSolVec, x);
82 
83  VecDestroy(& globSolVec);
84  VecDestroy(& globRhsVec);
85 
86  return s;
87 }
88 
91 {
92  int nite;
93  PetscErrorCode err;
94  KSPConvergedReason reason;
95 
96  Timer timer;
97  timer.startTimer();
98 
99  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
100  * Create the linear solver and set various options
101  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
102 #ifdef _OPENMP
103  #pragma omp critical
104 #endif
105  if ( !Lhs.kspInit ) {
106 #ifdef __PARALLEL_MODE
107  MPI_Comm comm = engngModel->giveParallelComm();
108 #else
109  MPI_Comm comm = PETSC_COMM_SELF;
110 #endif
111  KSPCreate(comm, & Lhs.ksp);
112  Lhs.kspInit = true;
113  }
114 
115  /*
116  * Set operators. Here the matrix that defines the linear system
117  * also serves as the preconditioning matrix.
118  */
119  if ( Lhs.newValues ) { // Optimization for successive solves
122 #if PETSC_VERSION_MAJOR >= 3 && PETSC_VERSION_MINOR >= 5
123  // The syntax for this function changed in PETSc version 3.5.1 /ES
124  KSPSetOperators(Lhs.ksp, * Lhs.giveMtrx(), * Lhs.giveMtrx());
125 #else
126  KSPSetOperators(Lhs.ksp, * Lhs.giveMtrx(), * Lhs.giveMtrx(), DIFFERENT_NONZERO_PATTERN);
127 #endif
128  } else {
129  //KSPSetOperators(Lhs->ksp, * Lhs->giveMtrx(), * Lhs->giveMtrx(), SAME_PRECONDITIONER);
130 #if PETSC_VERSION_MAJOR >= 3 && PETSC_VERSION_MINOR >= 5
131  // The syntax for this function changed in PETSc version 3.5.1 /ES
132  KSPSetOperators(Lhs.ksp, * Lhs.giveMtrx(), * Lhs.giveMtrx());
133 #else
134  KSPSetOperators(Lhs.ksp, * Lhs.giveMtrx(), * Lhs.giveMtrx(), SAME_NONZERO_PATTERN);
135 #endif
136  }
137  Lhs.newValues = false;
138 
139  /*
140  * Set linear solver defaults for this problem (optional).
141  * - The following two statements are optional; all of these
142  * parameters could alternatively be specified at runtime via
143  * KSPSetFromOptions(). All of these defaults can be
144  * overridden at runtime, as indicated below.
145  */
146  KSPSetTolerances(Lhs.ksp, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT);
147 
148  /*
149  * Set runtime options, e.g.,
150  * -ksp_type <type> -pc_type <type> -ksp_monitor -ksp_rtol <rtol>
151  * These options will override those specified above as long as
152  * KSPSetFromOptions() is called _after_ any other customization
153  * routines.
154  */
155  KSPSetFromOptions(Lhs.ksp);
156  }
157 
158  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
159  * Solve the linear system
160  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
161  //MatView(*Lhs->giveMtrx(),PETSC_VIEWER_STDOUT_SELF);
162  err = KSPSolve(Lhs.ksp, b, x);
163  if ( err != 0 ) {
164  OOFEM_ERROR("Error when solving: %d\n", err);
165  }
166  KSPGetConvergedReason(Lhs.ksp, & reason);
167  KSPGetIterationNumber(Lhs.ksp, & nite);
168 
169  if ( reason >= 0 ) {
170  //OOFEM_LOG_INFO("PetscSolver: Converged. KSPConvergedReason: %d, number of iterations: %d\n", reason, nite);
171  } else {
172  OOFEM_WARNING("Diverged! KSPConvergedReason: %d, number of iterations: %d\n", reason, nite);
173  }
174 
175  timer.stopTimer();
176  if ( this->engngModel->giveProblemScale() == macroScale ) {
177  OOFEM_LOG_INFO( "PetscSolver: User time consumed by solution: %.2fs, KSPConvergedReason: %d, number of iterations: %d\n", timer.getUtime(), reason, nite );
178  }
179 
180  if ( reason < 0 ) {
181  return NM_NoSuccess;
182  } else {
183  return NM_Success;
184  }
185 }
186 
187 
188 #if 0
191 {
192  PetscSparseMtrx *Lhs = dynamic_cast< PetscSparseMtrx * >(&A);
193  if ( !Lhs ) {
194  OOFEM_ERROR("PetscSparseMtrx Expected");
195  }
196 
197  Vec globRhsVec;
198  Vec globSolVec;
199 
200  bool newLhs = true;
201  int rows = B.giveNumberOfRows();
202  int cols = B.giveNumberOfColumns();
203  NM_Status s;
204  X.resize(rows, cols);
205  double *Xptr = X.givePointer();
206 
207  for ( int i = 0; i < cols; ++i ) {
208  VecCreateSeqWithArray(PETSC_COMM_SELF, rows, B.givePointer() + rows * i, & globRhsVec);
209  VecDuplicate(globRhsVec, & globSolVec);
210  s = this->petsc_solve(*Lhs, globRhsVec, globSolVec, newLhs);
211  if ( !( s & NM_Success ) ) {
212  OOFEM_WARNING("No success at solving column %d", i + 1);
213  return s;
214  }
215  newLhs = false;
216  double *ptr;
217  VecGetArray(globSolVec, & ptr);
218  for ( int j = 0; j < rows; ++j ) {
219  Xptr [ j + rows * i ] = ptr [ j ];
220  }
221  VecRestoreArray(globSolVec, & ptr);
222  }
223  VecDestroy(& globSolVec);
224  VecDestroy(& globRhsVec);
225  return s;
226 }
227 #endif
228 } // end namespace oofem
int giveNumberOfColumns() const
Returns number of columns of receiver.
Definition: floatmatrix.h:158
#define NM_Success
Numerical method exited with success.
Definition: nmstatus.h:47
Class and object Domain.
Definition: domain.h:115
problemScale giveProblemScale()
Returns scale in multiscale simulation.
Definition: engngm.h:418
Base class for all matrices stored in sparse format.
Definition: sparsemtrx.h:60
virtual int requiresUnknownsDictionaryUpdate()
Indicates if EngngModel requires Dofs dictionaries to be updated.
Definition: engngm.h:845
void createVecGlobal(Vec *answer) const
Creates a global vector that fits the instance of this matrix.
This base class is an abstraction for all numerical methods solving sparse linear system of equations...
const double * givePointer() const
Exposes the internal values of the matrix.
Definition: floatmatrix.h:558
KSP ksp
Linear solver context.
unsigned long NM_Status
Mask defining NumMetod Status; which can be asked after finishing computation by Numerical Method...
Definition: nmstatus.h:44
#define NM_NoSuccess
Numerical method failed to solve problem.
Definition: nmstatus.h:48
#define OOFEM_LOG_INFO(...)
Definition: logger.h:127
#define OOFEM_ERROR(...)
Definition: error.h:61
int scatterL2G(const FloatArray &src, Vec dest) const
Scatters and gathers vector in local form to global (parallel) one.
MPI_Comm giveParallelComm()
Returns the communication object of reciever.
Definition: engngm.h:549
Initializes the variable VERBOSE, in order to get a few intermediate messages on screen: beginning an...
Class representing vector of real numbers.
Definition: floatarray.h:82
Implementation of matrix containing floating point numbers.
Definition: floatmatrix.h:94
bool kspInit
Flag if context initialized.
void resize(int rows, int cols)
Checks size of receiver towards requested bounds.
Definition: floatmatrix.C:1358
PetscSolver(Domain *d, EngngModel *m)
Constructor.
Definition: petscsolver.C:50
REGISTER_SparseLinSolver(IMLSolver, ST_IML)
Definition: imlsolver.C:56
Class implementing single timer, providing wall clock and user time capabilities. ...
Definition: timer.h:46
bool newValues
Flag if matrix has changed since last solve.
virtual ~PetscSolver()
Definition: petscsolver.C:52
NM_Status petsc_solve(PetscSparseMtrx &A, Vec b, Vec x)
Solves the given linear system.
Definition: petscsolver.C:90
Abstract base class representing the "problem" under consideration.
Definition: engngm.h:181
int giveSize() const
Returns the size of receiver.
Definition: floatarray.h:218
the oofem namespace is to define a context or scope in which all oofem names are defined.
int scatterG2L(Vec src, FloatArray &dest) const
Scatters global vector to natural one.
virtual NM_Status solve(SparseMtrx &A, FloatArray &b, FloatArray &x)
Solves the given sparse linear system of equations .
Definition: petscsolver.C:54
int giveNumberOfRows() const
Returns number of rows of receiver.
Definition: floatmatrix.h:156
EngngModel * engngModel
Pointer to engineering model.
Definition: nummet.h:86
void startTimer()
Definition: timer.C:69
This class provides an sparse matrix interface to PETSc Matrices.
double getUtime()
Returns total user time elapsed in seconds.
Definition: timer.C:105
#define OOFEM_WARNING(...)
Definition: error.h:62
void stopTimer()
Definition: timer.C:77
void resize(int s)
Resizes receiver towards requested size.
Definition: floatarray.C:631

This page is part of the OOFEM documentation. Copyright (c) 2011 Borek Patzak
Project e-mail: info@oofem.org
Generated at Tue Jan 2 2018 20:07:30 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011