#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 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 forcing function, boundary values and exact solution ******************************************************************************/ template class ForcingFunction : public Function { public: ForcingFunction() : Function(1) {} virtual double value(const Point & point, const unsigned int component = 0 ) const; }; template double ForcingFunction::value(const Point & point, const unsigned int ) const { return 0; } template class BoundaryFunction : public Function { public: double a, alpha, beta, p1, p2, p3, p4; 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, value, mu; theta = calculate_theta(x,y); if (theta <= M_PI/2) { mu = cos(a*(M_PI/2 - beta))*cos(a*(theta-M_PI/2+alpha)); } else if (theta <= M_PI) { mu = cos(alpha*a)*cos(a*(theta - M_PI + beta)); } else if (theta <= 3*M_PI/2) { mu = cos(beta*a)*cos(a*(theta - M_PI - alpha)); } else { mu = cos(a*(M_PI/2-alpha))*cos(a*(theta-3*M_PI/2-beta)); } value = pow(r,a)*mu; return value; } template class ExactSolution : public Function { public: double a, alpha, beta, p1, p2, p3, p4; 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, u, mu; theta = calculate_theta(x,y); if (theta <= M_PI/2) { mu = cos(a*(M_PI/2 - beta))*cos(a*(theta-M_PI/2+alpha)); } else if (theta <= M_PI) { mu = cos(alpha*a)*cos(a*(theta - M_PI + beta)); } else if (theta <= 3*M_PI/2) { mu = cos(beta*a)*cos(a*(theta-M_PI-alpha)); } else { mu = cos(a*(M_PI/2-alpha))*cos(a*(theta-3*M_PI/2-beta)); } u = pow(r,a)*mu; return u; } template Tensor<1,dim> ExactSolution::gradient (const Point &point, const unsigned int) const { //double x = point[0]; //double y = point[1]; Tensor<1,dim> grad_u; grad_u[0] = 0; grad_u[1] = 0; return grad_u; } #endif