public void Multiply(Vector lhs, Vector rhs) { rhs.Clear(); //TODO: perhaps this should be done outside. foreach (var keyFactor in matrixManagers) { int id = keyFactor.Key; IFeti1SubdomainMatrixManager matrixManager = keyFactor.Value; SignedBooleanMatrixColMajor B = lagrangeEnumerator.BooleanMatrices[id]; Vector FBx = matrixManager.MultiplyInverseKffTimes(B.Multiply(lhs, true)); Vector BFBx = B.Multiply(FBx, false); rhs.AddIntoThis(BFBx); } }
//TODO: This can be moved to a base class. Only the S matrix is different for these preconditioners. // Other ones might be different though. public void SolveLinearSystem(Vector rhs, Vector lhs) { lhs.Clear(); //TODO: this should be avoided foreach (int s in subdomainIDs) { IFetiSubdomainMatrixManager matrixManager = matrixManagers[s]; IMappingMatrix Bpb = preconditioningBoundarySignedBooleanMatrices[s]; // inv(F) * y = Bpb * Kbb * Bpb^T * y Vector temp = Bpb.Multiply(rhs, true); temp = matrixManager.MultiplyKbbTimes(temp); Vector subdomainContribution = Bpb.Multiply(temp); lhs.AddIntoThis(subdomainContribution); } }
public void MultiplyFIrr(Vector lhs, Vector rhs) { Preconditions.CheckMultiplicationDimensions(Order, lhs.Length); Preconditions.CheckSystemSolutionDimensions(Order, rhs.Length); // FIrr[s] * x = sum_over_s( Br[s] * (inv(Krr[s]) * (Br[s]^T * x)) ) rhs.Clear(); foreach (int s in Br.Keys) { IFetiDPSubdomainMatrixManager matrices = matrixManagers[s]; Vector temp = Br[s].Multiply(lhs, true); temp = matrices.MultiplyInverseKrrTimes(temp); temp = Br[s].Multiply(temp); rhs.AddIntoThis(temp); } }
public (Vector lagrangeMultipliers, Vector cornerDisplacements) SolveInterfaceProblem(FetiDPFlexibilityMatrix flexibility, IFetiPreconditioner preconditioner, IFetiDPCoarseProblemSolver coarseProblemSolver, Vector globalFcStar, Vector dr, double globalForcesNorm, SolverLogger logger) { int systemOrder = flexibility.Order; // Matrix, preconditioner & rhs var pcgMatrix = new InterfaceProblemMatrix(flexibility, coarseProblemSolver); var pcgPreconditioner = new InterfaceProblemPreconditioner(preconditioner); Vector pcgRhs = CreateInterfaceProblemRhs(flexibility, coarseProblemSolver, globalFcStar, dr); // Solve the interface problem using PCG algorithm var pcgBuilder = new PcgAlgorithm.Builder(); pcgBuilder.MaxIterationsProvider = maxIterationsProvider; pcgBuilder.ResidualTolerance = pcgConvergenceTolerance; pcgBuilder.Convergence = pcgConvergenceStrategyFactory.CreateConvergenceStrategy(globalForcesNorm); PcgAlgorithm pcg = pcgBuilder.Build(); //TODO: perhaps use the pcg from the previous analysis if it has reorthogonalization. var lagranges = Vector.CreateZero(systemOrder); IterativeStatistics stats = pcg.Solve(pcgMatrix, pcgPreconditioner, pcgRhs, lagranges, true, () => Vector.CreateZero(systemOrder)); // Log statistics about PCG execution if (!stats.HasConverged) { throw new IterativeSolverNotConvergedException(FetiDPSolver.name + " did not converge to a solution. PCG" + $" algorithm run for {stats.NumIterationsRequired} iterations and the residual norm ratio was" + $" {stats.ResidualNormRatioEstimation}"); } logger.LogIterativeAlgorithm(stats.NumIterationsRequired, stats.ResidualNormRatioEstimation); // Calculate corner displacements: uc = inv(KccStar) * (fcStar + FIrc^T * lagranges) Vector uc = flexibility.MultiplyTransposedFIrc(lagranges); uc.AddIntoThis(globalFcStar); uc = coarseProblemSolver.MultiplyInverseCoarseProblemMatrixTimes(uc); return(lagranges, uc); }
private double[,] CalculateBendingDeformationMatrix(double[] surfaceBasisVector3, ShapeTSplines2DFromBezierExtraction tsplines, int j, double[] surfaceBasisVector2, double[] surfaceBasisVectorDerivative1, double[] surfaceBasisVector1, double J1, double[] surfaceBasisVectorDerivative2, double[] surfaceBasisVectorDerivative12, ControlPoint[] elementControlPoints) { var Bbending = new double[3, elementControlPoints.Length * 3]; var s1 = Vector.CreateFromArray(surfaceBasisVector1); var s2 = Vector.CreateFromArray(surfaceBasisVector2); var s3 = Vector.CreateFromArray(surfaceBasisVector3); var s11 = Vector.CreateFromArray(surfaceBasisVectorDerivative1); var s22 = Vector.CreateFromArray(surfaceBasisVectorDerivative2); var s12 = Vector.CreateFromArray(surfaceBasisVectorDerivative12); for (int column = 0; column < elementControlPoints.Length * 3; column += 3) { #region BI1 var BI1 = s3.CrossProduct(s3); BI1.ScaleIntoThis(tsplines.TSplineDerivativeValuesHeta[column / 3, j]); var auxVector = s2.CrossProduct(s3); auxVector.ScaleIntoThis(tsplines.TSplineDerivativeValuesKsi[column / 3, j]); BI1.AddIntoThis(auxVector); BI1.ScaleIntoThis(s3.DotProduct(s11)); auxVector = s1.CrossProduct(s11); auxVector.ScaleIntoThis(tsplines.TSplineDerivativeValuesHeta[column / 3, j]); BI1.AddIntoThis(auxVector); BI1.ScaleIntoThis(1 / J1); auxVector[0] = surfaceBasisVector3[0]; auxVector[1] = surfaceBasisVector3[1]; auxVector[2] = surfaceBasisVector3[2]; auxVector.ScaleIntoThis(-tsplines.TSplineSecondDerivativesValueKsi[column / 3, j]); BI1.AddIntoThis(auxVector); #endregion BI1 #region BI2 IVector BI2 = s3.CrossProduct(s3); BI2.ScaleIntoThis(tsplines.TSplineDerivativeValuesHeta[column / 3, j]); auxVector = s2.CrossProduct(s3); auxVector.ScaleIntoThis(tsplines.TSplineDerivativeValuesKsi[column / 3, j]); BI2.AddIntoThis(auxVector); BI2.ScaleIntoThis(s3.DotProduct(s22)); auxVector = s1.CrossProduct(s22); auxVector.ScaleIntoThis(tsplines.TSplineDerivativeValuesHeta[column / 3, j]); BI2.AddIntoThis(auxVector); auxVector = s22.CrossProduct(s2); auxVector.ScaleIntoThis(tsplines.TSplineDerivativeValuesKsi[column / 3, j]); BI2.AddIntoThis(auxVector); BI2.ScaleIntoThis(1 / J1); auxVector[0] = surfaceBasisVector3[0]; auxVector[1] = surfaceBasisVector3[1]; auxVector[2] = surfaceBasisVector3[2]; auxVector.ScaleIntoThis(-tsplines.TSplineSecondDerivativesValueHeta[column / 3, j]); BI2.AddIntoThis(auxVector); #endregion BI2 #region BI3 Vector BI3 = s3.CrossProduct(s3); BI3.ScaleIntoThis(tsplines.TSplineDerivativeValuesHeta[column / 3, j]); auxVector = s2.CrossProduct(s3); auxVector.ScaleIntoThis(tsplines.TSplineDerivativeValuesKsi[column / 3, j]); BI3.AddIntoThis(auxVector); BI3.ScaleIntoThis(s3.DotProduct(s12)); auxVector = s1.CrossProduct(s12); auxVector.ScaleIntoThis(tsplines.TSplineDerivativeValuesHeta[column / 3, j]); BI3.AddIntoThis(auxVector); auxVector = s22.CrossProduct(s2); auxVector.ScaleIntoThis(tsplines.TSplineDerivativeValuesKsi[column / 3, j]); BI3.AddIntoThis(auxVector); BI3.ScaleIntoThis(1 / J1); auxVector[0] = surfaceBasisVector3[0]; auxVector[1] = surfaceBasisVector3[1]; auxVector[2] = surfaceBasisVector3[2]; auxVector.ScaleIntoThis(-tsplines.TSplineSecondDerivativesValueKsiHeta[column / 3, j]); BI3.AddIntoThis(auxVector); #endregion BI3 Bbending[0, column] = BI1[0]; Bbending[0, column + 1] = BI1[1]; Bbending[0, column + 2] = BI1[2]; Bbending[1, column] = BI2[0]; Bbending[1, column + 1] = BI2[1]; Bbending[1, column + 2] = BI2[2]; Bbending[2, column] = 2 * BI3[0]; Bbending[2, column + 1] = 2 * BI3[1]; Bbending[2, column + 2] = 2 * BI3[2]; } return(Bbending); }
private Matrix CalculateBendingDeformationMatrix(Vector surfaceBasisVector3, Nurbs2D nurbs, int j, Vector surfaceBasisVector2, Vector surfaceBasisVectorDerivative1, Vector surfaceBasisVector1, double J1, Vector surfaceBasisVectorDerivative2, Vector surfaceBasisVectorDerivative12, NurbsKirchhoffLoveShellElement element) { var elementControlPoints = element.ControlPoints.ToArray(); Matrix Bbending = Matrix.CreateZero(3, elementControlPoints.Length * 3); for (int column = 0; column < elementControlPoints.Length * 3; column += 3) { #region BI1 var BI1 = surfaceBasisVector3.CrossProduct(surfaceBasisVector3); BI1.ScaleIntoThis(nurbs.NurbsDerivativeValuesHeta[column / 3, j]); var auxVector = surfaceBasisVector2.CrossProduct(surfaceBasisVector3); auxVector.ScaleIntoThis(nurbs.NurbsDerivativeValuesKsi[column / 3, j]); BI1.AddIntoThis(auxVector); BI1.ScaleIntoThis(surfaceBasisVector3.DotProduct(surfaceBasisVectorDerivative1)); auxVector = surfaceBasisVector1.CrossProduct(surfaceBasisVectorDerivative1); auxVector.ScaleIntoThis(nurbs.NurbsDerivativeValuesHeta[column / 3, j]); BI1.AddIntoThis(auxVector); BI1.ScaleIntoThis(1 / J1); auxVector[0] = surfaceBasisVector3[0]; auxVector[1] = surfaceBasisVector3[1]; auxVector[2] = surfaceBasisVector3[2]; auxVector.ScaleIntoThis(-nurbs.NurbsSecondDerivativeValueKsi[column / 3, j]); BI1.AddIntoThis(auxVector); #endregion BI1 #region BI2 Vector BI2 = surfaceBasisVector3.CrossProduct(surfaceBasisVector3); BI2.ScaleIntoThis(nurbs.NurbsDerivativeValuesHeta[column / 3, j]); auxVector = surfaceBasisVector2.CrossProduct(surfaceBasisVector3); auxVector.ScaleIntoThis(nurbs.NurbsDerivativeValuesKsi[column / 3, j]); BI2.AddIntoThis(auxVector); BI2.ScaleIntoThis(surfaceBasisVector3.DotProduct(surfaceBasisVectorDerivative2)); auxVector = surfaceBasisVector1.CrossProduct(surfaceBasisVectorDerivative2); auxVector.ScaleIntoThis(nurbs.NurbsDerivativeValuesHeta[column / 3, j]); BI2.AddIntoThis(auxVector); auxVector = surfaceBasisVectorDerivative2.CrossProduct(surfaceBasisVector2); auxVector.ScaleIntoThis(nurbs.NurbsDerivativeValuesKsi[column / 3, j]); BI2.AddIntoThis(auxVector); BI2.ScaleIntoThis(1 / J1); auxVector[0] = surfaceBasisVector3[0]; auxVector[1] = surfaceBasisVector3[1]; auxVector[2] = surfaceBasisVector3[2]; auxVector.ScaleIntoThis(-nurbs.NurbsSecondDerivativeValueHeta[column / 3, j]); BI2.AddIntoThis(auxVector); #endregion BI2 #region BI3 Vector BI3 = surfaceBasisVector3.CrossProduct(surfaceBasisVector3); BI3.ScaleIntoThis(nurbs.NurbsDerivativeValuesHeta[column / 3, j]); auxVector = surfaceBasisVector2.CrossProduct(surfaceBasisVector3); auxVector.ScaleIntoThis(nurbs.NurbsDerivativeValuesKsi[column / 3, j]); BI3.AddIntoThis(auxVector); BI3.ScaleIntoThis(surfaceBasisVector3.DotProduct(surfaceBasisVectorDerivative12)); auxVector = surfaceBasisVector1.CrossProduct(surfaceBasisVectorDerivative12); auxVector.ScaleIntoThis(nurbs.NurbsDerivativeValuesHeta[column / 3, j]); BI3.AddIntoThis(auxVector); auxVector = surfaceBasisVectorDerivative2.CrossProduct(surfaceBasisVector2); auxVector.ScaleIntoThis(nurbs.NurbsDerivativeValuesKsi[column / 3, j]); BI3.AddIntoThis(auxVector); BI3.ScaleIntoThis(1 / J1); auxVector[0] = surfaceBasisVector3[0]; auxVector[1] = surfaceBasisVector3[1]; auxVector[2] = surfaceBasisVector3[2]; auxVector.ScaleIntoThis(-nurbs.NurbsSecondDerivativeValueKsiHeta[column / 3, j]); BI3.AddIntoThis(auxVector); #endregion BI3 Bbending[0, column] = BI1[0]; Bbending[0, column + 1] = BI1[1]; Bbending[0, column + 2] = BI1[2]; Bbending[1, column] = BI2[0]; Bbending[1, column + 1] = BI2[1]; Bbending[1, column + 2] = BI2[2]; Bbending[2, column] = 2 * BI3[0]; Bbending[2, column + 1] = 2 * BI3[1]; Bbending[2, column + 2] = 2 * BI3[2]; } return(Bbending); }