/[escript]/trunk/escript/py_src/linearPDEs.py
ViewVC logotype

Diff of /trunk/escript/py_src/linearPDEs.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3051 by lgao, Tue Jun 29 00:45:49 2010 UTC revision 3402 by gross, Tue Dec 7 07:36:12 2010 UTC
# Line 1  Line 1 
1    # -*- coding: utf-8 -*-
2    
3  ########################################################  ########################################################
4  #  #
# Line 67  class SolverOptions(object): Line 68  class SolverOptions(object):
68      :cvar CR: The conjugate residual method      :cvar CR: The conjugate residual method
69      :cvar CGS: The conjugate gradient square method      :cvar CGS: The conjugate gradient square method
70      :cvar BICGSTAB: The stabilized Bi-Conjugate Gradient method      :cvar BICGSTAB: The stabilized Bi-Conjugate Gradient method
71      :cvar TFQMR: Transport Free Quasi Minimal Residual method      :cvar TFQMR: Transpose Free Quasi Minimal Residual method
72      :cvar MINRES: Minimum residual method      :cvar MINRES: Minimum residual method
     :cvar SSOR: The symmetric over-relaxation method  
73      :cvar ILU0: The incomplete LU factorization preconditioner with no fill-in      :cvar ILU0: The incomplete LU factorization preconditioner with no fill-in
74      :cvar ILUT: The incomplete LU factorization preconditioner with fill-in      :cvar ILUT: The incomplete LU factorization preconditioner with fill-in
75      :cvar JACOBI: The Jacobi preconditioner      :cvar JACOBI: The Jacobi preconditioner
76      :cvar GMRES: The Gram-Schmidt minimum residual method      :cvar GMRES: The Gram-Schmidt minimum residual method
77      :cvar PRES20: Special GMRES with restart after 20 steps and truncation after 5 residuals      :cvar PRES20: Special GMRES with restart after 20 steps and truncation after 5 residuals
78      :cvar LUMPING: Matrix lumping      :cvar ROWSUM_LUMPING: Matrix lumping using row sum
79        :cvar HRZ_LUMPING: Matrix lumping using the HRZ approach
80      :cvar NO_REORDERING: No matrix reordering allowed      :cvar NO_REORDERING: No matrix reordering allowed
81      :cvar MINIMUM_FILL_IN: Reorder matrix to reduce fill-in during factorization      :cvar MINIMUM_FILL_IN: Reorder matrix to reduce fill-in during factorization
82      :cvar NESTED_DISSECTION: Reorder matrix to improve load balancing during factorization      :cvar NESTED_DISSECTION: Reorder matrix to improve load balancing during factorization
# Line 89  class SolverOptions(object): Line 90  class SolverOptions(object):
90      :cvar AMLI: Algebraic Multi Level Iteration      :cvar AMLI: Algebraic Multi Level Iteration
91      :cvar REC_ILU: recursive ILU0      :cvar REC_ILU: recursive ILU0
92      :cvar RILU: relaxed ILU0      :cvar RILU: relaxed ILU0
93      :cvar GAUSS_SEIDEL: Gauss-Seidel solver      :cvar GAUSS_SEIDEL: Gauss-Seidel preconditioner
     :cvar GAUSS_SEIDEL_MPI: MPI versioned Gauss-Seidel solver  
94      :cvar DEFAULT_REORDERING: the reordering method recommended by the solver      :cvar DEFAULT_REORDERING: the reordering method recommended by the solver
95      :cvar SUPER_LU: the Super_LU solver package      :cvar SUPER_LU: the Super_LU solver package
96      :cvar PASTIX: the Pastix direct solver_package      :cvar PASTIX: the Pastix direct solver_package
# Line 108  class SolverOptions(object): Line 108  class SolverOptions(object):
108      CR= 4      CR= 4
109      CGS= 5      CGS= 5
110      BICGSTAB= 6      BICGSTAB= 6
     SSOR= 7  
111      ILU0= 8      ILU0= 8
112      ILUT= 9      ILUT= 9
113      JACOBI= 10      JACOBI= 10
114      GMRES= 11      GMRES= 11
115      PRES20= 12      PRES20= 12
116      LUMPING= 13      LUMPING= 13
117        ROWSUM_LUMPING= 13
118        HRZ_LUMPING= 14
119      NO_REORDERING= 17      NO_REORDERING= 17
120      MINIMUM_FILL_IN= 18      MINIMUM_FILL_IN= 18
121      NESTED_DISSECTION= 19      NESTED_DISSECTION= 19
# Line 140  class SolverOptions(object): Line 141  class SolverOptions(object):
141      MIN_COARSE_MATRIX_SIZE=37      MIN_COARSE_MATRIX_SIZE=37
142      AMLI=38      AMLI=38
143      STANDARD_COARSENING=39      STANDARD_COARSENING=39
     GAUSS_SEIDEL_MPI=40  
