PLaSK library
Loading...
Searching...
No Matches
muller.cpp
Go to the documentation of this file.
1
/*
2
* This file is part of PLaSK (https://plask.app) by Photonics Group at TUL
3
* Copyright (c) 2022 Lodz University of Technology
4
*
5
* This program is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, version 3.
8
*
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
13
*/
14
#include "
muller.hpp
"
15
using namespace
std
;
16
17
namespace
plask
{
namespace
optical {
namespace
effective {
18
19
//**************************************************************************
21
dcomplex
RootMuller::find
(dcomplex start)
const
22
{
23
dcomplex first = start - 0.5 *
params
.
initial_dist
;
24
dcomplex second = start + 0.5 *
params
.
initial_dist
;
25
26
writelog(
LOG_DETAIL
,
"Searching for the root with Muller method between {0} and {1}"
,
str
(first),
str
(second));
27
log_value
.
resetCounter
();
28
29
double
xtol2
=
params
.
tolx
*
params
.
tolx
;
30
double
fmin2
=
params
.
tolf_min
*
params
.
tolf_min
;
31
double
fmax2
=
params
.
tolf_max
*
params
.
tolf_max
;
32
33
dcomplex
x2
= first,
x1
= second,
x0
= start;
34
35
dcomplex
f2
=
valFunction
(
x2
);
log_value
(
x2
,
f2
);
36
dcomplex
f1
=
valFunction
(
x1
);
log_value
(
x1
,
f1
);
37
dcomplex
f0
=
valFunction
(
x0
);
log_value
.
count
(
x0
,
f0
);
38
39
for
(
int
i = 0; i <
params
.
maxiter
; ++i) {
40
if
(
isnan
(
real
(
f0
)) ||
isnan
(
imag
(
f0
)))
41
throw
ComputationError
(
solver
.
getId
(),
"computed value is NaN"
);
42
dcomplex
q
= (
x0
-
x1
) / (
x1
-
x2
);
43
dcomplex A =
q
*
f0
-
q
*(
q
+1.) *
f1
+
q
*
q
*
f2
;
44
dcomplex B = (2.*
q
+1.) *
f0
- (
q
+1.)*(
q
+1.) *
f1
+
q
*
q
*
f2
;
45
dcomplex C = (
q
+1.) *
f0
;
46
dcomplex S =
sqrt
(B*B - 4.*A*C);
47
x2
=
x1
;
f2
=
f1
;
48
x1
=
x0
;
f1
=
f0
;
49
x0
=
x1
- (
x1
-
x2
) * ( 2.*C / std::max(B+S, B-S, [](
const
dcomplex&
a
,
const
dcomplex&
b
){
return
abs2
(
a
) <
abs2
(
b
);}) );
50
f0
=
valFunction
(
x0
);
log_value
.
count
(
x0
,
f0
);
51
if
(
abs2
(
f0
) <
fmin2
|| (
abs2
(
x0
-
x1
) <
xtol2
&&
abs2
(
f0
) <
fmax2
)) {
52
writelog(
LOG_RESULT
,
"Found root at "
+
str
(
x0
));
53
return
x0
;
54
}
55
}
56
57
throw
ComputationError
(
solver
.
getId
(),
"Muller: {0}: maximum number of iterations reached"
,
log_value
.
chartName
());
58
}
59
60
}}}
// namespace plask::optical::effective
solvers
optical
effective
muller.cpp
Generated by
1.9.8