14 template<
typename scalar>
20 template<
typename scalar>
23 assert(A.rows() == A.cols());
38 auto U12 = A.block(0, 1, 1, n-1);
41 auto L21 = A.block(1, 0, n-1, 1) / A(0, 0);
44 auto A22 = A.block(1, 1, n-1, n-1);
45 Matrix<scalar> tmp = A22 - L21 * U12;
50 L.block(1, 0, n-1, 1) = L21;
51 U.block(0, 1, 1, n-1) = U12;
52 L.block(1, 1, n-1, n-1) = get<0>(LU22);
53 U.block(1, 1, n-1, n-1) = get<1>(LU22);
63 template<
typename time>
64 vector<time>
augment(time t0, time
dt, vector<time>
const & nodes)
66 vector<time>
t(1 + nodes.size());
68 for (
size_t m = 0; m < nodes.size(); m++) {
69 t[m+1] = t0 + dt * nodes[m];
78 template<
typename time>
81 if (this->quadrature->right_is_node()) {
82 this->end_state->copy(this->state.back());
84 vector<shared_ptr<Encapsulation<time>>> dst = { this->end_state };
85 dst[0]->copy(this->start_state);
86 dst[0]->mat_apply(dst, this->get_controller()->get_step_size(), this->quadrature->get_b_mat(), this->fs_impl,
false);
90 template<
typename time>
95 auto const nodes = this->quadrature->get_nodes();
96 auto const num_nodes = this->quadrature->get_num_nodes();
98 if (this->quadrature->left_is_node()) {
99 ML_CLOG(INFO,
"Sweeper",
"implicit sweeper shouldn't include left endpoint");
100 throw ValueError(
"implicit sweeper shouldn't include left endpoint");
103 for (
size_t m = 0; m < num_nodes; m++) {
108 Matrix<time> QT = this->quadrature->get_q_mat().transpose();
112 this->q_tilde = U.transpose();
114 ML_CLOG(DEBUG,
"Sweeper",
"Q':" << endl << QT);
115 ML_CLOG(DEBUG,
"Sweeper",
"L:" << endl << L);
116 ML_CLOG(DEBUG,
"Sweeper",
"U:" << endl << U);
117 ML_CLOG(DEBUG,
"Sweeper",
"LU:" << endl << L * U);
118 ML_CLOG(DEBUG,
"Sweeper",
"q_tilde:" << endl << this->q_tilde);
121 template<
typename time>
126 auto const dt = this->get_controller()->get_step_size();
127 auto const t = this->get_controller()->get_time();
129 ML_CLOG(INFO,
"Sweeper",
"predicting step " << this->get_controller()->get_step() + 1
130 <<
" (t=" <<
t <<
", dt=" <<
dt <<
")");
132 auto const anodes =
augment(
t,
dt, this->quadrature->get_nodes());
133 for (
size_t m = 0; m < anodes.size() - 1; ++m) {
134 this->impl_solve(this->fs_impl[m], this->state[m], anodes[m], anodes[m+1] - anodes[m],
135 m == 0 ? this->get_start_state() : this->state[m-1]);
138 this->set_end_state();
141 template<
typename time>
144 auto const dt = this->get_controller()->get_step_size();
145 auto const t = this->get_controller()->get_time();
147 ML_CLOG(INFO,
"Sweeper",
"sweeping on step " << this->get_controller()->get_step() + 1
148 <<
" in iteration " << this->get_controller()->get_iteration()
149 <<
" (dt=" <<
dt <<
")");
151 this->s_integrals[0]->mat_apply(this->s_integrals,
dt, this->quadrature->get_s_mat(), this->fs_impl,
true);
152 if (this->fas_corrections.size() > 0) {
153 for (
size_t m = 0; m < this->s_integrals.size(); m++) {
154 this->s_integrals[m]->saxpy(1.0, this->fas_corrections[m]);
158 for (
size_t m = 0; m < this->s_integrals.size(); m++) {
159 for (
size_t n = 0; n < m; n++) {
160 this->s_integrals[m]->saxpy(-
dt*this->q_tilde(m, n), this->fs_impl[n]);
166 auto const anodes =
augment(
t,
dt, this->quadrature->get_nodes());
167 for (
size_t m = 0; m < anodes.size() - 1; ++m) {
168 auto const ds = anodes[m+1] - anodes[m];
169 rhs->copy(m == 0 ? this->get_start_state() : this->state[m-1]);
170 rhs->saxpy(1.0, this->s_integrals[m]);
171 rhs->saxpy(-ds, this->fs_impl[m]);
172 for (
size_t n = 0; n < m; n++) {
173 rhs->saxpy(
dt*this->q_tilde(m, n), this->fs_impl[n]);
175 this->impl_solve(this->fs_impl[m], this->state[m], anodes[m], ds, rhs);
177 this->set_end_state();
180 template<
typename time>
183 this->start_state->copy(this->end_state);
186 template<
typename time>
192 auto const dt = this->get_controller()->get_step_size();
193 auto const t0 = this->get_controller()->get_time();
194 auto const nodes = this->quadrature->get_nodes();
195 for (
size_t m = 0; m < nodes.size(); m++) {
196 this->f_impl_eval(this->fs_impl[m], this->state[m], t0 +
dt * nodes[m]);
200 template<
typename time>
203 dst[0]->mat_apply(dst, dt, this->quadrature->get_q_mat(), this->fs_impl,
true);
void setup(shared_ptr< WrapperInterface< scalar, time >> wrapper)
#define ML_CLOG(level, logger_id, x)
same as CLOG(level, logger, x) from easylogging++
vector< time > augment(time t0, time dt, vector< time > const &nodes)
Augment nodes: nodes <- [t0] + dt * nodes.
virtual void setup(bool coarse) override
Setup (allocate etc) the sweeper.
pair< Matrix< scalar >, Matrix< scalar > > lu_pair
Data/solution encapsulation.
#define UNUSED(expr)
Denoting unused function parameters for omitting compiler warnings.
Eigen::Matrix< scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > Matrix
static lu_pair< scalar > lu_decomposition(const Matrix< scalar > &A)
LU (without pivoting) decomposition.