예제 #1
0
 private PcgSolver(IModel model, PcgAlgorithm pcgAlgorithm, IPreconditionerFactory preconditionerFactory,
                   IDofOrderer dofOrderer) :
     base(model, dofOrderer, new CsrAssembler(true), "PcgSolver")
 {
     this.pcgAlgorithm          = pcgAlgorithm;
     this.preconditionerFactory = preconditionerFactory;
 }
예제 #2
0
 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;
 }
예제 #3
0
 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));
 }
예제 #4
0
 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));
 }
예제 #5
0
        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);
        }
예제 #6
0
 public void Propagate(IDofOrderer dofOrderer, Vector totalFreeDisplacements, Vector totalConstrainedDisplacements)
 {
     throw new NotImplementedException();
 }
예제 #7
0
 public StressRecovery(Model2D_old model, IDofOrderer dofOrderer)
 {
     this.model      = model;
     this.dofOrderer = dofOrderer;
 }
예제 #8
0
        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);
            }
        }
예제 #9
0
 public DisplacementOutput(Model2D_old model, IDofOrderer dofOrderer)
 {
     this.model      = model;
     this.dofOrderer = dofOrderer;
 }
예제 #10
0
 private SuiteSparseSolver(IModel model, double factorizationPivotTolerance, IDofOrderer dofOrderer) :
     base(model, dofOrderer, new SymmetricCscAssembler(), "SkylineSolver")
 {
     this.factorizationPivotTolerance = factorizationPivotTolerance;
 }
예제 #11
0
 private SkylineSolver(IStructuralModel model, double factorizationPivotTolerance, IDofOrderer dofOrderer) :
     base(model, dofOrderer, new SkylineAssembler(), "SkylineSolver")
 {
     this.factorizationPivotTolerance = factorizationPivotTolerance;
 }
예제 #12
0
 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;
 }
예제 #14
0
        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);
            }
        }
예제 #15
0
 public GmresSolver(IStructuralAsymmetricModel model, AsymmetricDofOrderer dofRowOrderer, IDofOrderer dofColOrderer)
     : base(model, dofRowOrderer, dofColOrderer, new CsrRectangularAssembler(true), "GmresSolver")
 {
     this.gmresAlgorithm = new GmresAlgorithm.Builder().Build();
 }
예제 #16
0
 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;
 }