144    
145      def __init__(self):      def __init__(self):
146          self.setLevelMax()          self.setLevelMax()
# Line 169  class SolverOptions(object): Line 169  class SolverOptions(object):
169          self.setCoarsening()          self.setCoarsening()
170          self.setMinCoarseMatrixSize()          self.setMinCoarseMatrixSize()
171          self.setRelaxationFactor()                  self.setRelaxationFactor()        
172            self.setLocalPreconditionerOff()
173          self.resetDiagnostics(all=True)          self.resetDiagnostics(all=True)
174            self.setMinCoarseMatrixSparsity()
175            self.setNumRefinements()
176            self.setNumCoarseMatrixRefinements()
177            self.setUsePanel()
178            self.setUseDirectInterpolation()
179            self.setDiagonalDominanceThreshold()
180            
181    
182      def __str__(self):      def __str__(self):
183          return self.getSummary()          return self.getSummary()
# Line 184  class SolverOptions(object): Line 192  class SolverOptions(object):
192          out+="\nAbsolute tolerance = %e"%self.getAbsoluteTolerance()          out+="\nAbsolute tolerance = %e"%self.getAbsoluteTolerance()
193          out+="\nSymmetric problem = %s"%self.isSymmetric()          out+="\nSymmetric problem = %s"%self.isSymmetric()
194          out+="\nMaximum number of iteration steps = %s"%self.getIterMax()          out+="\nMaximum number of iteration steps = %s"%self.getIterMax()
195          out+="\nInner tolerance = %e"%self.getInnerTolerance()          # out+="\nInner tolerance = %e"%self.getInnerTolerance()
196          out+="\nAdapt innner tolerance = %s"%self.adaptInnerTolerance()          # out+="\nAdapt innner tolerance = %s"%self.adaptInnerTolerance()
197            
198          if self.getPackage() == self.PASO:          if self.getPackage() == self.PASO:
199              out+="\nSolver method = %s"%self.getName(self.getSolverMethod())              out+="\nSolver method = %s"%self.getName(self.getSolverMethod())
# Line 194  class SolverOptions(object): Line 202  class SolverOptions(object):
202                  out+="\nRestart  = %s"%self.getRestart()                  out+="\nRestart  = %s"%self.getRestart()
203              if self.getSolverMethod() == self.AMG:              if self.getSolverMethod() == self.AMG:
204                  out+="\nNumber of pre / post sweeps = %s / %s, %s"%(self.getNumPreSweeps(), self.getNumPostSweeps(), self.getNumSweeps())                  out+="\nNumber of pre / post sweeps = %s / %s, %s"%(self.getNumPreSweeps(), self.getNumPostSweeps(), self.getNumSweeps())
205                  out+="\nMaximum number of levels = %s"%self.LevelMax()                  out+="\nMaximum number of levels = %s"%self.getLevelMax()
206                  out+="\nCoarsening threshold = %e"%self.getCoarseningThreshold()                  out+="\nCoarsening threshold = %e"%self.getCoarseningThreshold()
207                  out+="\Coarsening method = %s"%self.getName(self.getCoarsening())                  out+="\nCoarsening method = %s"%self.getName(self.getCoarsening())
208              out+="\nPreconditioner = %s"%self.getName(self.getPreconditioner())              out+="\nPreconditioner = %s"%self.getName(self.getPreconditioner())
209                out+="\nApply preconditioner locally = %s"%self.useLocalPreconditioner()
210              if self.getPreconditioner() == self.AMG:              if self.getPreconditioner() == self.AMG:
211                  out+="\nMaximum number of levels = %s"%self.LevelMax()                  out+="\nMaximum number of levels = %s"%self.getLevelMax()
212                  out+="\nCoarsening method = %s"%self.getName(self.getCoarsening())                  out+="\nCoarsening threshold = %e"%self.getCoarseningThreshold()
213                  out+="\nCoarsening threshold = %e"%self.getMinCoarseMatrixSize()                  out+="\nMinimal sparsity on coarsest level = %e"%(self.getMinCoarseMatrixSparsity(),)
214                  out+="\nSmoother = %e"%self.getName(self.getSmoother())                  out+="\nSmoother = %s"%self.getName(self.getSmoother())
215                  out+="\nMinimum size of the coarsest level matrix = %e"%self.getCoarseningThreshold()                  out+="\nMinimum size of the coarsest level matrix = %e"%self.getCoarseningThreshold()
216                  out+="\nNumber of pre / post sweeps = %s / %s, %s"%(self.getNumPreSweeps(), self.getNumPostSweeps(), self.getNumSweeps())                  out+="\nNumber of pre / post sweeps = %s / %s, %s"%(self.getNumPreSweeps(), self.getNumPostSweeps(), self.getNumSweeps())
217                    out+="\nNumber of refinement steps in coarsest level solver = %d"%(self.getNumCoarseMatrixRefinements(),)
218                    out+="\nUse node panel = %s"%(self.usePanel())
219                    out+="\nUse direct interpolation only = %s"%(self.useDirectInterpolation())
220                    out+="\nThreshold for diagonal dominant rows = %s"%(setDiagonalDominanceThreshold(),)
221    
222              if self.getPreconditioner() == self.AMLI:              if self.getPreconditioner() == self.AMLI:
223                  out+="\nMaximum number of levels = %s"%self.LevelMax()                  out+="\nMaximum number of levels = %s"%self.getLevelMax()
224                  out+="\nCoarsening method = %s"%self.getName(self.getCoarsening())                  out+="\nCoarsening method = %s"%self.getName(self.getCoarsening())
225                  out+="\nCoarsening threshold = %e"%self.getMinCoarseMatrixSize()                  out+="\nCoarsening threshold = %e"%self.getMinCoarseMatrixSize()
226                  out+="\nMinimum size of the coarsest level matrix = %e"%self.getCoarseningThreshold()                  out+="\nMinimum size of the coarsest level matrix = %e"%self.getCoarseningThreshold()
227                  out+="\nNumber of pre / post sweeps = %s / %s, %s"%(self.getNumPreSweeps(), self.getNumPostSweeps(), self.getNumSweeps())                  out+="\nNumber of pre / post sweeps = %s / %s, %s"%(self.getNumPreSweeps(), self.getNumPostSweeps(), self.getNumSweeps())
228          if self.getPreconditioner() == self.GAUSS_SEIDEL:          if self.getPreconditioner() == self.GAUSS_SEIDEL:
229                  out+="\nNumber of sweeps = %s"%self.getNumSweeps()                  out+="\nNumber of sweeps = %s"%self.getNumSweeps()
             if self.getPreconditioner() == self.GAUSS_SEIDEL_MPI:  
                 out+="\nNumber of sweeps = %s"%self.getNumSweeps()  
230              if self.getPreconditioner() == self.ILUT:              if self.getPreconditioner() == self.ILUT:
231                  out+="\nDrop tolerance = %e"%self.getDropTolerance()                  out+="\nDrop tolerance = %e"%self.getDropTolerance()
232                  out+="\nStorage increase = %e"%self.getDropStorage()                  out+="\nStorage increase = %e"%self.getDropStorage()
# Line 235  class SolverOptions(object): Line 247  class SolverOptions(object):
247          if key == self.CR: return "CR"          if key == self.CR: return "CR"
248          if key == self.CGS: return "CGS"          if key == self.CGS: return "CGS"
249          if key == self.BICGSTAB: return "BICGSTAB"          if key == self.BICGSTAB: return "BICGSTAB"
         if key == self.SSOR: return "SSOR"  
