Peano
Loading...
Searching...
No Matches
Solver.cpp
Go to the documentation of this file.
1#include "Solver.h"
2
5#include "tarch/mpi/Rank.h"
6#include <cmath>
7
8
9tarch::logging::Log mghype::matrixfree::solvers::Solver::_log( "mghype::matrixfree::solvers::Solver" );
10
11
13 const std::string& name,
14 double tolerance
15):
16 _name(name),
17 _tolerance(tolerance),
18 _initialGlobalResidualMaxNorm(0.0),
19 _initialGlobalResidualEukledianNormSquared(0.0),
20 _initialGlobalResidualHNormSquared(0.0),
21 _previousGlobalResidualMaxNorm(0.0),
22 _previousGlobalResidualEukledianNormSquared(0.0),
23 _previousGlobalResidualHNormSquared(0.0),
24 _globalDeltaUMaxNorm(0.0),
25 _globalDeltaUEukledianNormSquared(0.0),
26 _globalDeltaUHNormSquared(0.0),
27 _minH(std::numeric_limits<double>::max()),
28 _maxH(0.0) {
29 const std::string prefix = "Abstract";
30 std::string::size_type index = _name.find( prefix );
31 if (index!=std::string::npos) {
32 _name.erase(index, prefix.length());
33 }
34}
35
36
38 return _globalResidualMaxNorm;
39}
40
41
43 int residualReducedUnderThreshold = 0;
44 int residualGrows = 0;
45
46 // The criterion holds if ALL three norms reach the tolerance
47 // or if the total numberOfResidualGrowths exceeds a limit
48
49 if ( tarch::la::equals(_initialGlobalResidualMaxNorm,0.0) ) {
50 _initialGlobalResidualMaxNorm = _globalResidualMaxNorm;
51 }
52 else if (_previousGlobalResidualMaxNorm * 1.2 < _globalResidualMaxNorm) {
53 logWarning( "terminationCriterionHolds()", "max residual grows from " << _previousGlobalResidualMaxNorm << " to " << _globalResidualMaxNorm );
54 residualGrows++;
55 }
56 else if (_globalResidualMaxNorm / _initialGlobalResidualMaxNorm < _tolerance) {
57 residualReducedUnderThreshold++;
58 }
59
60 _previousGlobalResidualMaxNorm = _globalResidualMaxNorm;
61 _previousGlobalResidualEukledianNormSquared = _globalResidualEukledianNormSquared;
62 _previousGlobalResidualHNormSquared = _globalResidualHNormSquared;
63
64 logDebug( "terminationCriterionHolds()", "residualReducedUnderThreshold=" << residualReducedUnderThreshold );
65 static int numberOfResidualGrowths = 0;
66 const int numberOfChecks = 1; // reset to 3 for all-norms check and uncomment the blocks above...
67 const int residualGrowthsLimit = 50; // stop if the residual norm increases over several consecutive iterations
68
69 if (residualGrows==numberOfChecks) numberOfResidualGrowths++;
70
71 bool output = (residualReducedUnderThreshold==numberOfChecks or numberOfResidualGrowths > residualGrowthsLimit);
72
73 if (residualReducedUnderThreshold==numberOfChecks)
74 logInfo( "terminationCriterionHolds()", "ONLY CHECKING MAX-NORM: terminating because residualReducedUnderThreshold==" << residualReducedUnderThreshold );
75
76 if (numberOfResidualGrowths > residualGrowthsLimit)
77 logInfo( "terminationCriterionHolds()", "terminating because numberOfResidualGrowths==" << numberOfResidualGrowths );
78
79 return output;
80}
81
82
84 tarch::multicore::Lock lock( _semaphore );
85
86 _globalResidualMaxNorm = 0.0;
87 _globalResidualEukledianNormSquared = 0.0;
88 _globalResidualHNormSquared = 0.0;
89
90 _globalDeltaUMaxNorm = 0.0;
91 _globalDeltaUEukledianNormSquared = 0.0;
92 _globalDeltaUHNormSquared = 0.0;
93
94 // Commenting out as we will set this during init and leave it alone...
95 // _minH = std::numeric_limits<double>::max();
96 // _maxH = 0;
97}
98
99
101 double residual,
103) {
104 tarch::multicore::Lock lock( _semaphore );
105
106 _globalResidualMaxNorm = std::max( _globalResidualMaxNorm, std::abs(residual) );
107 _globalResidualEukledianNormSquared += residual * residual;
108 _globalResidualHNormSquared += residual * residual * tarch::la::volume(h);
109}
110
111
113 double du,
115) {
116 tarch::multicore::Lock lock( _semaphore );
117
118 _globalDeltaUMaxNorm = std::max( _globalDeltaUMaxNorm, std::abs(du) );
119 _globalDeltaUEukledianNormSquared += du * du;
120 _globalDeltaUHNormSquared += du * du * tarch::la::volume(h);
121}
122
123
126) {
127 _minH = std::min( _minH, tarch::la::min(h) );
128 _maxH = std::max( _maxH, tarch::la::max(h) );
129}
130
131
133 std::ostringstream msg;
134 msg << _name
135 << ": |r|_max=" << _globalResidualMaxNorm
136 << ", |r|_2=" << std::sqrt( _globalResidualEukledianNormSquared )
137 << ", |r|_h=" << std::sqrt( _globalResidualHNormSquared )
138 << ", |du|_max=" << _globalDeltaUMaxNorm
139 << ", |du|_2=" << std::sqrt( _globalDeltaUEukledianNormSquared )
140 << ", |du|_h=" << std::sqrt( _globalDeltaUHNormSquared )
141 << ", h_min=" << _minH
142 << ", h_max=" << _maxH;
143 return msg.str();
144}
145
146
148 #if defined(Parallel)
149 double residualMax = _globalResidualMaxNorm;
150 double residual2 = _globalResidualEukledianNormSquared;
151 double residualH = _globalResidualHNormSquared;
152 double duMax = _globalDeltaUMaxNorm;
153 double du2 = _globalDeltaUEukledianNormSquared;
154 double duH = _globalDeltaUHNormSquared;
155 double hMin = _minH;
156 double hMax = _maxH;
157
158 MPI_Reduce( &residualMax, &_globalResidualMaxNorm, 1, MPI_DOUBLE, MPI_MAX, tarch::mpi::Rank::getGlobalMasterRank(), tarch::mpi::Rank::getInstance().getCommunicator() );
159 MPI_Reduce( &residual2, &_globalResidualEukledianNormSquared, 1, MPI_DOUBLE, MPI_SUM, tarch::mpi::Rank::getGlobalMasterRank(), tarch::mpi::Rank::getInstance().getCommunicator() );
160 MPI_Reduce( &residualH, &_globalResidualHNormSquared, 1, MPI_DOUBLE, MPI_SUM, tarch::mpi::Rank::getGlobalMasterRank(), tarch::mpi::Rank::getInstance().getCommunicator() );
161
162 MPI_Reduce( &duMax, &_globalDeltaUMaxNorm, 1, MPI_DOUBLE, MPI_MAX, tarch::mpi::Rank::getGlobalMasterRank(), tarch::mpi::Rank::getInstance().getCommunicator() );
163 MPI_Reduce( &du2, &_globalDeltaUEukledianNormSquared, 1, MPI_DOUBLE, MPI_SUM, tarch::mpi::Rank::getGlobalMasterRank(), tarch::mpi::Rank::getInstance().getCommunicator() );
164 MPI_Reduce( &duH, &_globalDeltaUHNormSquared, 1, MPI_DOUBLE, MPI_SUM, tarch::mpi::Rank::getGlobalMasterRank(), tarch::mpi::Rank::getInstance().getCommunicator() );
165
166 MPI_Reduce( &hMin, &_minH, 1, MPI_DOUBLE, MPI_MIN, tarch::mpi::Rank::getGlobalMasterRank(), tarch::mpi::Rank::getInstance().getCommunicator() );
167 MPI_Reduce( &hMax, &_maxH, 1, MPI_DOUBLE, MPI_MAX, tarch::mpi::Rank::getGlobalMasterRank(), tarch::mpi::Rank::getInstance().getCommunicator() );
168 #endif
169}
#define logDebug(methodName, logMacroMessageStream)
Definition Log.h:50
#define logWarning(methodName, logMacroMessageStream)
Wrapper macro around tarch::tarch::logging::Log to improve logging.
Definition Log.h:440
#define logInfo(methodName, logMacroMessageStream)
Wrapper macro around tarch::tarch::logging::Log to improve logging.
Definition Log.h:411
std::string _name
Name of solver.
Definition Solver.h:81
virtual bool terminationCriterionHolds()
Definition Solver.cpp:42
void updateGlobalSolutionUpdates(double deltaU, const tarch::la::Vector< Dimensions, double > &h)
Definition Solver.cpp:112
void synchroniseGlobalResidualAndSolutionUpdate()
Synchronise the global stats between MPI ranks.
Definition Solver.cpp:147
void updateGlobalResidual(double residual, const tarch::la::Vector< Dimensions, double > &h)
Definition Solver.cpp:100
void updateMinMaxMeshSize(const tarch::la::Vector< Dimensions, double > &h)
Definition Solver.cpp:124
void clearGlobalResidualAndSolutionUpdate()
Clear the global mesh stats.
Definition Solver.cpp:83
Solver(const std::string &name, double tolerance)
Construct the solver.
Definition Solver.cpp:12
double getGlobalResidualMaxNorm() const
Definition Solver.cpp:37
virtual std::string toString() const
Definition Solver.cpp:132
static tarch::logging::Log _log
Definition Solver.h:74
Log Device.
Definition Log.h:516
static int getGlobalMasterRank()
Get the global master.
Definition Rank.cpp:415
static Rank & getInstance()
This operation returns the singleton instance.
Definition Rank.cpp:539
Create a lock around a boolean semaphore region.
Definition Lock.h:19
STL namespace.
CF abs(const CF &cf)
Scalar volume(const Vector< Size, Scalar > &vector)
Computes the volume of the tetrahedron spanned by the Cartesian unit vectors scaled by the correspond...
double max(double a, double b, double c)
I need the maximum of three values all the time, to I decided to write a function for this.
Definition Scalar.cpp:8
bool equals(const Matrix< Rows, Cols, Scalar > &lhs, const Matrix< Rows, Cols, Scalar > &rhs, const Scalar &tolerance=NUMERICAL_ZERO_DIFFERENCE)
Compares to matrices on equality by means of a numerical accuracy.
Scalar min(const Vector< Size, Scalar > &vector)
Returns the element with minimal value (NOT absolute value).
Simple vector class.
Definition Vector.h:134