private PcgSolver(IModel model, PcgAlgorithm pcgAlgorithm, IPreconditionerFactory preconditionerFactory, IDofOrderer dofOrderer) : base(model, dofOrderer, new CsrAssembler(true), "PcgSolver") { this.pcgAlgorithm = pcgAlgorithm; this.preconditionerFactory = preconditionerFactory; }
public Factory(Model singleSubdomainModel, IDofOrderer originalDofOrderer, Func <Model, ISolver, IStaticProvider> createProblemProvider) { this.singleSubdomainModel = singleSubdomainModel; this.singleSubdomain = singleSubdomainModel.Subdomains.First(); this.originalDofOrderer = originalDofOrderer; this.createProblemProvider = createProblemProvider; }
public Vector CalculateConstrainedDisplacements(IDofOrderer dofOrderer) { double[] uc = new double[dofOrderer.NumConstrainedDofs]; foreach ((XNode node, StructuralDof dofType, double displacement) in constraints) { int dof = dofOrderer.GetConstrainedDofOf(node, dofType); uc[dof] = displacement; } return(Vector.CreateFromArray(uc)); }
public Vector CalculateFreeForces(IDofOrderer dofOrderer) { double[] rhs = new double[dofOrderer.NumStandardDofs + dofOrderer.NumEnrichedDofs]; foreach ((XNode node, StructuralDof dofType, double load) in loads) { try { int dof = dofOrderer.GetStandardDofOf(node, dofType); rhs[dof] += load; // This supports multiple loads on the same dof, which isn't implemented yet } catch (KeyNotFoundException ex) { throw new NotImplementedException("Load on a constrained dof at node " + node.ID + ", axis " + dofType, ex); } } return(Vector.CreateFromArray(rhs)); }
protected SingleSubdomainRectangularSolverBase(IStructuralAsymmetricModel model, IAsymmetricDofOrderer dofRowOrderer, IDofOrderer dofColOrderer, IGlobalMatrixRectangularAssembler <TMatrix> assembler, string name) { if (model.Subdomains.Count != 1) { throw new InvalidSolverException( $"{name} can be used if there is only 1 subdomain"); } this.model = model; subdomain = model.Subdomains[0]; linearSystem = new SingleSubdomainSystem <TMatrix>(subdomain); LinearSystems = new Dictionary <int, ILinearSystem>() { { subdomain.ID, linearSystem } }; linearSystem.MatrixObservers.Add(this); this.dofRowOrderer = dofRowOrderer; this.dofColOrderer = dofColOrderer; this.assembler = assembler; this.Logger = new SolverLogger(name); }
public void Propagate(IDofOrderer dofOrderer, Vector totalFreeDisplacements, Vector totalConstrainedDisplacements) { throw new NotImplementedException(); }
public StressRecovery(Model2D_old model, IDofOrderer dofOrderer) { this.model = model; this.dofOrderer = dofOrderer; }
public void WriteOutputData(IDofOrderer dofOrderer, Vector freeDisplacements, Vector constrainedDisplacements, int step) { // TODO: guess initial capacities from previous steps or from the model var allPoints = new List <VtkPoint>(); var allCells = new List <VtkCell>(); var displacements = new List <double[]>(); var strains = new List <Tensor2D>(); var stresses = new List <Tensor2D>(); int pointCounter = 0; foreach (XContinuumElement2D element in model.Elements) { Vector standardDisplacements = dofOrderer.ExtractDisplacementVectorOfElementFromGlobal(element, freeDisplacements, constrainedDisplacements); Vector enrichedDisplacements = dofOrderer.ExtractEnrichedDisplacementsOfElementFromGlobal(element, freeDisplacements); bool mustTriangulate = MustBeTriangulated(element, out ISingleCrack intersectingCrack); if (!mustTriangulate) { // Mesh var cellPoints = new VtkPoint[element.Nodes.Count]; for (int p = 0; p < cellPoints.Length; ++p) { cellPoints[p] = new VtkPoint(pointCounter++, element.Nodes[p]); allPoints.Add(cellPoints[p]); } allCells.Add(new VtkCell(element.CellType, cellPoints)); // Displacements for (int p = 0; p < cellPoints.Length; ++p) { displacements.Add(new double[] { standardDisplacements[2 * p], standardDisplacements[2 * p + 1] }); } // Strains and stresses at Gauss points of element // WARNING: do not use the quadrature object, since GPs are sorted differently. IReadOnlyList <GaussPoint> gaussPoints = element.GaussPointExtrapolation.Quadrature.IntegrationPoints; var strainsAtGPs = new Tensor2D[gaussPoints.Count]; var stressesAtGPs = new Tensor2D[gaussPoints.Count]; for (int gp = 0; gp < gaussPoints.Count; ++gp) { EvalInterpolation2D evalInterpol = element.Interpolation.EvaluateAllAt(element.Nodes, gaussPoints[gp]); (Tensor2D strain, Tensor2D stress) = ComputeStrainStress(element, gaussPoints[gp], evalInterpol, standardDisplacements, enrichedDisplacements); strainsAtGPs[gp] = strain; stressesAtGPs[gp] = stress; } // Extrapolate strains and stresses to element nodes. This is exact, since the element is not enriched IReadOnlyList <Tensor2D> strainsAtNodes = element.GaussPointExtrapolation. ExtrapolateTensorFromGaussPointsToNodes(strainsAtGPs, element.Interpolation); IReadOnlyList <Tensor2D> stressesAtNodes = element.GaussPointExtrapolation. ExtrapolateTensorFromGaussPointsToNodes(stressesAtGPs, element.Interpolation); for (int p = 0; p < cellPoints.Length; ++p) { strains.Add(strainsAtNodes[p]); stresses.Add(stressesAtNodes[p]); } } else { // Triangulate and then operate on each triangle SortedSet <CartesianPoint> triangleVertices = intersectingCrack.FindTriangleVertices(element); IReadOnlyList <Triangle2D <CartesianPoint> > triangles = triangulator.CreateMesh(triangleVertices); foreach (Triangle2D <CartesianPoint> triangle in triangles) { // Mesh int numTriangleNodes = 3; var cellPoints = new VtkPoint[numTriangleNodes]; for (int p = 0; p < numTriangleNodes; ++p) { CartesianPoint point = triangle.Vertices[p]; cellPoints[p] = new VtkPoint(pointCounter++, point.X, point.Y, point.Z); allPoints.Add(cellPoints[p]); } allCells.Add(new VtkCell(CellType.Tri3, cellPoints)); // Displacements, strains and stresses are not defined on the crack, thus they must be evaluated at GPs // and extrapolated to each point of interest. However how should I choose the Gauss points? Here I take // the Gauss points of the subtriangles. IGaussPointExtrapolation2D extrapolation = ExtrapolationGaussTriangular3Points.UniqueInstance; IIsoparametricInterpolation2D interpolation = InterpolationTri3.UniqueInstance; // Find the Gauss points of the triangle in the natural system of the element IInverseInterpolation2D inverseMapping = element.Interpolation.CreateInverseMappingFor(element.Nodes); var triangleNodesNatural = new NaturalPoint[numTriangleNodes]; for (int p = 0; p < numTriangleNodes; ++p) { triangleNodesNatural[p] = inverseMapping.TransformPointCartesianToNatural(cellPoints[p]); } NaturalPoint[] triangleGPsNatural = FindTriangleGPsNatural(triangleNodesNatural, extrapolation.Quadrature.IntegrationPoints); // Find the field values at the Gauss points of the triangle (their coordinates are in the natural // system of the element) var displacementsAtGPs = new double[triangleGPsNatural.Length][]; var strainsAtGPs = new Tensor2D[triangleGPsNatural.Length]; var stressesAtGPs = new Tensor2D[triangleGPsNatural.Length]; for (int gp = 0; gp < triangleGPsNatural.Length; ++gp) { EvalInterpolation2D evalInterpol = element.Interpolation.EvaluateAllAt(element.Nodes, triangleGPsNatural[gp]); displacementsAtGPs[gp] = element.CalculateDisplacementField(triangleGPsNatural[gp], evalInterpol, standardDisplacements, enrichedDisplacements).CopyToArray(); (Tensor2D strain, Tensor2D stress) = ComputeStrainStress(element, triangleGPsNatural[gp], evalInterpol, standardDisplacements, enrichedDisplacements); strainsAtGPs[gp] = strain; stressesAtGPs[gp] = stress; } // Extrapolate the field values to the triangle nodes. We need their coordinates in the auxiliary // system of the triangle. We could use the inverse interpolation of the triangle to map the natural // (element local) coordinates of the nodes to the auxiliary system of the triangle. Fortunately they // can be accessed by the extrapolation object directly. IReadOnlyList <double[]> displacementsAtTriangleNodes = extrapolation.ExtrapolateVectorFromGaussPointsToNodes(displacementsAtGPs, interpolation); IReadOnlyList <Tensor2D> strainsAtTriangleNodes = extrapolation.ExtrapolateTensorFromGaussPointsToNodes(strainsAtGPs, interpolation); IReadOnlyList <Tensor2D> stressesAtTriangleNodes = extrapolation.ExtrapolateTensorFromGaussPointsToNodes(stressesAtGPs, interpolation); for (int p = 0; p < numTriangleNodes; ++p) { displacements.Add(displacementsAtTriangleNodes[p]); strains.Add(strainsAtTriangleNodes[p]); stresses.Add(stressesAtTriangleNodes[p]); } } } } using (var writer = new VtkFileWriter($"{pathNoExtension}_{step}.vtk")) { writer.WriteMesh(allPoints, allCells); writer.WriteVector2DField("displacement", displacements); writer.WriteTensor2DField("strain", strains); writer.WriteTensor2DField("stress", stresses); } }
public DisplacementOutput(Model2D_old model, IDofOrderer dofOrderer) { this.model = model; this.dofOrderer = dofOrderer; }
private SuiteSparseSolver(IModel model, double factorizationPivotTolerance, IDofOrderer dofOrderer) : base(model, dofOrderer, new SymmetricCscAssembler(), "SkylineSolver") { this.factorizationPivotTolerance = factorizationPivotTolerance; }
private SkylineSolver(IStructuralModel model, double factorizationPivotTolerance, IDofOrderer dofOrderer) : base(model, dofOrderer, new SkylineAssembler(), "SkylineSolver") { this.factorizationPivotTolerance = factorizationPivotTolerance; }
public TensorOutput(Model2D_old model, IDofOrderer dofOrderer) { this.model = model; this.dofOrderer = dofOrderer; }
private DenseMatrixSolver(IModel model, IDofOrderer dofOrderer, bool isMatrixPositiveDefinite) : base(model, dofOrderer, new DenseMatrixAssembler(), "DenseMatrixSolver") { this.isMatrixPositiveDefinite = isMatrixPositiveDefinite; }
private Feti1Solver(IStructuralModel model, IFeti1SubdomainMatrixManagerFactory matrixManagerFactory, IDofOrderer dofOrderer, Dictionary <int, double> factorPivotTolerances, IFetiPreconditionerFactory preconditionerFactory, IFeti1InterfaceProblemSolver interfaceProblemSolver, bool problemIsHomogeneous, bool projectionMatrixQIsIdentity) { // Model if (model.Subdomains.Count == 1) { throw new InvalidSolverException( $"{name} cannot be used if there is only 1 subdomain"); } this.model = model; // Subdomains subdomains = new Dictionary <int, ISubdomain>(); foreach (ISubdomain subdomain in model.Subdomains) { subdomains[subdomain.ID] = subdomain; } // Matrix managers and linear systems matrixManagers = new Dictionary <int, IFeti1SubdomainMatrixManager>(); matrixManagersGeneral = new Dictionary <int, IFetiSubdomainMatrixManager>(); this.linearSystems = new Dictionary <int, ISingleSubdomainLinearSystem>(); var externalLinearSystems = new Dictionary <int, ILinearSystem>(); foreach (ISubdomain subdomain in model.Subdomains) { int s = subdomain.ID; var matrixManager = matrixManagerFactory.CreateMatricesManager(subdomain); matrixManagers[s] = matrixManager; matrixManagersGeneral[s] = matrixManager; this.linearSystems[s] = matrixManager.LinearSystem; externalLinearSystems[s] = matrixManager.LinearSystem; //TODO: This will call HandleMatrixWillBeSet() once for each subdomain. For now I will clear the data when // BuildMatrices() is called. Redesign this. //matrixManager.LinearSystem.MatrixObservers.Add(this); } LinearSystems = externalLinearSystems; this.dofOrderer = dofOrderer; this.dofSeparator = new Feti1DofSeparator(); this.factorPivotTolerances = factorPivotTolerances; this.preconditionerFactory = preconditionerFactory; // Interface problem this.interfaceProblemSolver = interfaceProblemSolver; // Homogeneous/heterogeneous problems this.problemIsHomogeneous = problemIsHomogeneous; this.projectionMatrixQIsIdentity = projectionMatrixQIsIdentity; if (problemIsHomogeneous) { this.stiffnessDistribution = new HomogeneousStiffnessDistribution(model, dofSeparator); } else { this.stiffnessDistribution = new HeterogeneousStiffnessDistribution(model, dofSeparator); } }
public GmresSolver(IStructuralAsymmetricModel model, AsymmetricDofOrderer dofRowOrderer, IDofOrderer dofColOrderer) : base(model, dofRowOrderer, dofColOrderer, new CsrRectangularAssembler(true), "GmresSolver") { this.gmresAlgorithm = new GmresAlgorithm.Builder().Build(); }
public GmresSolver(IAsymmetricModel model, GmresAlgorithm gmresAlgorithm, IPreconditionerFactory preconditionerFactory, AsymmetricDofOrderer dofRowOrderer, IDofOrderer dofColOrderer) : base(model, dofRowOrderer, dofColOrderer, new CsrNonSymmetricAssembler(true), "GmresSolver") { this.gmresAlgorithm = new GmresAlgorithm.Builder().Build(); this.preconditionerFactory = preconditionerFactory; }