250          if key == self.ILU0: return "ILU0:"          if key == self.ILU0: return "ILU0:"
251          if key == self.ILUT: return "ILUT"          if key == self.ILUT: return "ILUT"
252          if key == self.JACOBI: return "JACOBI"          if key == self.JACOBI: return "JACOBI"
253          if key == self.GMRES: return "GMRES"          if key == self.GMRES: return "GMRES"
254          if key == self.PRES20: return "PRES20"          if key == self.PRES20: return "PRES20"
255          if key == self.LUMPING: return "LUMPING"          if key == self.ROWSUM_LUMPING: return "ROWSUM_LUMPING"
256            if key == self.HRZ_LUMPING: return "HRZ_LUMPING"
257          if key == self.NO_REORDERING: return "NO_REORDERING"          if key == self.NO_REORDERING: return "NO_REORDERING"
258          if key == self.MINIMUM_FILL_IN: return "MINIMUM_FILL_IN"          if key == self.MINIMUM_FILL_IN: return "MINIMUM_FILL_IN"
259          if key == self.NESTED_DISSECTION: return "NESTED_DISSECTION"          if key == self.NESTED_DISSECTION: return "NESTED_DISSECTION"
# Line 257  class SolverOptions(object): Line 269  class SolverOptions(object):
269          if key == self.TFQMR: return "TFQMR"          if key == self.TFQMR: return "TFQMR"
270          if key == self.MINRES: return "MINRES"          if key == self.MINRES: return "MINRES"
271          if key == self.GAUSS_SEIDEL: return "GAUSS_SEIDEL"          if key == self.GAUSS_SEIDEL: return "GAUSS_SEIDEL"
         if key == self.GAUSS_SEIDEL_MPI: return "GAUSS_SEIDEL_MPI"  
272          if key == self.RILU: return "RILU"          if key == self.RILU: return "RILU"
273          if key == self.DEFAULT_REORDERING: return "DEFAULT_REORDERING"          if key == self.DEFAULT_REORDERING: return "DEFAULT_REORDERING"
274          if key == self.SUPER_LU: return "SUPER_LU"          if key == self.SUPER_LU: return "SUPER_LU"
# Line 267  class SolverOptions(object): Line 278  class SolverOptions(object):
278          if key == self.STANDARD_COARSENING: return "STANDARD_COARSENING"          if key == self.STANDARD_COARSENING: return "STANDARD_COARSENING"
279          if key == self.AGGREGATION_COARSENING: return "AGGREGATION_COARSENING"          if key == self.AGGREGATION_COARSENING: return "AGGREGATION_COARSENING"
280          if key == self.NO_PRECONDITIONER: return "NO_PRECONDITIONER"          if key == self.NO_PRECONDITIONER: return "NO_PRECONDITIONER"
         if key == self.MIN_COARSE_MATRIX_SIZE: return "MIN_COARSE_MATRIX_SIZE"  
281                    
282      def resetDiagnostics(self,all=False):      def resetDiagnostics(self,all=False):
283          """          """
# Line 284  class SolverOptions(object): Line 294  class SolverOptions(object):
294          self.__net_time=None          self.__net_time=None
295          self.__residual_norm=None          self.__residual_norm=None
296          self.__converged=None          self.__converged=None
297            self.__preconditioner_size=-1
298            self.__time_step_backtracking_used=None
299          if all:          if all:
300              self.__cum_num_inner_iter=0              self.__cum_num_inner_iter=0
301              self.__cum_num_iter=0              self.__cum_num_iter=0
# Line 321  class SolverOptions(object): Line 333  class SolverOptions(object):
333              self.__residual_norm=float(value)              self.__residual_norm=float(value)
334          if name == "converged":          if name == "converged":
335              self.__converged = (value == True)              self.__converged = (value == True)
336            if name == "time_step_backtracking_used":
337                self.__time_step_backtracking_used = (value == True)
338            if name == "coarse_level_sparsity":
339               self.__coarse_level_sparsity = value
340        if name == "num_coarse_unknowns":
341               self.__num_coarse_unknowns= value
342      def getDiagnostics(self, name):      def getDiagnostics(self, name):
343          """          """
344          Returns the diagnostic information ``name``. Possible values are:          Returns the diagnostic information ``name``. Possible values are:
# Line 336  class SolverOptions(object): Line 354  class SolverOptions(object):
354          - "cum_set_up_time": cumulative time to set up of the solver          - "cum_set_up_time": cumulative time to set up of the solver
355          - "net_time": net execution time, excluding setup time for the solver and execution time for preconditioner          - "net_time": net execution time, excluding setup time for the solver and execution time for preconditioner
356          - "cum_net_time": cumulative net execution time          - "cum_net_time": cumulative net execution time
357          - "residual_norm": norm of the final residual          - "preconditioner_size": size of preconditioner [Bytes]
358          - "converged": return self.__converged          - "converged": return True if solution has converged.
359                - "time_step_backtracking_used": returns True if time step back tracking has been used.
360            - "coarse_level_sparsity": returns the sparsity of the matrix on the coarsest level
361            - "num_coarse_unknowns": returns the number of unknowns on the coarsest level
362            
363                    
364          :param name: name of diagnostic information to return          :param name: name of diagnostic information to return
# Line 359  class SolverOptions(object): Line 379  class SolverOptions(object):
379          elif name == "cum_net_time": return self.__cum_net_time          elif name == "cum_net_time": return self.__cum_net_time
380          elif name == "residual_norm": return self.__residual_norm          elif name == "residual_norm": return self.__residual_norm
381          elif name == "converged": return self.__converged                elif name == "converged": return self.__converged      
382            elif name == "preconditioner_size": return  self.__preconditioner_size
383            elif name == "time_step_backtracking_used": return  self.__time_step_backtracking_used
384            elif name == "coarse_level_sparsity": return self.__coarse_level_sparsity
385            elif name == "num_coarse_unknowns": return self.__num_coarse_unknowns
386          else:          else:
387              raise ValueError,"unknown diagnostic item %s"%name              raise ValueError,"unknown diagnostic item %s"%name
388      def hasConverged(self):      def hasConverged(self):
# Line 369  class SolverOptions(object): Line 393  class SolverOptions(object):
393          return self.getDiagnostics("converged")          return self.getDiagnostics("converged")
394      def setCoarsening(self,method=0):      def setCoarsening(self,method=0):
395          """          """
396          Sets the key of the coarsening method to be applied in AMG.          Sets the key of the coarsening method to be applied in AMG or AMLI
397    
398          :param method: selects the coarsening method .          :param method: selects the coarsening method .
399          :type method: in {SolverOptions.DEFAULT}, `SolverOptions.YAIR_SHAPIRA_COARSENING`,  `SolverOptions.RUGE_STUEBEN_COARSENING`, `SolverOptions.AGGREGATION_COARSENING`          :type method: in {SolverOptions.DEFAULT}, `SolverOptions.YAIR_SHAPIRA_COARSENING`,  `SolverOptions.RUGE_STUEBEN_COARSENING`, `SolverOptions.AGGREGATION_COARSENING`
# Line 381  class SolverOptions(object): Line 405  class SolverOptions(object):
405            
406      def getCoarsening(self):      def getCoarsening(self):
407          """          """
408          Returns the key of the coarsening algorithm to be applied AMG.          Returns the key of the coarsening algorithm to be applied AMG or AMLI
409    
410          :rtype: in the list `SolverOptions.DEFAULT`, `SolverOptions.YAIR_SHAPIRA_COARSENING`, `SolverOptions.RUGE_STUEBEN_COARSENING`, `SolverOptions.AGGREGATION_COARSENING`          :rtype: in the list `SolverOptions.DEFAULT`, `SolverOptions.YAIR_SHAPIRA_COARSENING`, `SolverOptions.RUGE_STUEBEN_COARSENING`, `SolverOptions.AGGREGATION_COARSENING`
411          """          """
# Line 389  class SolverOptions(object): Line 413  class SolverOptions(object):
413                
414      def setMinCoarseMatrixSize(self,size=500):      def setMinCoarseMatrixSize(self,size=500):
415          """          """
416          Sets the minumum size of the coarsest level matrix in AMG.          Sets the minumum size of the coarsest level matrix in AMG or AMLI
417    
418          :param size: minumum size of the coarsest level matrix .          :param size: minumum size of the coarsest level matrix .
419          :type size: positive ``int`` or ``None``          :type size: positive ``int`` or ``None``
420          """          """
421        if size==None: size=500
422          size=int(size)          size=int(size)
423          if size<0:          if size<0:
424             raise ValueError,"minumum size of the coarsest level matrix must be non-negative."             raise ValueError,"minumum size of the coarsest level matrix must be non-negative."
     if size==None: size=500  
