Coverage Report

Created: 2026-03-31 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/quantlib/ql/methods/finitedifferences/operators/firstderivativeop.cpp
Line
Count
Source
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2008 Andreas Gaida
5
 Copyright (C) 2008 Ralph Schreyer
6
 Copyright (C) 2008 Klaus Spanderen
7
8
 This file is part of QuantLib, a free-software/open-source library
9
 for financial quantitative analysts and developers - http://quantlib.org/
10
11
 QuantLib is free software: you can redistribute it and/or modify it
12
 under the terms of the QuantLib license.  You should have received a
13
 copy of the license along with this program; if not, please email
14
 <quantlib-dev@lists.sf.net>. The license is also available online at
15
 <https://www.quantlib.org/license.shtml>.
16
17
 This program is distributed in the hope that it will be useful, but WITHOUT
18
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19
 FOR A PARTICULAR PURPOSE.  See the license for more details.
20
*/
21
22
#include <ql/methods/finitedifferences/meshers/fdmmesher.hpp>
23
#include <ql/methods/finitedifferences/operators/fdmlinearoplayout.hpp>
24
#include <ql/methods/finitedifferences/operators/firstderivativeop.hpp>
25
26
namespace QuantLib {
27
28
    FirstDerivativeOp::FirstDerivativeOp(
29
                                Size direction,
30
                                const ext::shared_ptr<FdmMesher>& mesher)
31
0
    : TripleBandLinearOp(direction, mesher) {
32
33
0
        for (const auto& iter : *mesher->layout()) {
34
0
            const Size i = iter.index();
35
0
            const Real hm = mesher->dminus(iter, direction_);
36
0
            const Real hp = mesher->dplus(iter, direction_);
37
38
0
            const Real zetam1 = hm*(hm+hp);
39
0
            const Real zeta0  = hm*hp;
40
0
            const Real zetap1 = hp*(hm+hp);
41
42
0
            if (iter.coordinates()[direction_] == 0) {
43
                //upwinding scheme
44
0
                lower_[i] = 0.0;
45
0
                diag_[i]  = -(upper_[i] = 1/hp);
46
0
            }
47
0
            else if (   iter.coordinates()[direction_]
48
0
                     == mesher->layout()->dim()[direction]-1) {
49
                 // downwinding scheme
50
0
                lower_[i] = -(diag_[i] = 1/hm);
51
0
                upper_[i] = 0.0;
52
0
            }
53
0
            else {
54
0
                lower_[i] = -hp/zetam1;
55
0
                diag_[i]  = (hp-hm)/zeta0;
56
0
                upper_[i] = hm/zetap1;
57
0
            }
58
0
        }
59
0
    }
60
}
61