protected override void MatrixTimesVectorImpl(double[] a_Source, double[] a_Destination) { for (int i = 0; i < m_TempVector.Length; ++i) { m_TempVector[i] = 0; } m_J.MatrixTransposeTimesVector(a_Source, m_TempVector); //temp = JTa for (int i = 0; i < m_W.Length; ++i) { m_TempVector[i] = m_TempVector[i] * m_W[i]; //temp = WJTa } m_J.MatrixTimesVector(m_TempVector, a_Destination); // a_Destination = JWJTa }
private void SolveEquation11(float a_SpringConstant, float a_DampingConstant) { ParticlesGetVelocities(qdot); ValidateVector(qdot); //double[] M = ParticlesMassMatrix(); //ValidateVector(M); ParticlesInverseMassMatrix(W); ValidateVector(W); ParticlesGetForces(Q); ValidateVector(Q); ConstraintsGetValues(C); ValidateVector(C); //double[] CMass = ConstraintsGetAvgMasses(); //ValidateVector(CMass); ConstraintsGetDerivativeValues(CDot); ValidateVector(CDot); // JDot times qdot. for (int i = 0; i < JDotqdot.Length; ++i) { JDotqdot[i] = 0; } m_JDot.MatrixTimesVector(qdot, JDotqdot); ValidateVector(JDotqdot); // W times Q. for (int i = 0; i < WQ.Length; ++i) { WQ[i] = W[i] * Q[i]; } ValidateVector(WQ); // J times WQ. for (int i = 0; i < JWQ.Length; ++i) { JWQ[i] = 0; } m_J.MatrixTimesVector(WQ, JWQ); ValidateVector(JWQ); // Compute the RHS of equation 11. for (int i = 0; i < RHS.Length; ++i) { RHS[i] = -JDotqdot[i] - JWQ[i] - a_SpringConstant * C[i] - a_DampingConstant * CDot[i]; if (double.IsNaN(RHS[i]) || double.IsNaN(RHS[i])) { throw new System.Exception("NaN or Inf in RHS of eq 11"); } } // Set up implicit matrix of LHS and solve. int stepsPerformed = 0; m_Solver.Solve(LHS, lambda, RHS, out stepsPerformed); ValidateVector(lambda); //Debug.Log("Nr of iterations in conjgrad solver: " + stepsPerformed); for (int i = 0; i < QHat.Length; ++i) { QHat[i] = 0; } m_J.MatrixTransposeTimesVector(lambda, QHat); ValidateVector(QHat); if (QHat.Length != m_Particles.Count << 1) { throw new Exception("QHat does not match particles!"); } for (int i = 0; i < m_Particles.Count; ++i) { m_Particles[i].ForceAccumulator += new Vector2((float)QHat[i * 2], (float)QHat[(i * 2) + 1]); Vector2 newForce = m_Particles[i].ForceAccumulator; if (double.IsNaN(newForce.x) || double.IsNaN(newForce.y) || double.IsInfinity(newForce.x) || double.IsInfinity(newForce.y)) { throw new Exception("NaN or Inf in accumulated force after eq 11"); } } }