public double InnerEdgeForm(ref CommonParams cp, double[] U_Neg, double[] U_Pos, double[,] Grad_uA, double[,] Grad_uB, double v_Neg, double v_Pos, double[] Grad_vA, double[] Grad_vB) { CommonParams inp = cp; // Particle parameters // ============================= FSI_ParameterAtIB coupling = m_getParticleParams(inp.X); Vector orientation = new Vector(Math.Cos(coupling.Angle()), Math.Sin(coupling.Angle())); double scaleActiveBoundary = orientation * new Vector(inp.Normal) > 0 && coupling.ActiveStress() != 0 ? 1 : 0; // Level-set velocity // ============================= double[] uLevSet_temp = new double[1]; if (m_d == 0) { uLevSet_temp[0] = coupling.VelocityAtPointOnLevelSet()[0]; } else { uLevSet_temp[0] = coupling.VelocityAtPointOnLevelSet()[1]; } // Outer values for Velocity and VelocityMean // ============================= inp.Parameters_OUT = new double[inp.Parameters_IN.Length]; inp.Parameters_OUT[0] = coupling.VelocityAtPointOnLevelSet()[0]; inp.Parameters_OUT[1] = coupling.VelocityAtPointOnLevelSet()[1]; // Velocity0MeanVectorOut is set to zero, i.e. always LambdaIn is used. inp.Parameters_OUT[2] = 0; inp.Parameters_OUT[3] = 0; // Computing Flux // ============================= double FlxNeg = m_UseMovingMesh == true ? 0 // Moving mesh : (this.NegFlux.InnerEdgeForm(ref inp, U_Neg, uLevSet_temp, null, null, v_Neg, 0, null, null)) * (1 - scaleActiveBoundary); // Splitting return(FlxNeg); }
/// <summary> /// default-implementation /// </summary> public double InnerEdgeForm(ref CommonParams inp, double[] uA, double[] uB, double[,] Grad_uA, double[,] Grad_uB, double vA, double vB, double[] Grad_vA, double[] Grad_vB) { int dim = inp.Normal.Dim; double _penalty = m_PenaltyFunc(m_penalty, inp.jCellIn); // Particle parameters // ===================== if (inp.X.IsNullOrEmpty()) { throw new Exception("X is null or empty"); } if (m_GetParticleParams == null) { throw new Exception("m_GetParticleParams is null or empty"); } if (inp.X.Abs() < 0) { throw new ArithmeticException("invalid length of position vector"); } FSI_ParameterAtIB coupling = m_GetParticleParams(inp.X); if (coupling == null) { throw new Exception("coupling is null or empty"); } Vector orientation = new Vector(Math.Cos(coupling.Angle()), Math.Sin(coupling.Angle())); Vector orientationNormal = new Vector(-Math.Sin(coupling.Angle()), Math.Cos(coupling.Angle())); Vector activeStressVector = orientationNormal * inp.Normal > 0 ? new Vector(-coupling.ActiveStress() * inp.Normal[1], coupling.ActiveStress() * inp.Normal[0]) : new Vector(coupling.ActiveStress() * inp.Normal[1], -coupling.ActiveStress() * inp.Normal[0]); BoundaryConditionType bcType = orientation * inp.Normal <= 0 || coupling.ActiveStress() == 0 ? BoundaryConditionType.passive : BoundaryConditionType.active; Debug.Assert(ArgumentOrdering.Count == dim); Debug.Assert(Grad_uA.GetLength(0) == ArgumentOrdering.Count); Debug.Assert(Grad_uB.GetLength(0) == ArgumentOrdering.Count); Debug.Assert(Grad_uA.GetLength(1) == dim); Debug.Assert(Grad_uB.GetLength(1) == dim); // Gradient of u and v // ===================== double Grad_uA_xN = 0, Grad_vA_xN = 0; for (int d = 0; d < dim; d++) { Grad_uA_xN += Grad_uA[component, d] * inp.Normal[d]; Grad_vA_xN += Grad_vA[d] * inp.Normal[d]; } double returnValue = 0.0; // 3D for IBM_Solver // ===================== if (dim == 3) { returnValue -= Grad_uA_xN * (vA); // consistency term returnValue -= Grad_vA_xN * (uA[component] - 0); // symmetry term returnValue += _penalty * (uA[component] - 0) * (vA); // penalty term Debug.Assert(!(double.IsInfinity(returnValue) || double.IsNaN(returnValue))); return(returnValue * muA); } // 2D // ===================== Vector uAFict = coupling.VelocityAtPointOnLevelSet(); switch (bcType) { case BoundaryConditionType.passive: { for (int d = 0; d < dim; d++) { returnValue -= muA * Grad_uA[component, d] * vA * inp.Normal[d]; returnValue -= muA * Grad_vA[d] * (uA[component] - uAFict[component]) * inp.Normal[d]; } returnValue += muA * (uA[component] - uAFict[component]) * vA * _penalty; break; } case BoundaryConditionType.active: { // normal direction, solid wall for (int dN = 0; dN < dim; dN++) { for (int dD = 0; dD < dim; dD++) { // consistency term returnValue -= muA * (inp.Normal[dN] * Grad_uA[dN, dD] * inp.Normal[dD]) * vA * inp.Normal[component]; // symmetry term returnValue -= muA * (Grad_vA[dD] * inp.Normal[dD]) * (inp.Normal[dN] * uA[dN] - inp.Normal[dN] * uAFict[dN]) * inp.Normal[component]; } // penalty term returnValue += muA * inp.Normal[dN] * (uA[dN] - uAFict[dN]) * inp.Normal[component] * vA * _penalty; } // tangential direction, active part double[,] P = new double[dim, dim]; for (int d1 = 0; d1 < dim; d1++) { for (int d2 = 0; d2 < dim; d2++) { if (d1 == d2) { P[d1, d2] = 1 - inp.Normal[d1] * inp.Normal[d2]; } else { P[d1, d2] = inp.Normal[d1] * inp.Normal[d2]; } } } for (int d1 = 0; d1 < dim; d1++) { for (int d2 = 0; d2 < dim; d2++) { returnValue -= P[d1, d2] * activeStressVector[d2] * (P[d1, component] * vA); } } break; } } Debug.Assert(!(double.IsInfinity(returnValue) || double.IsNaN(returnValue))); return(returnValue); }