425          self.__MinCoarseMatrixSize=size          self.__MinCoarseMatrixSize=size
426                    
427      def getMinCoarseMatrixSize(self):      def getMinCoarseMatrixSize(self):
428          """          """
429          Returns the minumum size of the coarsest level matrix in AMG.          Returns the minumum size of the coarsest level matrix in AMG or AMLI
430    
431          :rtype: ``int``          :rtype: ``int``
432          """          """
# Line 413  class SolverOptions(object): Line 437  class SolverOptions(object):
437          Sets the preconditioner to be used.          Sets the preconditioner to be used.
438    
439          :param preconditioner: key of the preconditioner to be used.          :param preconditioner: key of the preconditioner to be used.
440          :type preconditioner: in `SolverOptions.SSOR`, `SolverOptions.ILU0`, `SolverOptions.ILUT`, `SolverOptions.JACOBI`,          :type preconditioner: in `SolverOptions.ILU0`, `SolverOptions.ILUT`, `SolverOptions.JACOBI`,
441                                      `SolverOptions.AMG`, `SolverOptions.AMLI`, `SolverOptions.REC_ILU`, `SolverOptions.GAUSS_SEIDEL`, `SolverOptions.GAUSS_SEIDEL_MPI`, `SolverOptions.RILU`,                                      `SolverOptions.AMG`, `SolverOptions.AMLI`, `SolverOptions.REC_ILU`, `SolverOptions.GAUSS_SEIDEL`, `SolverOptions.RILU`,
442                                      `SolverOptions.NO_PRECONDITIONER`                                      `SolverOptions.NO_PRECONDITIONER`
443          :note: Not all packages support all preconditioner. It can be assumed that a package makes a reasonable choice if it encounters an unknown preconditioner.          :note: Not all packages support all preconditioner. It can be assumed that a package makes a reasonable choice if it encounters an unknown preconditioner.
444          """          """
445      if preconditioner==None: preconditioner=10      if preconditioner==None: preconditioner=10
446          if not preconditioner in [ SolverOptions.SSOR, SolverOptions.ILU0, SolverOptions.ILUT, SolverOptions.JACOBI,          if not preconditioner in [  SolverOptions.ILU0, SolverOptions.ILUT, SolverOptions.JACOBI,
447                                      SolverOptions.AMG, SolverOptions.AMLI, SolverOptions.REC_ILU, SolverOptions.GAUSS_SEIDEL, SolverOptions.GAUSS_SEIDEL_MPI, SolverOptions.RILU,                                      SolverOptions.AMG, SolverOptions.AMLI, SolverOptions.REC_ILU, SolverOptions.GAUSS_SEIDEL, SolverOptions.RILU,
448                                      SolverOptions.NO_PRECONDITIONER] :                                      SolverOptions.NO_PRECONDITIONER] :
449               raise ValueError,"unknown preconditioner %s"%preconditioner               raise ValueError,"unknown preconditioner %s"%preconditioner
450          self.__preconditioner=preconditioner              self.__preconditioner=preconditioner    
# Line 428  class SolverOptions(object): Line 452  class SolverOptions(object):
452          """          """
453          Returns key of the preconditioner to be used.          Returns key of the preconditioner to be used.
454    
455          :rtype: in the list `SolverOptions.SSOR`, `SolverOptions.ILU0`, `SolverOptions.ILUT`, `SolverOptions.JACOBI`,          :rtype: in the list `SolverOptions.ILU0`, `SolverOptions.ILUT`, `SolverOptions.JACOBI`, SolverOptions.AMLI,
456                                      `SolverOptions.AMG`, `SolverOptions.REC_ILU`, `SolverOptions.GAUSS_SEIDEL`, `SolverOptions.GAUSS_SEIDEL_MPI`, `SolverOptions.RILU`,                                      `SolverOptions.AMG`, `SolverOptions.REC_ILU`, `SolverOptions.GAUSS_SEIDEL`, `SolverOptions.RILU`,
457                                      `SolverOptions.NO_PRECONDITIONER`                                      `SolverOptions.NO_PRECONDITIONER`
458          """          """
459          return self.__preconditioner          return self.__preconditioner
460      def setSmoother(self, smoother=28):      def setSmoother(self, smoother=None):
461          """          """
462          Sets the smoother to be used.          Sets the smoother to be used.
463    
# Line 460  class SolverOptions(object): Line 484  class SolverOptions(object):
484    
485          :param method: key of the solver method to be used.          :param method: key of the solver method to be used.
486          :type method: in `SolverOptions.DEFAULT`, `SolverOptions.DIRECT`, `SolverOptions.CHOLEVSKY`, `SolverOptions.PCG`,          :type method: in `SolverOptions.DEFAULT`, `SolverOptions.DIRECT`, `SolverOptions.CHOLEVSKY`, `SolverOptions.PCG`,
487                          `SolverOptions.CR`, `SolverOptions.CGS`, `SolverOptions.BICGSTAB`, `SolverOptions.SSOR`,                          `SolverOptions.CR`, `SolverOptions.CGS`, `SolverOptions.BICGSTAB`,
488                          `SolverOptions.GMRES`, `SolverOptions.PRES20`, `SolverOptions.LUMPING`, `SolverOptions.ITERATIVE`,                          `SolverOptions.GMRES`, `SolverOptions.PRES20`, `SolverOptions.ROWSUM_LUMPING`, `SolverOptions.HRZ_LUMPING`, `SolverOptions.ITERATIVE`,
489                          `SolverOptions.AMG`, `SolverOptions.NONLINEAR_GMRES`, `SolverOptions.TFQMR`, `SolverOptions.MINRES`,                          `SolverOptions.NONLINEAR_GMRES`, `SolverOptions.TFQMR`, `SolverOptions.MINRES`
                         `SolverOptions.GAUSS_SEIDEL`, `SolverOptions.GAUSS_SEIDEL_MPI`  
