00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef __STEKLOV_POINCARE_2DBE_H
00037 #define __STEKLOV_POINCARE_2DBE_H
00038
00039 #include "Mesh.h"
00040 #include "DMatrix.h"
00041 #include "Precond.h"
00042 #include "GMRes.h"
00043 #include "Vect.h"
00044 #include "Triang3.h"
00045
00046 namespace OFELI {
00047
00053 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00054 struct ErrorInSteklovPoincare2DBE {
00055 void Message(const char *file, size_t line, int code);
00056 };
00057 #endif
00058
00059
00078 class SteklovPoincare2DBE {
00079
00080 public :
00081
00084 SteklovPoincare2DBE(bool ext=false)
00085 {
00086 _ext = -1;
00087 if (ext)
00088 _ext = 1;
00089 }
00090
00096 SteklovPoincare2DBE(const Mesh &mesh, bool ext=false);
00097
00105 SteklovPoincare2DBE(const Mesh &mesh, const SideVect<double> &g, Vect<double> &b, bool ext=false);
00106
00114 SteklovPoincare2DBE(const Mesh &mesh, const NodeVect<double> &g, Vect<double> &b, bool ext=false);
00115
00123 SteklovPoincare2DBE(const Mesh &mesh, const SideVect<double> &g, SideVect<double> &b, bool ext=false);
00124
00132 SteklovPoincare2DBE(const Mesh &mesh, const SideVect<double> &g, NodeVect<double> &b, bool ext=false);
00133
00135 ~SteklovPoincare2DBE() { }
00136
00140 void setMesh(const Mesh &mesh, bool ext=false);
00141
00144 void Solve();
00145
00152 int Solve(Vect<double> &b, const SideVect<double> &g);
00153
00160 int Solve(Vect<double> &b, const NodeVect<double> &g);
00161
00162 private :
00163 int _ext;
00164 const Mesh *_theMesh;
00165 size_t _nb_eq;
00166 Vect<Point<double> > _nn, _ttg, _center;
00167 Vect<double> _length;
00168 double _h;
00169 DMatrix<double> _A;
00170 ErrorInSteklovPoincare2DBE _e;
00171
00172
00173 inline double _single_layer(size_t j, const Point<double> &z) const
00174 {
00175 double t = z.NNorm();
00176 if (t < OFELI_EPSMCH)
00177 return -0.25/OFELI_PI*_h*_I1(0.5*_h);
00178 else
00179 return -0.125/OFELI_PI*_h*_I2(0.25*_h*_h,z*_ttg(j),t);
00180 }
00181
00182
00183 inline double _double_layer(size_t j, const Point<double> &z) const
00184 {
00185 double t = _nn(j)*z;
00186 if (fabs(t) < OFELI_EPSMCH)
00187 return 0;
00188 else
00189 return -0.25/OFELI_PI*t*_I3(0.25*_h*_h,z*_ttg(j),z.NNorm());
00190 }
00191
00192
00193 inline double _I1(double a) const { return 2*log(a)-2; }
00194
00195
00196 inline double _I2(double a, double b, double c) const
00197 {
00198 double d = sqrt(4*a*c-b*b);
00199 return 0.5*(log(a-b+c)*(2*a-b)+log(a+b+c)*(2*a+b)+2*(atan((2*a+b)/d)+atan((2*a-b)/d))*sqrt(4*a*c-b*b)-8*a)/a;
00200 }
00201
00202
00203 inline double _I3(double a, double b, double c) const
00204 {
00205 double d = sqrt(4*a*c-b*b);
00206 return 2*(atan((2*a-b)/d)+atan((2*a+b)/d))/d;
00207 }
00208
00209
00210 void _util();
00211 };
00212
00213 }
00214
00215 #endif