/// <summary> /// Calculate the tensors to implement the added damping model (Banks et.al. 2017) /// </summary> /// <param name="particle"></param> /// <param name="levelSetTracker"></param> /// <param name="fluidViscosity"></param> /// <param name="fluidDensity"></param> /// <param name="dt"></param> internal override void CalculateDampingTensor(Particle particle, LevelSetTracker levelSetTracker, double fluidViscosity, double fluidDensity, double dt) { AddedDamping = new ParticleAddedDamping(); Aux = new FSI_Auxillary(); AddedDampingTensor = AddedDamping.IntegrationOverLevelSet(particle, levelSetTracker, fluidViscosity, fluidDensity, dt, GetPosition(0)); Aux.TestArithmeticException(AddedDampingTensor, "particle added damping tensor"); }
/// <summary> /// Constructor for an arbitrary particle to be implemented in the Particle_Shape classes. /// </summary> /// <param name="motionInit"> /// Initializes the motion parameters of the particle (which model to use, whether it is a dry simulation etc.) /// </param> /// <param name="startPos"> /// The initial position. /// </param> /// <param name="startAngl"> /// The inital anlge. /// </param> /// <param name="activeStress"> /// The active stress excerted on the fluid by the particle. Zero for passive particles. /// </param> /// <param name="startTransVelocity"> /// The inital translational velocity. /// </param> /// <param name="startRotVelocity"> /// The inital rotational velocity. /// </param> public Particle(ParticleMotionInit motionInit, double[] startPos, double startAngl = 0.0, double activeStress = 0, double[] startTransVelocity = null, double startRotVelocity = 0) { SpatialDim = startPos.Length; ActiveStress = activeStress; m_MotionInit = motionInit; Aux = new FSI_Auxillary(); m_MotionInit.CheckInput(); Motion = m_MotionInit.ParticleMotion; Motion.InitializeParticlePositionAndAngle(startPos, startAngl); Motion.InitializeParticleVelocity(startTransVelocity, startRotVelocity); particleDensity = Motion.Density; }
/// <summary> /// Calculates the radial vector (SurfacePoint-ParticleReadOnlyPosition) /// </summary> /// <param name="SurfacePoint"> /// </param> /// <param name="RadialVector"> /// </param> /// <param name="RadialLength"> /// </param> internal void CalculateRadialVector(Vector SurfacePoint, out Vector RadialVector, out double RadialLength) { Aux = new FSI_Auxillary(); RadialVector = new Vector(SurfacePoint[0] - Motion.GetPosition(0)[0], SurfacePoint[1] - Motion.GetPosition(0)[1]); if (RadialVector.L2Norm() == 0) { throw new ArithmeticException("The radial vector has no length"); } RadialLength = RadialVector.Abs(); RadialVector.ScaleV(1 / RadialLength); Aux.TestArithmeticException(RadialVector, "particle radial vector"); Aux.TestArithmeticException(RadialLength, "particle radial length"); }
/// <summary> /// Used during init of the particle. Sets the position and the angle. /// </summary> /// <param name="initialPosition"> /// The initial position. /// </param> /// <param name="initialAngle"> /// The initial angle. /// </param> internal void InitializeParticlePositionAndAngle(double[] initialPosition, double initialAngle, int historyLength = 0) { if (historyLength == 0) { historyLength = NumberOfHistoryEntries; } Aux = new FSI_Auxillary(); for (int i = 0; i < historyLength; i++) { Position[i] = new Vector(initialPosition); Angle[i] = initialAngle * 2 * Math.PI / 360; Aux.TestArithmeticException(Position[i], "initial particle position"); Aux.TestArithmeticException(Angle[i], "initial particle angle"); } }
/// <summary> /// Returns the support point of the particle in the direction specified by a vector. /// </summary> /// <param name="vector"> /// A vector. /// </param> override public Vector GetSupportPoint(Vector supportVector, int SubParticleID) { Aux = new FSI_Auxillary(); Aux.TestArithmeticException(supportVector, "vector in calc of support point"); if (supportVector.L2Norm() == 0) { throw new ArithmeticException("The given vector has no length"); } Vector SupportPoint = new Vector(SpatialDim); double angle = Motion.GetAngle(0); Vector position = new Vector(Motion.GetPosition(0)); double[,] rotMatrix = new double[2, 2]; rotMatrix[0, 0] = m_Length * Math.Cos(angle); rotMatrix[0, 1] = -m_Thickness *Math.Sin(angle); rotMatrix[1, 0] = m_Length * Math.Sin(angle); rotMatrix[1, 1] = m_Thickness * Math.Cos(angle); double[,] transposeRotMatrix = rotMatrix.CloneAs(); transposeRotMatrix[0, 1] = rotMatrix[1, 0]; transposeRotMatrix[1, 0] = rotMatrix[0, 1]; double[] rotVector = new double[2]; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { rotVector[i] += transposeRotMatrix[i, j] * supportVector[j]; } } rotVector.ScaleV(1 / rotVector.L2Norm()); for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { SupportPoint[i] += rotMatrix[i, j] * rotVector[j]; } SupportPoint[i] += position[i]; } return(SupportPoint); }