forked from idaholab/moose
-
Notifications
You must be signed in to change notification settings - Fork 0
/
EigenProblem.h
167 lines (131 loc) · 5.13 KB
/
EigenProblem.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html
#pragma once
// MOOSE Includes
#include "FEProblemBase.h"
#include "Eigenvalue.h"
// Forward declarations
class EigenProblem;
class NonlinearEigenSystem;
template <>
InputParameters validParams<EigenProblem>();
/**
* Problem for solving eigenvalue problems
*/
class EigenProblem : public FEProblemBase
{
public:
static InputParameters validParams();
EigenProblem(const InputParameters & parameters);
virtual void solve() override;
virtual void init() override;
virtual bool converged() override;
virtual unsigned int getNEigenPairsRequired() { return _n_eigen_pairs_required; }
virtual void setNEigenPairsRequired(unsigned int n_eigen_pairs)
{
_n_eigen_pairs_required = n_eigen_pairs;
}
virtual bool isGeneralizedEigenvalueProblem() { return _generalized_eigenvalue_problem; }
virtual bool isNonlinearEigenvalueSolver();
// silences warning in debug mode about the other computeJacobian signature being hidden
using FEProblemBase::computeJacobian;
NonlinearEigenSystem & getNonlinearEigenSystem() { return *_nl_eigen; }
virtual void checkProblemIntegrity() override;
/**
* A flag indicates if a negative sign is used in eigen kernels.
* If the negative sign is used, eigen kernels are consistent in nonlinear solver.
* In nonlinear solver, RHS kernels always have a negative sign.
*/
bool negativeSignEigenKernel() { return _negative_sign_eigen_kernel; }
/**
* If we need to initialize eigen vector. We initialize the eigen vector
* only when "auto_initialization" is on and nonlinear eigen solver is selected.
*/
bool needInitializeEigenVector();
/*
* Specify whether or not to initialize eigenvector automatically
*/
void needInitializeEigenVector(bool need) { _auto_initilize_eigen_vector = need; }
#if LIBMESH_HAVE_SLEPC
void setEigenproblemType(Moose::EigenProblemType eigen_problem_type);
virtual Real computeResidualL2Norm() override;
/**
* Form a Jacobian matrix for all kernels and BCs with a given tag
*/
virtual void computeJacobianTag(const NumericVector<Number> & soln,
SparseMatrix<Number> & jacobian,
TagID tag) override;
/**
* Form several matrices simultaneously
*/
void computeMatricesTags(const NumericVector<Number> & soln,
const std::vector<std::unique_ptr<SparseMatrix<Number>>> & jacobians,
const std::set<TagID> & tags);
/**
* Form two Jacobian matrices, whre each is associateed with one tag, through one
* element-loop.
*/
virtual void computeJacobianAB(const NumericVector<Number> & soln,
SparseMatrix<Number> & jacobianA,
SparseMatrix<Number> & jacobianB,
TagID tagA,
TagID tagB);
virtual void computeJacobianBlocks(std::vector<JacobianBlock *> & blocks) override;
/**
* Form a vector for all kernels and BCs with a given tag
*/
virtual void computeResidualTag(const NumericVector<Number> & soln,
NumericVector<Number> & residual,
TagID tag) override;
/**
* Form two vetors, whre each is associateed with one tag, through one
* element-loop.
*/
virtual void computeResidualAB(const NumericVector<Number> & soln,
NumericVector<Number> & residualA,
NumericVector<Number> & residualB,
TagID tagA,
TagID tagB);
/**
* Scale eigenvector. Scaling_factor is often computed based on physics.
*/
void scaleEigenvector(const Real scaling_factor);
/**
* For nonlinear eigen solver, a good initial value can help convergence.
* Should set initial values for only eigen variables.
*/
void initEigenvector(const Real initial_value);
/**
*
*/
bool doInitialFreePowerIteration() { return _do_initial_free_power_iteration; }
void doInitialFreePowerIteration(bool do_power) { _do_initial_free_power_iteration = do_power; }
/**
* Which eigenvalue is active
*/
unsigned int activeEigenvalueIndex() { return _active_eigen_index; }
const ConsoleStream & console() { return _console; }
virtual void initPetscOutput() override;
#endif
protected:
unsigned int _n_eigen_pairs_required;
bool _generalized_eigenvalue_problem;
std::shared_ptr<NonlinearEigenSystem> _nl_eigen;
bool _negative_sign_eigen_kernel;
unsigned int _active_eigen_index;
bool _auto_initilize_eigen_vector;
bool _do_initial_free_power_iteration;
/// Timers
PerfID _compute_jacobian_tag_timer;
PerfID _compute_jacobian_ab_timer;
PerfID _compute_residual_tag_timer;
PerfID _compute_residual_ab_timer;
PerfID _solve_timer;
PerfID _compute_jacobian_blocks_timer;
};