Real RndSmoothCircleIC::computeCircleValue(const Point & p, const Point & center, const Real & radius) { Point l_center = center; Point l_p = p; if (!_3D_spheres) //Create 3D cylinders instead of spheres { l_p(2) = 0.0; l_center(2) = 0.0; } //Compute the distance between the current point and the center Real dist = _mesh.minPeriodicDistance(_var.number(), l_p, l_center); //Return value Real value = 0.0; if (dist <= radius - _int_width / 2.0) //Random value inside circle value = _invalue - _variation_invalue + 2.0 * _random.rand(_tid) * _variation_invalue; else if (dist < radius + _int_width / 2.0) //Smooth interface { Real int_pos = (dist - radius + _int_width/2.0) / _int_width; value = _outvalue + (_invalue - _outvalue) * (1.0 + std::cos(int_pos * libMesh::pi)) / 2.0; } else //Random value outside circle value = _outvalue - _variation_outvalue + 2.0 * _random.rand(_tid) * _variation_outvalue; return value; }
Point SmoothCircleBaseIC::computeCircleGradient(const Point & p, const Point & center, const Real & radius) { Point l_center = center; Point l_p = p; if (!_3D_spheres) //Create 3D cylinders instead of spheres { l_p(2) = 0.0; l_center(2) = 0.0; } //Compute the distance between the current point and the center Real dist = _mesh.minPeriodicDistance(_var.number(), l_p, l_center); Real DvalueDr = 0.0; if (dist < radius + _int_width/2.0 && dist > radius - _int_width/2.0) { Real int_pos = (dist - radius + _int_width / 2.0) / _int_width; Real Dint_posDr = 1.0 / _int_width; DvalueDr = Dint_posDr * (_invalue - _outvalue) * (-std::sin(int_pos * libMesh::pi) * libMesh::pi) / 2.0; } //Set gradient over the smooth interface if (dist != 0.0) return _mesh.minPeriodicVector(_var.number(), center, p) * (DvalueDr / dist); else return Gradient(0.0, 0.0, 0.0); }
RealGradient SmoothCircleBaseIC::computeCircleGradient(const Point & p, const Point & center, const Real & radius) { Point l_center = center; Point l_p = p; if (!_3D_spheres) // Create 3D cylinders instead of spheres { l_p(2) = 0.0; l_center(2) = 0.0; } // Compute the distance between the current point and the center Real dist = _mesh.minPeriodicDistance(_var.number(), l_p, l_center); // early return if we are probing the center of the circle if (dist == 0.0) return 0.0; Real DvalueDr = 0.0; switch (_profile) { case ProfileType::COS: if (dist < radius + _int_width / 2.0 && dist > radius - _int_width / 2.0) { const Real int_pos = (dist - radius + _int_width / 2.0) / _int_width; const Real Dint_posDr = 1.0 / _int_width; DvalueDr = Dint_posDr * (_invalue - _outvalue) * (-std::sin(int_pos * libMesh::pi) * libMesh::pi) / 2.0; } break; case ProfileType::TANH: DvalueDr = -(_invalue - _outvalue) * 0.5 / _int_width * libMesh::pi * (1.0 - Utility::pow<2>(std::tanh(4.0 * (radius - dist) / _int_width))); break; default: mooseError("Internal error."); } return _mesh.minPeriodicVector(_var.number(), center, p) * (DvalueDr / dist); }
Real SmoothCircleBaseIC::computeCircleValue(const Point & p, const Point & center, const Real & radius) { Point l_center = center; Point l_p = p; if (!_3D_spheres) // Create 3D cylinders instead of spheres { l_p(2) = 0.0; l_center(2) = 0.0; } // Compute the distance between the current point and the center Real dist = _mesh.minPeriodicDistance(_var.number(), l_p, l_center); switch (_profile) { case ProfileType::COS: { // Return value Real value = _outvalue; // Outside circle if (dist <= radius - _int_width / 2.0) // Inside circle value = _invalue; else if (dist < radius + _int_width / 2.0) // Smooth interface { Real int_pos = (dist - radius + _int_width / 2.0) / _int_width; value = _outvalue + (_invalue - _outvalue) * (1.0 + std::cos(int_pos * libMesh::pi)) / 2.0; } return value; } case ProfileType::TANH: return (_invalue - _outvalue) * 0.5 * (std::tanh(libMesh::pi * (radius - dist) / _int_width) + 1.0) + _outvalue; default: mooseError("Internal error."); } }