Loading [MathJax]/extensions/tex2jax.js
Plugins
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
newton_limex_impl.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: Copyright (c) 2010-2015: G-CSC, Goethe University Frankfurt
3 * SPDX-License-Identifier: LicenseRef-UG4-LGPL-3.0
4 *
5 * Author: Markus Breit,
6 * but largely copied from ugcore Newton implementation by Andreas Vogel
7 *
8 * This file is part of UG4.
9 *
10 * UG4 is free software: you can redistribute it and/or modify it under the
11 * terms of the GNU Lesser General Public License version 3 (as published by the
12 * Free Software Foundation) with the following additional attribution
13 * requirements (according to LGPL/GPL v3 §7):
14 *
15 * (1) The following notice must be displayed in the Appropriate Legal Notices
16 * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
17 *
18 * (2) The following notice must be displayed at a prominent place in the
19 * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
20 *
21 * (3) The following bibliography is recommended for citation and must be
22 * preserved in all covered files:
23 * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
24 * parallel geometric multigrid solver on hierarchically distributed grids.
25 * Computing and visualization in science 16, 4 (2013), 151-164"
26 * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
27 * flexible software system for simulating pde based models on high performance
28 * computers. Computing and visualization in science 16, 4 (2013), 165-179"
29 *
30 * This program is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 * GNU Lesser General Public License for more details.
34 */
35
36#include <sstream>
37
39//#include "common/util/string_util.h"
40#include "newton_limex.h"
41
42
43#define PROFILE_NEWTON
44#ifdef PROFILE_NEWTON
45 #define NEWTON_PROFILE_FUNC() PROFILE_FUNC_GROUP("Newton")
46 #define NEWTON_PROFILE_BEGIN(name) PROFILE_BEGIN_GROUP(name, "Newton")
47 #define NEWTON_PROFILE_END() PROFILE_END()
48#else
49 #define NEWTON_PROFILE_FUNC()
50 #define NEWTON_PROFILE_BEGIN(name)
51 #define NEWTON_PROFILE_END()
52#endif
53
54
55namespace ug{
56
57template <typename TAlgebra>
60: m_spLinearSolver(NULL),
61 m_N(NULL),
62 m_J(NULL),
63 m_spAss(NULL),
64 m_linSolverSteps(0),
65 m_linSolverRate(0.0)
66{}
67
68
69template <typename TAlgebra>
72: m_spLinearSolver(NULL),
73 m_N(NULL),
74 m_J(NULL),
75 m_spAss(NULL),
76 m_linSolverSteps(0),
77 m_linSolverRate(0.0)
78{
79 init(N);
80}
81
82
83template <typename TAlgebra>
86: m_spLinearSolver(NULL),
87 m_N(new AssembledOperator<TAlgebra>(spAss)),
88 m_J(NULL),
89 m_spAss(spAss),
90 m_linSolverSteps(0),
91 m_linSolverRate(0.0)
92{}
93
94
95template <typename TAlgebra>
97{
98 NEWTON_PROFILE_BEGIN(NewtonLimexSolver_init);
99 m_N = N.template cast_dynamic<AssembledOperator<TAlgebra> >();
100 if (m_N.invalid())
101 UG_THROW("NewtonLimexSolver: currently only works for AssembledDiscreteOperator.");
102
103 m_spAss = m_N->discretization();
104 return true;
105}
106
107
108template <typename TAlgebra>
110{
111 return true;
112}
113
114
115template <typename TAlgebra>
117{
118 NEWTON_PROFILE_BEGIN(NewtonLimexSolver_apply);
119 // check for linear solver
120 if (m_spLinearSolver.invalid())
121 UG_THROW("NewtonLimexSolver::apply: Linear solver not set.");
122
123 // prepare Jacobian
124 if (m_J.invalid() || m_J->discretization() != m_spAss)
125 m_J = make_sp(new AssembledLinearOperator<TAlgebra>(m_spAss));
126
127 m_J->set_level(m_N->level());
128
129 // create tmp vectors
130 SmartPtr<vector_type> spD = u.clone_without_values();
131 SmartPtr<vector_type> spC = u.clone_without_values();
132
133 // set Dirichlet values
134 try {m_N->prepare(u);}
135 UG_CATCH_THROW("NewtonLimexSolver::prepare: Operator preparation failed.");
136
137 // compute defect
138 try
139 {
140 NEWTON_PROFILE_BEGIN(NewtonComputeDefect1);
141 m_N->apply(*spD, u);
143 }
144 UG_CATCH_THROW("NewtonLimexSolver::apply: Defect computation failed.");
145
146 // increase offset of output for linear solver
147 const int stdLinOffset = m_spLinearSolver->standard_offset();
148 m_spLinearSolver->convergence_check()->set_offset(stdLinOffset + 3);
149
150// perform exactly one Newton step
151 // set c = 0
152 NEWTON_PROFILE_BEGIN(NewtonSetCorretionZero);
153 spC->set(0.0);
155
156 // compute Jacobian
157 try
158 {
159 NEWTON_PROFILE_BEGIN(NewtonComputeJacobian);
160 m_J->init(u);
162 }
163 UG_CATCH_THROW("NewtonLimexSolver::apply: Jacobian initialization failed.");
164
165 // init Jacobian inverse
166 try
167 {
168 NEWTON_PROFILE_BEGIN(NewtonPrepareLinSolver);
169 if (!m_spLinearSolver->init(m_J, u))
170 {
171 UG_LOGN("ERROR in 'NewtonLimexSolver::apply': Cannot init inverse linear "
172 "operator for Jacobi operator.");
173 return false;
174 }
176 }
177 UG_CATCH_THROW("NewtonLimexSolver::apply: Initialization of Linear Solver failed.");
178
179 // solve linearized system
180 try
181 {
182 NEWTON_PROFILE_BEGIN(NewtonApplyLinSolver);
183 if (!m_spLinearSolver->apply(*spC, *spD))
184 {
185 UG_LOGN("ERROR in 'NewtonLimexSolver::apply': Cannot apply inverse linear "
186 "operator for Jacobi operator.");
187 return false;
188 }
190 }
191 UG_CATCH_THROW("NewtonLimexSolver::apply: Application of Linear Solver failed.");
192
193 // store convergence history
194 m_linSolverSteps = m_spLinearSolver->step();
195 m_linSolverRate = m_spLinearSolver->convergence_check()->avg_rate();
196
197 // update solution
198 u -= *spC;
199
200 // apply constraints
201 m_N->prepare(u);
202
203 // reset offset of output for linear solver to previous value
204 m_spLinearSolver->convergence_check()->set_offset(stdLinOffset);
205
206 return true;
207}
208
209
210template <typename TAlgebra>
212{
213 return m_linSolverRate;
214}
215
216template <typename TAlgebra>
218{
219 return m_linSolverSteps;
220}
221
222template <typename TAlgebra>
224{
225 std::stringstream ss;
226 ss << "NewtonLimexSolver\n";
227
228 ss << " LinearSolver: ";
229 if (m_spLinearSolver.valid()) ss << ConfigShift(m_spLinearSolver->config_string()) << "\n";
230 else ss << " NOT SET!\n";
231
232 return ss.str();
233}
234
235
236}
TAlgebra::vector_type vector_type
vector type
Definition newton_limex.h:61
LimexNewtonSolver()
default constructor
Definition newton_limex_impl.h:59
virtual bool prepare(vector_type &u)
prepare operator
Definition newton_limex_impl.h:109
number linear_solver_rate() const
prints average linear solver convergence
Definition newton_limex_impl.h:211
virtual bool init(SmartPtr< IOperator< vector_type > > N)
This operator inverts the operator N: Y -> X.
Definition newton_limex_impl.h:96
virtual std::string config_string() const
Returns information about configuration parameters. This should return necessary information about pa...
Definition newton_limex_impl.h:223
virtual bool apply(vector_type &u)
apply operator, i.e. N^{-1}(0) = u
Definition newton_limex_impl.h:116
int linear_solver_steps() const
information on linear solver convergence
Definition newton_limex_impl.h:217
#define UG_CATCH_THROW(msg)
#define UG_THROW(msg)
#define UG_LOGN(msg)
double number
UG_API std::string ConfigShift(std::string s)
#define NEWTON_PROFILE_END()
Definition newton_limex_impl.h:47
#define NEWTON_PROFILE_BEGIN(name)
Definition newton_limex_impl.h:46
SmartPtr< T, FreePolicy > make_sp(T *inst)
function ProblemDisc new(problemDesc, dom)