public IntersectedMeshOutputAveraging(Model2D_old model, ICrackDescription crackGeometry, string pathNoExtension) { this.crackGeometry = crackGeometry; this.model = model; this.pathNoExtension = pathNoExtension; this.triangulator = new Triangulator2D <CartesianPoint>((x, y) => new CartesianPoint(x, y)); }
private IDomainDecomposer initialDecomposer; //TODO: this should be discarded once used. public TipAdaptiveDecomposer(BidirectionalMesh2D <XNode, XContinuumElement2D> mesh, IReadOnlyList <IRegion2D> regions, ICrackDescription crack, IDomainDecomposer initialDecomposer) { this.mesh = mesh; this.regions = regions; this.crack = crack; this.initialDecomposer = initialDecomposer; }
/// <summary> /// WARNING: This doesn't work if a node is enriched with more than 1 Heaviside functions from different cracks. /// </summary> /// <param name="subdomain"></param> /// <returns></returns> private static Dictionary <XNode, HashSet <IEnrichmentItem2D> > FindBoundaryNodesWithSingularHeaviside( ICrackDescription crack, XSubdomain2D_old subdomain) { var singularNodeEnrichments = new Dictionary <XNode, HashSet <IEnrichmentItem2D> >(); foreach (ISingleCrack singleCrack in crack.SingleCracks) { // Build nodal supports of boundary Heaviside nodes. // TODO: if the same node is enriched with more than one cracks, then avoid redoing the following for each crack var boundaryHeavisideNodes = new List <XNode>(); var nodalSupports = new List <ISet <XContinuumElement2D> >(); foreach (var node in subdomain.BoundaryNodes) { // Only process Heaviside nodes bool isHeaviside = false; foreach (var enrichment in node.EnrichmentItems.Keys) { if (enrichment == singleCrack.CrackBodyEnrichment) { boundaryHeavisideNodes.Add(node); isHeaviside = true; break; } } if (isHeaviside) { // Intersection of nodal support and subdomain var support = new HashSet <XContinuumElement2D>(); foreach (var element in singleCrack.Mesh.FindElementsWithNode(node)) { if (subdomain.Elements.Contains(element)) { support.Add(element); } } nodalSupports.Add(support); } } // Find problematic nodes ISet <XNode> singularNodes = singleCrack.SingularityResolver. FindHeavisideNodesToRemove(singleCrack, boundaryHeavisideNodes, nodalSupports); // Register the problematic nodes foreach (var node in singularNodes) { bool nodeExists = singularNodeEnrichments.TryGetValue(node, out HashSet <IEnrichmentItem2D> enrichmentsOnly); if (!nodeExists) { enrichmentsOnly = new HashSet <IEnrichmentItem2D>(); singularNodeEnrichments.Add(node, enrichmentsOnly); } enrichmentsOnly.Add(singleCrack.CrackBodyEnrichment); } } return(singularNodeEnrichments); }
public static XSubdomainDofOrderer CreateNodeMajor(ICrackDescription crack, XSubdomain2D_old subdomain) //TODO: also add AMD reordering { // Handle nodes with singular Heaviside enrichment Dictionary <XNode, HashSet <IEnrichmentItem2D> > singularityHeavisideEnrichments = FindBoundaryNodesWithSingularHeaviside(crack, subdomain); if (singularityHeavisideEnrichments.Count > 0) { Console.Write($"WARNING: Subdomain {subdomain.ID} has boundary nodes that are enriched with Heaviside,"); Console.Write(" but that would lead to singular matrices, since the nodal support in this subdomain only"); Console.Write(" contains Gauss points with the same sign. It would be better to use another domain"); Console.Write(" decomposition. The nodes in question are: "); foreach (var node in singularityHeavisideEnrichments.Keys) { Console.Write(node + " "); } Console.WriteLine(); } var subdomainEnrichedDofs = new DofTable <EnrichedDof>(); var boundaryDofs = new Dictionary <XNode, ISet <EnrichedDof> >(); int dofCounter = 0; foreach (XNode node in subdomain.AllNodes) { bool isboundaryNode = subdomain.BoundaryNodes.Contains(node); if (isboundaryNode && node.IsEnriched) { boundaryDofs.Add(node, new HashSet <EnrichedDof>()); } bool isSingularityNode = singularityHeavisideEnrichments.TryGetValue(node, out HashSet <IEnrichmentItem2D> singularEnrichments); foreach (IEnrichmentItem2D enrichment in node.EnrichmentItems.Keys) { if (isSingularityNode && singularEnrichments.Contains(enrichment)) { continue; } foreach (EnrichedDof dof in enrichment.Dofs) { if (isboundaryNode) { boundaryDofs[node].Add(dof); } subdomainEnrichedDofs[node, dof] = dofCounter; ++dofCounter; } } } return(new XSubdomainDofOrderer(dofCounter, subdomainEnrichedDofs, singularityHeavisideEnrichments, boundaryDofs)); }
public void OrderSubdomainDofs(ISet <XSubdomain2D_old> enrichedSubdomains, ISet <XSubdomain2D_old> modifiedSubdomains, ICrackDescription crack) { int numTotalDofs = NumStandardDofs; foreach (var subdomain in enrichedSubdomains) { if (modifiedSubdomains.Contains(subdomain)) { subdomain.DofOrderer = XSubdomainDofOrderer.CreateNodeMajor(crack, subdomain); } subdomain.DofOrderer.FirstGlobalDofIndex = numTotalDofs; numTotalDofs += subdomain.DofOrderer.NumEnrichedDofs; } }
public QuasiStaticCrackPropagationAnalyzer(XModel model, ISolver solver, /*IStaticProvider problem,*/ ICrackDescription crack, double fractureToughness, int maxIterations) { this.model = model; this.solver = solver; this.linearSystems = solver.LinearSystems; //this.problem = problem; this.crack = crack; this.fractureToughness = fractureToughness; this.maxIterations = maxIterations; //TODO: Refactor problem structural and remove the next problem = new ElementStructuralStiffnessProvider(); loadsAssembler = new DirichletEquivalentLoadsStructural(problem);; }