490          :note: Not all packages support all solvers. It can be assumed that a package makes a reasonable choice if it encounters an unknown solver method.          :note: Not all packages support all solvers. It can be assumed that a package makes a reasonable choice if it encounters an unknown solver method.
491          """          """
492      if method==None: method=0      if method==None: method=0
493          if not method in [ SolverOptions.DEFAULT, SolverOptions.DIRECT, SolverOptions.CHOLEVSKY, SolverOptions.PCG,          if not method in [ SolverOptions.DEFAULT, SolverOptions.DIRECT, SolverOptions.CHOLEVSKY, SolverOptions.PCG,
494                             SolverOptions.CR, SolverOptions.CGS, SolverOptions.BICGSTAB, SolverOptions.SSOR,                             SolverOptions.CR, SolverOptions.CGS, SolverOptions.BICGSTAB,
495                             SolverOptions.GMRES, SolverOptions.PRES20, SolverOptions.LUMPING, SolverOptions.ITERATIVE, SolverOptions.AMG,                             SolverOptions.GMRES, SolverOptions.PRES20, SolverOptions.ROWSUM_LUMPING, SolverOptions.HRZ_LUMPING,
496                             SolverOptions.NONLINEAR_GMRES, SolverOptions.TFQMR, SolverOptions.MINRES, SolverOptions.GAUSS_SEIDEL, SolverOptions.GAUSS_SEIDEL_MPI]:                             SolverOptions.ITERATIVE,
497                               SolverOptions.NONLINEAR_GMRES, SolverOptions.TFQMR, SolverOptions.MINRES ]:
498               raise ValueError,"unknown solver method %s"%method               raise ValueError,"unknown solver method %s"%method
499          self.__method=method          self.__method=method
500      def getSolverMethod(self):      def getSolverMethod(self):
# Line 478  class SolverOptions(object): Line 502  class SolverOptions(object):
502          Returns key of the solver method to be used.          Returns key of the solver method to be used.
503    
504          :rtype: in the list `SolverOptions.DEFAULT`, `SolverOptions.DIRECT`, `SolverOptions.CHOLEVSKY`, `SolverOptions.PCG`,          :rtype: in the list `SolverOptions.DEFAULT`, `SolverOptions.DIRECT`, `SolverOptions.CHOLEVSKY`, `SolverOptions.PCG`,
505                          `SolverOptions.CR`, `SolverOptions.CGS`, `SolverOptions.BICGSTAB`, `SolverOptions.SSOR`,                          `SolverOptions.CR`, `SolverOptions.CGS`, `SolverOptions.BICGSTAB`,
506                          `SolverOptions.GMRES`, `SolverOptions.PRES20`, `SolverOptions.LUMPING`, `SolverOptions.ITERATIVE`,                          `SolverOptions.GMRES`, `SolverOptions.PRES20`, `SolverOptions.ROWSUM_LUMPING`, `SolverOptions.HRZ_LUMPING`, `SolverOptions.ITERATIVE`,
507                          `SolverOptions.AMG`, `SolverOptions.NONLINEAR_GMRES`, `SolverOptions.TFQMR`, `SolverOptions.MINRES`,                          `SolverOptions.NONLINEAR_GMRES`, `SolverOptions.TFQMR`, `SolverOptions.MINRES`
                         `SolverOptions.GAUSS_SEIDEL`, `SolverOptions.GAUSS_SEIDEL_MPI`  
