HermesCommon  3.0
amesos_solver.cpp
Go to the documentation of this file.
1 // This file is part of HermesCommon
2 //
3 // Copyright (c) 2009 hp-FEM group at the University of Nevada, Reno (UNR).
4 // Email: hpfem-group@unr.edu, home page: http://www.hpfem.org/.
5 //
6 // Hermes2D is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published
8 // by the Free Software Foundation; either version 2 of the License,
9 // or (at your option) any later version.
10 //
11 // Hermes2D is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with Hermes2D; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include "config.h"
23 #ifdef HAVE_AMESOS
24 #include "amesos_solver.h"
25 #include "callstack.h"
26 #include "Amesos_ConfigDefs.h"
27 
28 namespace Hermes
29 {
30  namespace Solvers
31  {
32  template<typename Scalar> Amesos AmesosSolver<Scalar>::factory;
33 
34  template<typename Scalar>
36  : DirectSolver<Scalar>(m, rhs), m(m), rhs(rhs)
37  {
38  solver = factory.Create(solver_type, problem);
39  assert(solver != nullptr);
40  // WARNING: Amesos does not use RCP to allocate the Amesos_BaseSolver,
41  // so don't forget to delete it!
42  // ( Amesos.cpp, line 88, called from factory.Create():
43  // return new_ Amesos_Klu(LinearProblem); )
44  }
45 
46  template<typename Scalar>
48  {
49  if (solver)
50  {
51  delete solver;
52  solver = nullptr;
53  }
54  }
55 
56  template<typename Scalar>
58  {
59  this->free();
60  }
61 
62  template<typename Scalar>
63  bool AmesosSolver<Scalar>::is_available(const char *name)
64  {
65  return factory.Query(name);
66  }
67 
68  template<typename Scalar>
69  void AmesosSolver<Scalar>::set_use_transpose(bool use_transpose)
70  {
71  solver->SetUseTranspose(use_transpose);
72  }
73 
74  template<typename Scalar>
76  {
77  return solver->UseTranspose();
78  }
79 
80  template<typename Scalar>
82  {
83  return m->size;
84  }
85 
86  template<>
88  {
89  assert(m != nullptr);
90  assert(rhs != nullptr);
91 
92  assert(m->size == rhs->size);
93 
94  problem.SetOperator(m->mat);
95  problem.SetRHS(rhs->vec);
96  Epetra_Vector x(*rhs->std_map);
97  problem.SetLHS(&x);
98 
99  if (!setup_factorization())
100  this->warn("AmesosSolver: LU factorization could not be completed");
101 
102  int status = solver->Solve();
103  if (status != 0)
104  throw Hermes::Exceptions::Exception("AmesosSolver: Solution failed.");
105 
106  this->tick();
107  this->time = this->accumulated();
108 
109  free_with_check(this->sln);
110  this->sln = malloc_with_check<AmesosSolver<double>, double>(m->size, this);
111  // copy the solution into sln vector
112  memset(this->sln, 0, m->size * sizeof(double));
113 
114  for (unsigned int i = 0; i < m->size; i++)
115  this->sln[i] = x[i];
116  }
117 
118  template<>
120  {
121  assert(m != nullptr);
122  assert(rhs != nullptr);
123 
124  assert(m->size == rhs->size);
125 
126  throw Hermes::Exceptions::Exception("AmesosSolver<Scalar>::solve() not yet implemented for complex problems");
127 
128  if (!setup_factorization())
129  this->warn("AmesosSolver: LU factorization could not be completed");
130 
131  int status = solver->Solve();
132  if (status != 0)
133  throw Hermes::Exceptions::Exception("AmesosSolver: Solution failed.");
134 
135  this->tick();
136  this->time = this->accumulated();
137 
138  free_with_check(this->sln);
139  this->sln = malloc_with_check<AmesosSolver<std::complex<double> >, std::complex<double>>(m->size, this);
140  // copy the solution into sln vector
141  memset(this->sln, 0, m->size * sizeof(std::complex<double>));
142  }
143 
144  template<typename Scalar>
146  {
147  // Perform both factorization phases for the first time.
148  int eff_fact_scheme;
149  if (this->reuse_scheme != HERMES_CREATE_STRUCTURE_FROM_SCRATCH &&
150  solver->NumSymbolicFact() == 0 && solver->NumNumericFact() == 0)
151  eff_fact_scheme = HERMES_CREATE_STRUCTURE_FROM_SCRATCH;
152  else
153  eff_fact_scheme = this->reuse_scheme;
154 
155  int status;
156  switch (eff_fact_scheme)
157  {
159  //debug_log("Factorizing symbolically.");
160  status = solver->SymbolicFactorization();
161  if (status != 0)
162  {
163  this->warn("Symbolic factorization failed.");
164  return false;
165  }
166 
169  status = solver->NumericFactorization();
170  if (status != 0)
171  {
172  this->warn("Numeric factorization failed.");
173  return false;
174  }
175  }
176 
177  return true;
178  }
179 
180  template class HERMES_API AmesosSolver < double > ;
181  template class HERMES_API AmesosSolver < std::complex<double> > ;
182  }
183 }
184 #endif
AmesosSolver class as an interface to Amesos.
General namespace for the Hermes library.
Exception interface Basically a std::exception, but with a constructor with string and with print_msg...
Definition: exceptions.h:49
unsigned int size
matrix size
Definition: matrix.h:97
Encapsulation of Amesos linear solver.
Definition: amesos_solver.h:39
File containing functionality for investigating call stack.
pattern as the one already factorized.
unsigned int size
size of vector
Definition: vector.h:111