#ifndef MYFUNCTIONS_H #define MYFUNCTIONS_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace dealii; inline double calculate_theta(double x, double y) { const double EPSILON = 1e-10; double theta; double phi = atan(fabs(y/x)); if (fabs(x) < EPSILON && fabs(y) < EPSILON) { theta = 0; } else if (fabs(y) < EPSILON && x > 0) { theta = 0; } else if (fabs(x) < EPSILON && y > 0) { theta = M_PI/2; } else if (fabs(y) < EPSILON && x < 0) { theta = M_PI; } else if (fabs(x) < EPSILON && y < 0) { theta = 3*M_PI/2; } else if (x >= 0 && y >= 0) { theta = phi; } else if (y >= 0 && x <= 0) { theta = M_PI - phi; } else if (y < 0 && x < 0) { theta = M_PI + phi; } else { theta = 2*M_PI - phi; } return theta; } /******************************************************************************* * Define boundary values and exact solution ******************************************************************************/ template class BoundaryFunction : public Function { public: double alpha; BoundaryFunction() : Function(1) {} virtual double value(const Point & point, const unsigned int component = 0 ) const; }; template double BoundaryFunction::value(const Point & point, const unsigned int ) const { double x = point[0]; double y = point[1]; double r = sqrt(pow(x,2) + pow(y,2)); double theta = calculate_theta(x,y); double value = pow(r,alpha)*sin(alpha*theta); return value; } template class ExactSolution : public Function { public: double alpha; ExactSolution() : Function(1) {}; virtual double value(const Point & point, const unsigned int component = 0 ) const; virtual Tensor<1,dim> gradient (const Point &point, const unsigned int component = 0) const; }; template double ExactSolution::value(const Point & point, const unsigned int ) const { double x = point[0]; double y = point[1]; double r = sqrt(pow(x,2) + pow(y,2)); double theta = calculate_theta(x,y); double value = pow(r,alpha)*sin(alpha*theta); return value; } template Tensor<1,dim> ExactSolution::gradient (const Point &point, const unsigned int) const { double x = point[0]; double y = point[1]; double r = sqrt(pow(x,2) + pow(y,2)); double theta = calculate_theta(x,y); Tensor<1,dim> grad_u; grad_u[0] = alpha*pow(r,alpha-2)*(x*sin(alpha*theta) - y*cos(alpha*theta)); grad_u[1] = alpha*pow(r,alpha-2)*(y*sin(alpha*theta) + x*cos(alpha*theta)); return grad_u; } #endif