508          """          """
509          return self.__method          return self.__method
510                    
# Line 510  class SolverOptions(object): Line 533  class SolverOptions(object):
533          to optimize compute time and storage use during elimination.          to optimize compute time and storage use during elimination.
534    
535          :param ordering: selects the reordering strategy.          :param ordering: selects the reordering strategy.
536          :type ordering: in `SolverOptions.NO_REORDERING`, `SolverOptions.NO_REORDERING`, `SolverOptions.NO_REORDERING`, `SolverOptions.DEFAULT_REORDERING`          :type ordering: in 'SolverOptions.NO_REORDERING', 'SolverOptions.MINIMUM_FILL_IN', 'SolverOptions.NESTED_DISSECTION', 'SolverOptions.DEFAULT_REORDERING'
537          """          """
538          if not ordering in [self.NO_REORDERING, self.MINIMUM_FILL_IN, self.NESTED_DISSECTION, self.DEFAULT_REORDERING]:          if not ordering in [self.NO_REORDERING, self.MINIMUM_FILL_IN, self.NESTED_DISSECTION, self.DEFAULT_REORDERING]:
539               raise ValueError,"unknown reordering strategy %s"%ordering               raise ValueError,"unknown reordering strategy %s"%ordering
# Line 519  class SolverOptions(object): Line 542  class SolverOptions(object):
542          """          """
543          Returns the key of the reordering method to be applied if supported by the solver.          Returns the key of the reordering method to be applied if supported by the solver.
544    
545          :rtype: in the list `SolverOptions.NO_REORDERING`, `SolverOptions.NO_REORDERING`,  `SolverOptions.NO_REORDERING`, `SolverOptions.DEFAULT_REORDERING`          :rtype: ordering in 'SolverOptions.NO_REORDERING', 'SolverOptions.MINIMUM_FILL_IN', 'SolverOptions.NESTED_DISSECTION', 'SolverOptions.DEFAULT_REORDERING'
546          """          """
547          return self.__reordering          return self.__reordering
548      def setRestart(self,restart=None):      def setRestart(self,restart=None):
# Line 554  class SolverOptions(object): Line 577  class SolverOptions(object):
577              return -1              return -1
578              else:              else:
579              return r              return r
580      
581        def setDiagonalDominanceThreshold(self,value=0.5):
582            """
583            Sets the threshold for diagonal dominant rows which are eliminated during AMG coarsening.
584    
585         :param value: threshold
586         :type value: ``float``
587            """
588            value=float(value)
589            if value<0 or value>1.:
590           raise ValueError,"Diagonal dominance threshold must be between 0 and 1."
591        self.__diagonal_dominance_threshold=value
592            
593        def getDiagonalDominanceThreshold(self):
594            """
595            Returns the threshold for diagonal dominant rows which are eliminated during AMG coarsening.
596    
597            :rtype: ``float``
598            """
599            return self.__diagonal_dominance_threshold
600            
601      def setTruncation(self,truncation=20):      def setTruncation(self,truncation=20):
602          """          """
603          Sets the number of residuals in GMRES to be stored for orthogonalization.  The more residuals are stored          Sets the number of residuals in GMRES to be stored for orthogonalization.  The more residuals are stored
# Line 609  class SolverOptions(object): Line 653  class SolverOptions(object):
653          :rtype: ``int``          :rtype: ``int``
654          """          """
655          return self.__iter_max          return self.__iter_max
656      def setLevelMax(self,level_max=5):      def setLevelMax(self,level_max=100):
657          """          """
658          Sets the maximum number of coarsening levels to be used in an algebraic multi level solver or preconditioner          Sets the maximum number of coarsening levels to be used in an algebraic multi level solver or preconditioner
659    
# Line 645  class SolverOptions(object): Line 689  class SolverOptions(object):
689          :rtype: ``float``          :rtype: ``float``
690          """          """
691          return self.__coarsening_threshold          return self.__coarsening_threshold
692      def setNumSweeps(self,sweeps=2):      def setNumSweeps(self,sweeps=1):
693          """          """
694          Sets the number of sweeps in a Jacobi or Gauss-Seidel/SOR preconditioner.          Sets the number of sweeps in a Jacobi or Gauss-Seidel/SOR preconditioner.
695    
# Line 895  class SolverOptions(object): Line 939  class SolverOptions(object):
939          self.__adapt_inner_tolerance=False          self.__adapt_inner_tolerance=False
940      def setInnerToleranceAdaption(self,adapt=True):      def setInnerToleranceAdaption(self,adapt=True):
941          """          """
942          Sets a flag to indicate automatic selection of the inner tolerance.          Sets the flag to indicate automatic selection of the inner tolerance.
943    
944          :param adapt: If ``True``, the inner tolerance is selected automatically.          :param adapt: If ``True``, the inner tolerance is selected automatically.
945          :type adapt: ``bool``          :type adapt: ``bool``
# Line 931  class SolverOptions(object): Line 975  class SolverOptions(object):
975          self.__accept_convergence_failure=False          self.__accept_convergence_failure=False
976      def setAcceptanceConvergenceFailure(self,accept=False):      def setAcceptanceConvergenceFailure(self,accept=False):
977          """          """
978          Sets a flag to indicate the acceptance of a failure of convergence.          Sets the flag to indicate the acceptance of a failure of convergence.
979    
980          :param accept: If ``True``, any failure to achieve convergence is accepted.          :param accept: If ``True``, any failure to achieve convergence is accepted.
981          :type accept: ``bool``          :type accept: ``bool``
# Line 941  class SolverOptions(object): Line 985  class SolverOptions(object):
985          else:          else:
986              self.setAcceptanceConvergenceFailureOff()              self.setAcceptanceConvergenceFailureOff()
987    
988        def useLocalPreconditioner(self):
989            """
990            Returns ``True`` if the preconditoner is applied locally on each MPI. This reducess communication costs
991            and speeds up the application of the preconditioner but at the costs of more iteration steps. This can be an
992            advantage on clusters with slower interconnects.
993    
994            :return: ``True`` if local preconditioning is applied
995            :rtype: ``bool``
996            """
997            return self.__use_local_preconditioner
998    
999        def setLocalPreconditionerOn(self):
1000            """
1001            Sets the flag to use  local preconditioning to on
1002            """
1003            self.__use_local_preconditioner=True
1004        def setLocalPreconditionerOff(self):
1005            """
1006            Sets the flag to use  local preconditioning to off
1007            """
1008            self.__use_local_preconditioner=False
1009            
1010        def setLocalPreconditioner(self,use=False):
1011            """
1012            Sets the flag to use  local preconditioning
1013    
1014            :param use: If ``True``, local proconditioning on each MPI rank is applied
1015            :type use: ``bool``
1016            """
1017            if use:
1018                self.setUseLocalPreconditionerOn()
1019            else:
1020                self.setUseLocalPreconditionerOff()
1021                
1022        def setMinCoarseMatrixSparsity(self,sparsity=0.05):
1023           """
1024           Sets the minimum sparsity on the coarsest level. Typically
1025           a direct solver is used when the sparsity becomes bigger than
1026           the set limit.
1027          
1028           :param sparsity: minimual sparsity
1029           :type sparsity: ``float``
1030           """
1031           sparsity=float(sparsity)
1032           if factor<0:
1033         raise ValueError,"sparsity must be non-negative."
1034           if factor>1:
1035               raise ValueError,"sparsity must be less than 1."
1036           self.__min_sparsity=factor
1037        def setMinCoarseMatrixSparsity(self,sparsity=0.05):
1038           """
1039           Sets the minimum sparsity on the coarsest level. Typically
1040           a direct solver is used when the sparsity becomes bigger than
1041           the set limit.
1042          
1043           :param sparsity: minimual sparsity
1044           :type sparsity: ``float``
1045           """
1046           sparsity=float(sparsity)
1047           if sparsity<0:
1048         raise ValueError,"sparsity must be non-negative."
1049           if sparsity>1:
1050              raise ValueError,"sparsity must be less than 1."
1051           self.__min_sparsity=sparsity
1052    
1053        def getMinCoarseMatrixSparsity(self):
1054          """
1055          Returns the minimum sparsity on the coarsest level. Typically
1056          a direct solver is used when the sparsity becomes bigger than
1057          the set limit.
1058      
1059          :return: minimual sparsity
1060          :rtype: ``float``
1061          """
1062          return self.__min_sparsity
1063    
1064        def setNumRefinements(self,refinements=2):
1065          """
1066          Sets the number of refinement steps to refine the solution when a direct solver is applied.
1067      
1068          :param refinements: number of refinements
1069          :type refinements: non-negative ``int``
1070          """
1071          refinements=int(refinements)
1072          if refinements<0:
1073         raise ValueError,"number of refinements must be non-negative."
1074          self.__refinements=refinements
1075      
1076        def getNumRefinements(self):
1077           """
1078           Returns the number of refinement steps to refine the solution when a direct solver is applied.
1079          
1080           :rtype: non-negative ``int``
1081           """
1082           return self.__refinements
1083    
1084        def setNumCoarseMatrixRefinements(self,refinements=2):
1085          """
1086          Sets the number of refinement steps to refine the solution on the coarset level when a direct solver is applied.
1087      
1088          :param refinements: number of refinements
1089          :type refinements: non-negative ``int``
1090          """
1091          refinements=int(refinements)
1092          if refinements<0:
1093         raise ValueError,"number of refinements must be non-negative."
1094          self.__coarse_refinements=refinements
1095      
1096        def getNumCoarseMatrixRefinements(self):
1097          """
1098          Returns the number of resfinement steps to refine the solution on the coarset level when a direct solver is applied.
1099          
1100          :rtype: non-negative ``int``
1101          """
1102          return self.__coarse_refinements
1103    
1104        def usePanel(self):
1105            """
1106            Returns ``True`` if a panel is used to serach for unknown in the AMG coarsening, The panel approach is normally faster
1107            but can lead to larger coarse level systems.
1108            
1109            :return: ``True`` if a panel is used to find unknowns in AMG coarsening
1110            :rtype: ``bool``
1111            """
1112            return self.__use_panel
1113    
1114        def setUsePanelOn(self):
1115            """
1116            Sets the flag to use a panel to find unknowns in AMG coarsening
1117            """
1118            self.__use_panel=True
1119            
1120        def setUsePanelOff(self):
1121            """
1122            Sets the flag to use a panel to find unknowns in AMG coarsening to off
1123            """
1124            self.__use_panel=False
1125            
1126        def setUsePanel(self,use=True):
1127            """
1128            Sets the flag to use  a panel to find unknowns in AMG coarsening
1129    
1130            :param use: If ``True``,a panel is used to find unknowns in AMG coarsening
1131            :type use: ``bool``
1132            """
1133            if use:
1134                self.setUsePanelOn()
1135            else:
1136                self.setUsePanelOff()
1137                
1138        def useDirectInterpolation(self):
1139            """
1140            Returns ``True`` if direct interpolation is used in AMG.
1141    
1142        :return: ``True`` if direct interpolation is used in AMG.
1143            :rtype: ``bool``
1144            """
1145            return self.__use_direct_interpolation
1146    
1147        def setUseDirectInterpolationOn(self):
1148            """
1149            Sets the flag to use direct interpolation in AMG
1150            """
1151            self.__use_direct_interpolation=True
1152            
1153        def setUseDirectInterpolationOff(self):
1154            """
1155            Sets the flag to use direct interpolation in AMG
1156            """
1157            self.__use_direct_interpolation=False
1158            
1159        def setUseDirectInterpolation(self,use=False):
1160            """
1161            Sets the flag to use direct interpolation in AMG
1162    
1163        :param use: If ``True``, direct interpolation in AMG
1164        :type use: ``bool``
1165            """
1166            if use:
1167                self.setUseDirectInterpolationOn()
1168            else:
1169                self.setUseDirectInterpolationOff()
1170    
1171    
1172  class IllegalCoefficient(ValueError):  class IllegalCoefficient(ValueError):
1173     """     """
1174     Exception that is raised if an illegal coefficient of the general or     Exception that is raised if an illegal coefficient of the general or
# Line 1544  class LinearProblem(object): Line 1772  class LinearProblem(object):
1772        :return: True if the current solver method is lumping        :return: True if the current solver method is lumping
1773        :rtype: ``bool``        :rtype: ``bool``
1774        """        """
1775        return self.getSolverOptions().getSolverMethod()==self.getSolverOptions().LUMPING        return self.getSolverOptions().getSolverMethod() in [ SolverOptions.ROWSUM_LUMPING, SolverOptions.HRZ_LUMPING ]
1776     # ==========================================================================     # ==========================================================================
1777     #    symmetry  flag:     #    symmetry  flag:
1778     # ==========================================================================     # ==========================================================================
# Line 2423  class LinearPDE(LinearProblem): Line 2651  class LinearPDE(LinearProblem):
2651        """        """
2652        Returns the system type which needs to be used by the current set up.        Returns the system type which needs to be used by the current set up.
2653        """        """
2654        solver_options=self.getSolverOptions()        if self.isUsingLumping():
2655        return self.getDomain().getSystemMatrixTypeId(solver_options.getSolverMethod(), solver_options.getPreconditioner(),solver_options.getPackage(), solver_options.isSymmetric())       return "__ESCRIPT_DATA"
2656          else:
2657         solver_options=self.getSolverOptions()
2658         return self.getDomain().getSystemMatrixTypeId(solver_options.getSolverMethod(), solver_options.getPreconditioner(),solver_options.getPackage(), solver_options.isSymmetric())
2659    
2660     def checkSymmetry(self,verbose=True):     def checkSymmetry(self,verbose=True):
2661        """        """
# Line 2475  class LinearPDE(LinearProblem): Line 2706  class LinearPDE(LinearProblem):
2706         if not self.isSolutionValid():         if not self.isSolutionValid():
2707            mat,f=self.getSystem()            mat,f=self.getSystem()
2708            if self.isUsingLumping():            if self.isUsingLumping():
2709             if not util.inf(abs(mat)) > 0.:
2710             raise ZeroDivisionError,"Lumped mass matrix as zero entry (try order 1 elements or HRZ lumping)."
2711               self.setSolution(f*1/mat)               self.setSolution(f*1/mat)
2712            else:            else:
2713               self.trace("PDE is resolved.")               self.trace("PDE is resolved.")
# Line 2548  class LinearPDE(LinearProblem): Line 2781  class LinearPDE(LinearProblem):
2781                   self.resetOperator()                   self.resetOperator()
2782                   operator=self.getCurrentOperator()                   operator=self.getCurrentOperator()
2783                   if hasattr(self.getDomain(), "addPDEToLumpedSystem") :                   if hasattr(self.getDomain(), "addPDEToLumpedSystem") :
2784                      self.getDomain().addPDEToLumpedSystem(operator, D_times_e, d_times_e)              hrz_lumping=( self.getSolverOptions().getSolverMethod() ==  SolverOptions.HRZ_LUMPING )
2785                      self.getDomain().addPDEToLumpedSystem(operator, D_reduced_times_e, d_reduced_times_e)              self.getDomain().addPDEToLumpedSystem(operator, D_times_e, d_times_e,  hrz_lumping )
2786                self.getDomain().addPDEToLumpedSystem(operator, D_reduced_times_e, d_reduced_times_e, hrz_lumping)
2787                   else:                   else:
2788                      self.getDomain().addPDEToRHS(operator, \                      self.getDomain().addPDEToRHS(operator, \
2789                                                   escript.Data(), \                                                   escript.Data(), \
# Line 3100  class LameEquation(LinearPDE): Line 3334  class LameEquation(LinearPDE):
3334       else:       else:
3335          return super(LameEquation, self).getCoefficient(name)          return super(LameEquation, self).getCoefficient(name)
3336    
3337    
3338  def LinearSinglePDE(domain,debug=False):  def LinearSinglePDE(domain,debug=False):
3339     """     """
3340     Defines a single linear PDE.     Defines a single linear PDE.
# Line 3274  class TransportPDE(LinearProblem): Line 3509  class TransportPDE(LinearProblem):
3509                            of solution components is extracted from the                            of solution components is extracted from the
3510                            coefficients.                            coefficients.
3511       :param debug: if True debug information is printed       :param debug: if True debug information is printed
3512       :param useBackwardEuler: if set the backward Euler scheme is used. Otherwise the Crank-Nicholson scheme is applied. Note that backward Euler scheme will return a safe time step size which is practically infinity as the scheme is unconditional unstable. The Crank-Nicholson scheme provides a higher accuracy but requires to limit the time step size to be stable.       :param useBackwardEuler: if set the backward Euler scheme is used. Otherwise the Crank-Nicolson scheme is applied. Note that backward Euler scheme will return a safe time step size which is practically infinity as the scheme is unconditional unstable. The Crank-Nicolson scheme provides a higher accuracy but requires to limit the time step size to be stable.
3513       :type useBackwardEuler: ``bool``       :type useBackwardEuler: ``bool``
3514       """       """
3515       if useBackwardEuler:       if useBackwardEuler:
# Line 3536  class TransportPDE(LinearProblem): Line 3771  class TransportPDE(LinearProblem):
3771            if self.getNumSolutions() == 1:            if self.getNumSolutions() == 1:
3772          if u0.getShape()!=():          if u0.getShape()!=():
3773              raise ValueError,"Illegal shape %s of initial solution."%(u0.getShape(),)              raise ValueError,"Illegal shape %s of initial solution."%(u0.getShape(),)
3774          else:            else:
3775              if u0.getShape()!=(self.getNumSolutions(),):              if u0.getShape()!=(self.getNumSolutions(),):
3776                raise ValueError,"Illegal shape %s of initial solution."%(u0.getShape(),)                raise ValueError,"Illegal shape %s of initial solution."%(u0.getShape(),)
3777        self.setSolution(self.getOperator().solve(u0, self.getRightHandSide(),dt,option_class))        self.setSolution(self.getOperator().solve(u0, self.getRightHandSide(),dt,option_class))
# Line 3636  class TransportPDE(LinearProblem): Line 3871  class TransportPDE(LinearProblem):
3871       """       """
3872       super(TransportPDE,self).setDebugOff()       super(TransportPDE,self).setDebugOff()
3873            
3874    def SingleTransportPDE(domain,useBackwardEuler=False, debug=False):
3875       """
3876       Defines a single transport problem
3877    
3878       :param domain: domain of the PDE
3879       :type domain: `Domain`
3880       :param debug: if True debug information is printed
3881       :param useBackwardEuler: if set the backward Euler scheme is used. Otherwise the Crank-Nicolson scheme is applied. Note that backward Euler scheme will return a safe time step size which is practically infinity as the scheme is unconditional unstable. The Crank-Nicolson scheme provides a higher accuracy but requires to limit the time step size to be stable.
3882       :rtype: `TransportPDE`
3883       """
3884       return TransportPDE(domain,numEquations=1,numSolutions=1, useBackwardEuler=useBackwardEuler, debug=debug)

Legend:
Removed from v.3051  
changed lines
  Added in v.3402

  ViewVC Help
Powered by ViewVC 1.1.26