#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; const double nu = 0.3; const double E = 1; 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: int mode; BoundaryFunction() : Function(2) {} virtual void vector_value(const Point &p, Vector &values) const; }; template void BoundaryFunction::vector_value(const Point &point, Vector &values) const { const double G = E/(2*(1+nu)); const double k = 3 - 4*nu; double x = point[0]; double y = point[1]; double r = sqrt(pow(x,2) + pow(y,2)); double theta = calculate_theta(x,y); double lambda, Q; if (mode == 1) { lambda = 0.5444837367825; Q = 0.5430755788367; values(0) = 1/(2*G)*pow(r,lambda)*((k - Q*(lambda+1))*cos(lambda*theta)-lambda*cos((lambda-2)*theta)); values(1) = 1/(2*G)*pow(r,lambda)*((k + Q*(lambda+1))*sin(lambda*theta)+lambda*sin((lambda-2)*theta)); } else { lambda = 0.9085291898461; Q = -0.2189232362488; values(0) = 1/(2*G)*pow(r,lambda)*((k - Q*(lambda+1))*cos(lambda*theta)-lambda*cos((lambda-2)*theta)); values(1) = -1/(2*G)*pow(r,lambda)*((k + Q*(lambda+1))*sin(lambda*theta)+lambda*sin((lambda-2)*theta)); } } template class ExactSolution : public Function { public: int mode; ExactSolution() : Function(2) {}; virtual void vector_value(const Point &p, Vector &values) const; virtual void vector_gradient(const Point &p, std::vector > &gradients) const; }; template void ExactSolution::vector_value(const Point &point, Vector &values) const { const double G = E/(2*(1+nu)); const double k = 3 - 4*nu; double x = point[0]; double y = point[1]; double r = sqrt(pow(x,2) + pow(y,2)); double theta = calculate_theta(x,y); double lambda, Q; if (mode == 1) { lambda = 0.5444837367825; Q = 0.5430755788367; values(0) = 1/(2*G)*pow(r,lambda)*((k - Q*(lambda+1))*cos(lambda*theta)-lambda*cos((lambda-2)*theta)); values(1) = 1/(2*G)*pow(r,lambda)*((k + Q*(lambda+1))*sin(lambda*theta)+lambda*sin((lambda-2)*theta)); } else { lambda = 0.9085291898461; Q = -0.2189232362488; values(0) = 1/(2*G)*pow(r,lambda)*((k - Q*(lambda+1))*cos(lambda*theta)-lambda*cos((lambda-2)*theta)); values(1) = -1/(2*G)*pow(r,lambda)*((k + Q*(lambda+1))*sin(lambda*theta)+lambda*sin((lambda-2)*theta)); } }; template void ExactSolution::vector_gradient(const Point &point, std::vector > & gradients) const { gradients[0][0] = 0; gradients[0][1] = 0; gradients[1][0] = 0; gradients[1][1] = 0; } #endif