00001 #ifndef SOLVER_HPP
00002 #define SOLVER_HPP
00003
00004 #include "operator.hpp"
00005
00018
00019
00026 class SourceFunction {
00027 protected:
00028 unsigned N, M;
00029 unsigned m1, m2;
00030 double h, tau;
00031 public:
00033
00036 SourceFunction(unsigned _N, double _H, unsigned _M, double _T,
00037 unsigned _m1, unsigned _m2);
00039 virtual ~SourceFunction() { }
00041 virtual double operator()(unsigned xi, unsigned ti) const = 0;
00043 virtual double SquareNorm() const = 0;
00045 virtual void Update(double *q, double alpha, double dzeta) = 0;
00047 unsigned GetN() const { return N; }
00049 unsigned GetM() const { return M; }
00051 unsigned Get_m1() const { return m1; }
00053 unsigned Get_m2() const { return m2; }
00055 double Get_tau() const { return tau; }
00056 };
00057
00059
00060 class SourceFunctionGeneral : public SourceFunction {
00061 double *v;
00062 public:
00064
00075 SourceFunctionGeneral(unsigned _N, double _H, unsigned _M, double _T,
00076 unsigned _m1, unsigned _m2, double *_v);
00078 ~SourceFunctionGeneral();
00079 double operator()(unsigned xi, unsigned ti) const;
00080 double SquareNorm() const;
00082
00083 void Update(double *q, double alpha, double dzeta);
00084 };
00085
00087
00090 class SourceFunctionFixTime : public SourceFunction {
00091 double *vx;
00092 double *vt;
00093 double *vt_scale;
00094 double square_norm_vt;
00095 public:
00097
00110 SourceFunctionFixTime(unsigned _N, double _H, unsigned _M, double _T,
00111 unsigned _m1, unsigned _m2, double *_vt, double *_vx);
00113 ~SourceFunctionFixTime();
00114 double operator()(unsigned xi, unsigned ti) const;
00115 double SquareNorm() const;
00117
00122 void Update(double *q, double alpha, double dzeta);
00123 };
00124
00125
00128
00135 class StopCriteria {
00136 public:
00138 enum stop_type {
00140 stop_max_iters,
00142 stop_max_iters_calc_func,
00144 stop_func
00145 };
00147
00150 StopCriteria(unsigned max_iter, bool calc_func = false);
00152
00154 StopCriteria(double tol);
00156 void Reset();
00158 stop_type GetType() const;
00160 bool IsStop() const;
00162 void UpdateCurIter() { cur_iter++; }
00164 unsigned GetCurIter() const { return cur_iter; }
00166 bool NeedCalcFunc() const;
00168
00178 void CalcFunc(unsigned N, double h, const double *qT,
00179 double alpha, double square_norm_v);
00181 double GetCurFunc() const { return func_new; }
00182 private:
00183 char type;
00184 unsigned cur_iter;
00185 union un_param {
00186 unsigned max_iter;
00187 double tol;
00188 } param;
00189
00190 double func_old, func_new;
00191 };
00192
00193
00195
00200 class SmoluchowskiSolver {
00201 SmoluchowskiLinearOperator& A;
00202 double *s, *h_obs;
00203
00204 void calc_s();
00205 public:
00208 SmoluchowskiSolver(SmoluchowskiLinearOperator& _A);
00210 ~SmoluchowskiSolver();
00212 const double *Get_s() const;
00214 unsigned GetN() const;
00215
00218 class Callback {
00219 public:
00221 virtual void InverseProblemIter(const StopCriteria& stop_criteria) { }
00222 };
00223
00225
00236 void inverse_problem(SourceFunction& v,
00237 const double *g_obs, double alpha, double dzeta,
00238 StopCriteria& stopcriteria, Callback* callback = 0);
00239
00242 class RightSide {
00243 public:
00246 virtual double operator()(unsigned xi, unsigned ti) const = 0;
00247 };
00248
00250
00262 static void forward_problem(SmoluchowskiOperator& A, double T,
00263 unsigned M, const RightSide& rightside, double *res);
00264
00265
00266
00267
00268
00269
00271
00282 static void adjoint_problem(SmoluchowskiLinearOperator& A,
00283 double T, unsigned M, double *res);
00284 };
00285
00288 class RightSideNoTime : public SmoluchowskiSolver::RightSide {
00289 unsigned N;
00290 const double *arr;
00291 public:
00294
00299 RightSideNoTime(unsigned _N, const double *_arr);
00301 void Set(unsigned _N, const double *_arr);
00302 double operator()(unsigned xi, unsigned ti) const;
00303 };
00304
00306 class RightSideGeneral : public SmoluchowskiSolver::RightSide {
00307 unsigned N, M;
00308 const double *arr;
00309 public:
00311
00317 RightSideGeneral(unsigned _N, unsigned _M, const double *_arr);
00319 void Set(unsigned _N, unsigned _M, const double *_arr);
00320 double operator()(unsigned xi, unsigned ti) const;
00321 };
00322
00325 class RightSideSourceFunction : public SmoluchowskiSolver::RightSide {
00326 const SourceFunction& v;
00327 public:
00329 RightSideSourceFunction(const SourceFunction& _v);
00330 double operator()(unsigned xi, unsigned ti) const;
00331 };
00332
00333 #endif