1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 3 /* 4 Copyright (C) 2012 Peter Caspers 5 6 This file is part of QuantLib, a free-software/open-source library 7 for financial quantitative analysts and developers - http://quantlib.org/ 8 9 QuantLib is free software: you can redistribute it and/or modify it 10 under the terms of the QuantLib license. You should have received a 11 copy of the license along with this program; if not, please email 12 <quantlib-dev@lists.sf.net>. The license is also available online at 13 <http://quantlib.org/license.shtml>. 14 15 This program is distributed in the hope that it will be useful, but WITHOUT 16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 17 FOR A PARTICULAR PURPOSE. See the license for more details. 18 */ 19 20 21 /*! \file fdmtimedepdirichletboundary.cpp 22 */ 23 24 #include <ql/methods/finitedifferences/meshers/fdmmesher.hpp> 25 #include <ql/methods/finitedifferences/operators/fdmlinearop.hpp> 26 #include <ql/methods/finitedifferences/utilities/fdmindicesonboundary.hpp> 27 #include <ql/methods/finitedifferences/utilities/fdmtimedepdirichletboundary.hpp> 28 29 #include <algorithm> 30 31 namespace QuantLib { 32 FdmTimeDepDirichletBoundary(const ext::shared_ptr<FdmMesher> & mesher,const ext::function<Real (Real)> & valueOnBoundary,Size direction,Side side)33 FdmTimeDepDirichletBoundary::FdmTimeDepDirichletBoundary( 34 const ext::shared_ptr<FdmMesher>& mesher, 35 const ext::function<Real (Real)>& valueOnBoundary, 36 Size direction, Side side) 37 : indices_(FdmIndicesOnBoundary(mesher->layout(), 38 direction, side).getIndices()), 39 valueOnBoundary_(valueOnBoundary), 40 values_(indices_.size()) { 41 } 42 FdmTimeDepDirichletBoundary(const ext::shared_ptr<FdmMesher> & mesher,const ext::function<Disposable<Array> (Real)> & valuesOnBoundary,Size direction,Side side)43 FdmTimeDepDirichletBoundary::FdmTimeDepDirichletBoundary( 44 const ext::shared_ptr<FdmMesher>& mesher, 45 const ext::function<Disposable<Array> (Real)>& valuesOnBoundary, 46 Size direction, Side side) 47 : indices_(FdmIndicesOnBoundary(mesher->layout(), 48 direction, side).getIndices()), 49 valuesOnBoundary_(valuesOnBoundary), 50 values_(indices_.size()) { 51 } 52 setTime(Time t)53 void FdmTimeDepDirichletBoundary::setTime(Time t) { 54 if (valueOnBoundary_ != 0) { 55 std::fill(values_.begin(), values_.end(), valueOnBoundary_(t)); 56 } else if (valuesOnBoundary_ != 0) { 57 values_ = valuesOnBoundary_(t); 58 } 59 else { 60 QL_FAIL("no boundary values defined"); 61 } 62 } 63 applyAfterApplying(array_type & a) const64 void FdmTimeDepDirichletBoundary::applyAfterApplying(array_type& a) const { 65 QL_REQUIRE(indices_.size() == values_.size(), 66 "values on boundary size (" << values_.size() 67 << ") does not match hypersurface size (" 68 << indices_.size() << ")"); 69 for (std::vector<Size>::const_iterator iter = indices_.begin(); 70 iter != indices_.end(); ++iter) { 71 a[*iter] = values_[iter - indices_.begin()]; 72 } 73 } 74 applyAfterSolving(array_type & a) const75 void FdmTimeDepDirichletBoundary::applyAfterSolving(array_type& a) const { 76 this->applyAfterApplying(a); 77 } 78 } 79