private static PreprocessorModel CreateModel(IReadOnlyList <Node> nodes, IReadOnlyList <CellConnectivity <Node> > elements) { PreprocessorModel model = PreprocessorModel.Create2DPlaneStress(thickness); // Materials properties ElasticMaterial2D material = new ElasticMaterial2D(StressState2D.PlaneStress) { YoungModulus = youngModulus, PoissonRatio = poissonRatio }; DynamicMaterial dynamicProperties = new DynamicMaterial(density, 0.05, 0.05, true); // Mesh model.AddMesh2D(nodes, elements, material, dynamicProperties); // Prescribed displacements: all nodes at the bottom double tol = 1E-10; IEnumerable <Node> constrainedNodes = nodes.Where(node => Math.Abs(node.Y) <= tol); model.ApplyPrescribedDisplacements(constrainedNodes, StructuralDof.TranslationX, 0.0); model.ApplyPrescribedDisplacements(constrainedNodes, StructuralDof.TranslationY, 0.0); return(model); }
public ContinuumElement2DFactory(double commonThickness, ElasticMaterial2D commonMaterial, DynamicMaterial commonDynamicProperties) { this.commonThickness = commonThickness; this.commonMaterial = commonMaterial; this.commonDynamicProperties = commonDynamicProperties; }
public Quad4(ElasticMaterial2D material) { materialsAtGaussPoints = new ElasticMaterial2D[iInt2]; for (int i = 0; i < iInt2; i++) { materialsAtGaussPoints[i] = (ElasticMaterial2D)material.Clone(); } }
/// <summary> /// Initializes a model for 2D plane strain problems. /// </summary> /// <param name="planeStrainMaterial">The material properties for a plane strain problem. For now they must be the same /// for the whole domain.</param> /// <returns></returns> public static PreprocessorModel Create2DPlaneStrain(ElasticMaterial2D planeStrainMaterial) //TODO: extend this for non linear materials { if (planeStrainMaterial.StressState != StressState2D.PlaneStrain) { throw new ArgumentException("The provided material is not for plane strain problems"); } return(new PreprocessorModel(ProblemDimensions.TwoDimensionalPlaneStrain, 1.0, planeStrainMaterial)); }
public LinearFemAnalysis2DUniformHardcoded(int numElementsX, int numElementsY, ElasticMaterial2D material, BoundaryConditions bc) { this.numElementsX = numElementsX; this.numElementsY = numElementsY; this.NumElements = numElementsX * numElementsY; this.material = material; this.bc = bc; }
private PreprocessorModel(ProblemDimensions dimensions, double thickness, ElasticMaterial2D planeStrainMaterial) { this.isAssembled = false; this.planeStrainMaterial = planeStrainMaterial; this.thickness = thickness; this.model = new Model(); this.model.SubdomainsDictionary.Add(0, new Subdomain(0)); //TODO: let the user decide how many subdomains there will be this.Dimensions = dimensions; }
private static Model CreateModel(int numElementsX, int numElementsY) { // Create mesh var meshGenerator = new UniformMeshGenerator2D(0, 0, length, height, numElementsX, numElementsY); (Node[] nodes, Element[] elements) = meshGenerator.CreateMesh(); // Create model and add the nodes var model = new Model(); foreach (Node node in nodes) { model.NodesDictionary.Add(node.ID, node); } // Find nodes on the left side and constrain their displacement var leftNodes = model.FindNodesWithX(0); foreach (Node node in leftNodes) { node.Constraints.AddRange(new[] { DOFType.X, DOFType.Y }); } // Find nodes on the right side and apply load var rightNodes = model.FindNodesWithX(length); double loadPerNode = totalLoad / rightNodes.Count; foreach (Node node in rightNodes) { model.Loads.Add(new Load() { Amount = loadPerNode, Node = node, DOF = DOFType.Y }); } // Create Quad4 elements and their material var material = new ElasticMaterial2D(StressState2D.PlaneStress) { YoungModulus = youngModulus, PoissonRatio = poissonRatio }; foreach (Element element in elements) { element.ElementType = new Quad4(material) { Thickness = thickness }; model.ElementsDictionary.Add(element.ID, element); } // Finalize model creation model.ConnectDataStructures(); return(model); }
public ContinuumElement2D CreateElement(CellType cellType, IReadOnlyList <Node> nodes, double thickness, ElasticMaterial2D material, DynamicMaterial dynamicProperties) { int numGPs = integrationsForStiffness[cellType].IntegrationPoints.Count; var materialsAtGaussPoints = new ElasticMaterial2D[numGPs]; for (int gp = 0; gp < numGPs; ++gp) { materialsAtGaussPoints[gp] = material.Clone(); } return(CreateElement(cellType, nodes, thickness, materialsAtGaussPoints, dynamicProperties)); }
private static void TestMbbBeamHardCoded() { // Parameters int numElementsX = 60, numElementsY = 20; double filterAreaRadius = 1.5; // Define the optimization var material = new ElasticMaterial2D(StressState2D.PlaneStress) { YoungModulus = youngModulus, PoissonRatio = 0.3 }; var fem = new LinearFemAnalysis2DUniformHardcoded(numElementsX, numElementsY, material, LinearFemAnalysis2DUniformHardcoded.BoundaryConditions.MbbBeam); var filter = new MeshIndependentSensitivityFilter2DUniform(numElementsX, numElementsY, filterAreaRadius); TestMbbBeam(fem, filter); }
private static Model CreateModel(int numElementsX, int numElementsY) { // Create mesh var meshGenerator = new UniformMeshGenerator2D(0, 0, length, height, numElementsX, numElementsY); (Node[] nodes, Element[] elements) = meshGenerator.CreateMesh(); // Create model and add the nodes var model = new Model(); foreach (Node node in nodes) { model.NodesDictionary.Add(node.ID, node); } // Create Quad4 elements and their material var material = new ElasticMaterial2D(StressState2D.PlaneStress) { YoungModulus = youngModulus, PoissonRatio = poissonRatio }; foreach (Element element in elements) { element.ElementType = new Quad4(material) { Thickness = thickness }; model.ElementsDictionary.Add(element.ID, element); } // Boundary conditions: // ******************************************************************************************* // ******************************************************************************************* // Excercise: Write your own boundary conditions for simply supported beam // ******************************************************************************************* // ******************************************************************************************* ApplyCantileverBoundaryConditions(model); // Finalize model creation model.ConnectDataStructures(); return(model); }
private static void TestCantileverBeamHardCoded() { // Parameters int numElementsX = 32, numElementsY = 20; double filterAreaRadius = 1.2; // Define the fem analysis and the filter var material = new ElasticMaterial2D(StressState2D.PlaneStress) { YoungModulus = 1.0, PoissonRatio = 0.3 }; var fem = new LinearFemAnalysis2DUniformHardcoded(numElementsX, numElementsY, material, LinearFemAnalysis2DUniformHardcoded.BoundaryConditions.ShortCantilever); var filter = new MeshIndependentSensitivityFilter2DUniform(numElementsX, numElementsY, filterAreaRadius); // Run the test TestCantileverBeam(fem, filter); }
private static void TestCantileverBeamWith2LoadCasesHardCoded() { // Parameters int numElementsX = 30, numElementsY = 30; double filterAreaRadius = 1.2, volumeFraction = 0.4, penalty = 3.0; // Define the optimization var material = new ElasticMaterial2D(StressState2D.PlaneStress) { YoungModulus = youngModulus, PoissonRatio = 0.3 }; var fem = new LinearFemAnalysis2DUniformHardcoded(numElementsX, numElementsY, material, LinearFemAnalysis2DUniformHardcoded.BoundaryConditions.Cantilever2LoadCases); var filter = new MeshIndependentSensitivityFilter2DUniform(numElementsX, numElementsY, filterAreaRadius); var materialInterpolation = new PowerLawMaterialInterpolation(youngModulus, penalty, 1E-3); var simp = new TopologySimpLinear2D(fem, optimAlgorithmBuilder, filter, materialInterpolation, volumeFraction); var logger = new ObjectiveFunctionLogger(); simp.Logger = logger; // Run the optimization simp.Initialize(); (double compliance, Vector densities) = simp.Optimize(); // Check the history of the compliance (objective function) var expectedCompliances = Vector.CreateFromArray( TopologySimp99LinesTests.ComplianceHistoryForCantileverWith2LoadCases); Assert.True(expectedCompliances.Equals( Vector.CreateFromArray(logger.ObjectiveFunctionValues.ToArray()), 1E-11)); // Check the optimum element densities (design variables). string densitiesPath = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.Parent.FullName + @"\Resources\topology99lines_cantilever_loadcases_densities.txt"; var reader = new FullMatrixReader(false, ','); Vector densitiesExpected = reader.ReadFile(densitiesPath).Reshape(false); Assert.True(densitiesExpected.Equals(densities, 1E-11)); }
public CantileverBeam BuildWithQuad4Elements(int numElementsAlongLength, int numElementsAlongHeight) { // Material and section properties double thickness = Width; var material = new ElasticMaterial2D(StressState2D.PlaneStress) { YoungModulus = this.YoungModulus, PoissonRatio = this.PoissonRatio }; var dynamicProperties = new DynamicMaterial(1.0, 0.0, 0.0); // Model with 1 subdomain var model = new Model(); model.SubdomainsDictionary.Add(subdomainID, new Subdomain(subdomainID)); // Generate mesh var meshGenerator = new UniformMeshGenerator2D <Node>(0.0, 0.0, Length, Height, numElementsAlongLength, numElementsAlongHeight); (IReadOnlyList <Node> vertices, IReadOnlyList <CellConnectivity <Node> > cells) = meshGenerator.CreateMesh((id, x, y, z) => new Node(id: id, x: x, y: y, z: z)); // Add nodes to the model for (int n = 0; n < vertices.Count; ++n) { model.NodesDictionary.Add(n, vertices[n]); } // Add Quad4 elements to the model var factory = new ContinuumElement2DFactory(thickness, material, dynamicProperties); for (int e = 0; e < cells.Count; ++e) { ContinuumElement2D element = factory.CreateElement(cells[e].CellType, cells[e].Vertices); var elementWrapper = new Element() { ID = e, ElementType = element }; foreach (Node node in element.Nodes) { elementWrapper.AddNode(node); } model.ElementsDictionary.Add(e, elementWrapper); model.SubdomainsDictionary[subdomainID].Elements.Add(elementWrapper); } // Clamp boundary condition at one end double tol = 1E-10; //TODO: this should be chosen w.r.t. the element size along X foreach (var node in model.Nodes.Where(node => Math.Abs(node.X) <= tol)) { node.Constraints.Add(new Constraint() { DOF = StructuralDof.TranslationX, Amount = 0.0 }); node.Constraints.Add(new Constraint() { DOF = StructuralDof.TranslationY, Amount = 0.0 }); } // Apply concentrated load at the other end Node[] loadedNodes = model.Nodes.Where(node => Math.Abs(node.X - Length) <= tol).ToArray(); foreach (var node in loadedNodes) { model.Loads.Add(new Load() { Amount = EndPointLoad / loadedNodes.Length, Node = node, DOF = StructuralDof.TranslationY }); } return(new CantileverBeam(Length, Height, Width, EndPointLoad, YoungModulus, model, loadedNodes)); }
/// <summary>Initializes a new instance of the <see cref="Quad4"/> class.</summary> /// <param name="material">An elastic two-dimensional plane=strain or plane-stress material.</param> /// <param name="dofEnumerator"><inheritdoc cref="GenericDOFEnumerator"/></param> public Quad4(ElasticMaterial2D material, GenericDOFEnumerator dofEnumerator) : this(material) => this.dofEnumerator = dofEnumerator;
private static void SolveQuadCantileverDecompositionTest2() { #region Quad Cantilever Model double youngModulus = 3.0e07; double poissonRatio = 0.3; double nodalLoad = 1000; // Create a new elastic 2D material var material = new ElasticMaterial2D(StressState2D.PlaneStress) { YoungModulus = youngModulus, PoissonRatio = poissonRatio }; // Model creation Model model = new Model(); // Add a single subdomain to the model model.SubdomainsDictionary.Add(0, new Subdomain(0)); // Add nodes to the nodes dictonary of the model int indexNode = 0; for (int i = 0; i < 25; i++) { for (int j = 0; j < 5; j++) { model.NodesDictionary.Add(indexNode, new Node(id: indexNode++, x: i, y: j, z: 0.0)); } } // Constrain left nodes of the model for (int i = 0; i < 5; i++) { model.NodesDictionary[i].Constraints.Add(new Constraint { DOF = StructuralDof.TranslationX }); model.NodesDictionary[i].Constraints.Add(new Constraint { DOF = StructuralDof.TranslationY }); } int indexElement = 0; for (int i = 0; i < 24; i++) { for (int j = 0; j < 4; j++) { var element = new Element() { ID = indexElement, ElementType = new Quad4(material) }; element.AddNode(model.NodesDictionary[i * 5 + j]); element.AddNode(model.NodesDictionary[(i + 1) * 5 + j]); element.AddNode(model.NodesDictionary[(i + 1) * 5 + j + 1]); element.AddNode(model.NodesDictionary[i * 5 + j + 1]); model.ElementsDictionary.Add(indexElement, element); model.SubdomainsDictionary[0].Elements.Add(element); indexElement++; } } // Add nodal load values to node 3 model.Loads.Add(new Load() { Amount = nodalLoad, Node = model.NodesDictionary[124], DOF = StructuralDof.TranslationY }); // Needed in order to make all the required data structures model.ConnectDataStructures(); #endregion var domainDecomposer = new AutomaticDomainDecomposer(model, 8); domainDecomposer.UpdateModel(); Dictionary <int, int[]> expectedSubdomains = new Dictionary <int, int[]>() { { 0, new int[] { 0, 4, 1, 5, 8, 9, 2, 6, 10, 12, 13, 14 } }, { 1, new int[] { 3, 7, 11, 15, 18, 19, 17, 21, 22, 23, 16, 20 } }, { 2, new int[] { 24, 28, 25, 29, 32, 33, 26, 30, 34, 36, 37, 38 } }, { 3, new int[] { 27, 31, 35, 39, 42, 43, 41, 45, 46, 47, 40, 44 } }, { 4, new int[] { 48, 52, 49, 53, 56, 57, 50, 54, 58, 60, 61, 62 } }, { 5, new int[] { 51, 55, 59, 63, 66, 67, 65, 69, 70, 71, 64, 68 } }, { 6, new int[] { 72, 76, 73, 77, 80, 81, 74, 78, 82, 84, 85, 86 } }, { 7, new int[] { 75, 79, 83, 87, 90, 91, 89, 93, 94, 95, 88, 92 } } }; for (int i = 0; i < expectedSubdomains.Count; i++) { var subdomainElements = model.SubdomainsDictionary[i].Elements; Assert.Equal(expectedSubdomains[i].Length, model.SubdomainsDictionary[i].Elements.Count); for (int j = 0; j < expectedSubdomains[i].Length; j++) { Assert.Equal(expectedSubdomains[i][j], subdomainElements[j].ID); } } }
private static void SolveQuadCantileverDecompositionTest3() { #region Quad Cantilever Model double youngModulus = 3.0e07; double poissonRatio = 0.3; double nodalLoad = 1000; // Create a new elastic 2D material var material = new ElasticMaterial2D(StressState2D.PlaneStress) { YoungModulus = youngModulus, PoissonRatio = poissonRatio }; // Model creation Model model = new Model(); // Add a single subdomain to the model model.SubdomainsDictionary.Add(0, new Subdomain(0)); // Add nodes to the nodes dictonary of the model int indexNode = 0; for (int i = 0; i < 6; i++) { for (int j = 0; j < 3; j++) { model.NodesDictionary.Add(indexNode, new Node(id: indexNode++, x: i, y: j, z: 0.0)); } } // Constrain left nodes of the model for (int i = 0; i < 3; i++) { model.NodesDictionary[i].Constraints.Add(new Constraint { DOF = StructuralDof.TranslationX }); model.NodesDictionary[i].Constraints.Add(new Constraint { DOF = StructuralDof.TranslationY }); } int indexElement = 0; for (int i = 0; i < 5; i++) { for (int j = 0; j < 2; j++) { var element = new Element() { ID = indexElement, ElementType = new Quad4(material) }; element.AddNode(model.NodesDictionary[i * 3 + j]); element.AddNode(model.NodesDictionary[(i + 1) * 3 + j]); element.AddNode(model.NodesDictionary[(i + 1) * 3 + j + 1]); element.AddNode(model.NodesDictionary[i * 3 + j + 1]); model.ElementsDictionary.Add(indexElement, element); model.SubdomainsDictionary[0].Elements.Add(element); indexElement++; } } // Add nodal load values to node 3 model.Loads.Add(new Load() { Amount = nodalLoad, Node = model.NodesDictionary[17], DOF = StructuralDof.TranslationY }); // Needed in order to make all the required data structures model.ConnectDataStructures(); #endregion var domainDecomposer = new AutomaticDomainDecomposer(model, 3); domainDecomposer.UpdateModel(); Dictionary <int, int[]> expectedSubdomains = new Dictionary <int, int[]>() { { 0, new int[] { 0, 2, 1, 3 } }, { 1, new int[] { 4, 6, 5, 7 } }, { 2, new int[] { 8, 9 } } }; for (int i = 0; i < expectedSubdomains.Count; i++) { var subdomainElements = model.SubdomainsDictionary[i].Elements; Assert.Equal(expectedSubdomains[i].Length, model.SubdomainsDictionary[i].Elements.Count); for (int j = 0; j < expectedSubdomains[i].Length; j++) { Assert.Equal(expectedSubdomains[i][j], subdomainElements[j].ID); } } }
private static Model CreateModel(IReadOnlyList <Node> nodes, IReadOnlyList <CellConnectivity <Node> > elements) { // Initialize int numNodes = nodes.Count; int numElements = elements.Count; // Materials ElasticMaterial2D material = new ElasticMaterial2D(StressState2D.PlaneStress) { YoungModulus = youngModulus, PoissonRatio = poissonRatio }; // Subdomains Model model = new Model(); model.SubdomainsDictionary.Add(0, new Subdomain(0)); // Nodes for (int i = 0; i < numNodes; ++i) { model.NodesDictionary.Add(i, nodes[i]); } // Elements var factory = new ContinuumElement2DFactory(thickness, material, null); for (int i = 0; i < numElements; ++i) { ContinuumElement2D element = factory.CreateElement(elements[i].CellType, elements[i].Vertices); var elementWrapper = new Element() { ID = i, ElementType = element }; foreach (Node node in element.Nodes) { elementWrapper.AddNode(node); } model.ElementsDictionary.Add(i, elementWrapper); model.SubdomainsDictionary[0].Elements.Add(elementWrapper); } // Constraints double tol = 1E-10; Node[] constrainedNodes = nodes.Where(node => Math.Abs(node.Y) <= tol).ToArray(); for (int i = 0; i < constrainedNodes.Length; i++) { constrainedNodes[i].Constraints.Add(new Constraint { DOF = StructuralDof.TranslationX }); constrainedNodes[i].Constraints.Add(new Constraint { DOF = StructuralDof.TranslationY }); } // Loads Node[] loadedNodes = nodes.Where( node => (Math.Abs(node.Y - height) <= tol) && ((Math.Abs(node.X) <= tol))).ToArray(); if (loadedNodes.Length != 1) { throw new Exception("Only 1 node was expected at the top left corner"); } model.Loads.Add(new Load() { Amount = maxLoad, Node = loadedNodes[0], DOF = StructuralDof.TranslationX }); return(model); }
public static void Check2DscaleTransitionsAndMicrostructure() { //Check05cStressIntegration() double E_disp = 3.5; /*Gpa*/ double ni_disp = 0.4; // stathera Poisson var material1 = new ElasticMaterial2D(StressState2D.PlaneStress) { YoungModulus = E_disp, PoissonRatio = ni_disp, }; double[] GLVec = new double[3] { 0.01, 0, 0 }; material1.UpdateMaterial(GLVec); double[] stressesCheck1 = new double[3] { material1.Stresses[0], material1.Stresses[1], material1.Stresses[2] }; //material1.SaveState(); GLVec = new double[3] { 0.02, 0, 0 }; material1.UpdateMaterial(GLVec); double[] stressesCheck2 = new double[3] { material1.Stresses[0], material1.Stresses[1], material1.Stresses[2] }; //VectorExtensions.AssignTotalAffinityCount(); IdegenerateRVEbuilder homogeneousRveBuilder1 = new HomogeneousRVEBuilderLinearAndDegenerate(); //IRVEbuilder homogeneousRveBuilder1 = new HomogeneousRVEBuilderCheckEnaHexa(); IContinuumMaterial2D microstructure3 = new Microstructure2DplaneStress(homogeneousRveBuilder1, model => (new SkylineSolver.Builder()).BuildSolver(model), false, 1); //IContinuumMaterial3DDefGrad microstructure3copyConsCheck = new Microstructure3copyConsCheckEna(homogeneousRveBuilder1); double[,] consCheck1 = new double[3, 3]; for (int i1 = 0; i1 < 3; i1++) { for (int i2 = 0; i2 < 3; i2++) { consCheck1[i1, i2] = microstructure3.ConstitutiveMatrix[i1, i2]; } } microstructure3.UpdateMaterial(new double[3] { 0.010, 0, 0 }); double[] stressesCheck3 = new double[3] { microstructure3.Stresses[0], microstructure3.Stresses[1], microstructure3.Stresses[2] }; microstructure3.SaveState(); microstructure3.UpdateMaterial(new double[3] { 0.020, 0, 0 }); double[] stressesCheck4 = new double[3] { microstructure3.Stresses[0], microstructure3.Stresses[1], microstructure3.Stresses[2] }; microstructure3.SaveState(); microstructure3.UpdateMaterial(new double[3] { 0.030, 0, 0 }); double[] stressesCheck5 = new double[3] { microstructure3.Stresses[0], microstructure3.Stresses[1], microstructure3.Stresses[2] }; var Matrix1 = Matrix.CreateZero(3, 3); for (int i1 = 0; i1 < 3; i1++) { for (int i2 = 0; i2 < 3; i2++) { Matrix1[i1, i2] = microstructure3.ConstitutiveMatrix[i1, i2]; } } Assert.True(NRNLAnalyzerDevelopTest.AreDisplacementsSame(stressesCheck1, stressesCheck3)); Assert.True(NRNLAnalyzerDevelopTest.AreDisplacementsSame(stressesCheck2, stressesCheck4)); Assert.True(NRNLAnalyzerDevelopTest.AreDisplacementsSame(new double[3] { 3 * stressesCheck1[0], 3 * stressesCheck1[1], 3 * stressesCheck1[2] }, stressesCheck5)); Assert.True(AreDisplacementsSame(consCheck1, material1.ConstitutiveMatrix)); Assert.True(AreDisplacementsSame(Matrix1.CopyToArray2D(), material1.ConstitutiveMatrix)); }
private static void SolveDynamicLinearWall() { // Some values string workingDirectory = @"C:\Users\Serafeim\Desktop\Presentation"; double thickness = 0.1; double youngModulus = 2E6; double poissonRatio = 0.3; // Initialize model PreprocessorModel model = PreprocessorModel.Create2DPlaneStress(thickness); // Materials ElasticMaterial2D material = new ElasticMaterial2D(StressState2D.PlaneStress) { YoungModulus = youngModulus, PoissonRatio = poissonRatio }; DynamicMaterial dynamicProperties = new DynamicMaterial(25, 0.05, 0.05, true); // Read mesh from GMSH file string meshPath = workingDirectory + "\\wall.msh"; IReadOnlyList <Node> nodes; IReadOnlyList <CellConnectivity <Node> > elements; using (var reader = new GmshReader <Node>(meshPath)) { (nodes, elements) = reader.CreateMesh((id, x, y, z) => new Node(id: id, x: x, y: y, z: z)); } model.AddMesh2D(nodes, elements, material, dynamicProperties); // Prescribed displacements double tol = 1E-10; IEnumerable <Node> constrainedNodes = nodes.Where(node => Math.Abs(node.Y) <= tol); model.ApplyPrescribedDisplacements(constrainedNodes, StructuralDof.TranslationX, 0.0); model.ApplyPrescribedDisplacements(constrainedNodes, StructuralDof.TranslationY, 0.0); // Loads string accelerogramPath = workingDirectory + "\\elcentro_NS.txt"; Dictionary <IDofType, double> magnifications = new Dictionary <IDofType, double> { { StructuralDof.TranslationX, 1.0 } }; model.SetGroundMotion(accelerogramPath, magnifications, 0.02, 53.74); // Define output OutputRequests output = new OutputRequests(workingDirectory + "\\Plots"); output.Displacements = true; output.Strains = true; output.Stresses = true; output.StressesVonMises = true; // Set up the simulation procedure Job job = new Job(model); job.Procedure = Job.ProcedureOptions.DynamicImplicit; job.Integrator = Job.IntegratorOptions.Linear; job.Solver = Job.SolverOptions.DirectSkyline; job.FieldOutputRequests = output; // Run the simulation job.Submit(); }
private static void SolveStaticLinearWall() { // Some values string workingDirectory = @"C:\Users\Serafeim\Desktop\Presentation"; double height = 3.5; double thickness = 0.1; double youngModulus = 2E6; double poissonRatio = 0.3; double horizontalLoad = 1000.0; // Initialize model PreprocessorModel model = PreprocessorModel.Create2DPlaneStress(thickness); // Materials ElasticMaterial2D material = new ElasticMaterial2D(StressState2D.PlaneStress) { YoungModulus = youngModulus, PoissonRatio = poissonRatio }; // Read mesh from GMSH file string meshPath = workingDirectory + "\\wall.msh"; IReadOnlyList <Node> nodes; IReadOnlyList <CellConnectivity <Node> > elements; using (var reader = new GmshReader <Node>(meshPath)) { (nodes, elements) = reader.CreateMesh((id, x, y, z) => new Node(id: id, x: x, y: y, z: z)); } model.AddMesh2D(nodes, elements, material); // Prescribed displacements double tol = 1E-10; IEnumerable <Node> constrainedNodes = nodes.Where(node => Math.Abs(node.Y) <= tol); model.ApplyPrescribedDisplacements(constrainedNodes, StructuralDof.TranslationX, 0.0); model.ApplyPrescribedDisplacements(constrainedNodes, StructuralDof.TranslationY, 0.0); // Loads Node[] loadedNodes = nodes.Where( node => (Math.Abs(node.Y - height) <= tol) && ((Math.Abs(node.X) <= tol))).ToArray(); if (loadedNodes.Length != 1) { throw new Exception("Only 1 node was expected at the top left corner"); } model.ApplyNodalLoad(loadedNodes[0], StructuralDof.TranslationX, horizontalLoad); // Define output OutputRequests output = new OutputRequests(workingDirectory + "\\Plots"); output.Displacements = true; output.Strains = true; output.Stresses = true; output.StressesVonMises = true; // Set up the simulation procedure Job job = new Job(model); job.Procedure = Job.ProcedureOptions.Static; job.Integrator = Job.IntegratorOptions.Linear; job.Solver = Job.SolverOptions.DirectSkyline; job.FieldOutputRequests = output; // Run the simulation job.Submit(); }
private static void TestQuad4LinearCantileverExample() { // Model & subdomains var model = new Model(); int subdomainID = 0; model.SubdomainsDictionary.Add(subdomainID, new Subdomain(subdomainID)); // Materials double youngModulus = 3.76; double poissonRatio = 0.3779; double thickness = 1.0; double nodalLoad = 500.0; var material = new ElasticMaterial2D(StressState2D.PlaneStress) { YoungModulus = youngModulus, PoissonRatio = poissonRatio }; // Nodes var nodes = new Node[] { new Node(id: 1, x: 0.0, y: 0.0, z: 0.0), new Node(id: 2, x: 10.0, y: 0.0, z: 0.0), new Node(id: 3, x: 10.0, y: 10.0, z: 0.0), new Node(id: 4, x: 0.0, y: 10.0, z: 0.0) }; for (int i = 0; i < nodes.Length; ++i) { model.NodesDictionary.Add(i, nodes[i]); } // Elements var factory = new ContinuumElement2DFactory(thickness, material, null); var elementWrapper = new Element() { ID = 0, ElementType = factory.CreateElement(CellType.Quad4, nodes) }; elementWrapper.AddNodes(nodes); model.ElementsDictionary.Add(elementWrapper.ID, elementWrapper); model.SubdomainsDictionary[subdomainID].Elements.Add(elementWrapper); //var a = quad.StiffnessMatrix(element); // Prescribed displacements model.NodesDictionary[0].Constraints.Add(new Constraint() { DOF = StructuralDof.TranslationX, Amount = 0.0 }); model.NodesDictionary[0].Constraints.Add(new Constraint() { DOF = StructuralDof.TranslationY, Amount = 0.0 }); model.NodesDictionary[3].Constraints.Add(new Constraint() { DOF = StructuralDof.TranslationX, Amount = 0.0 }); model.NodesDictionary[3].Constraints.Add(new Constraint() { DOF = StructuralDof.TranslationY, Amount = 0.0 }); // Nodal loads model.Loads.Add(new Load() { Amount = nodalLoad, Node = model.NodesDictionary[1], DOF = StructuralDof.TranslationX }); model.Loads.Add(new Load() { Amount = nodalLoad, Node = model.NodesDictionary[2], DOF = StructuralDof.TranslationX }); // Solver var pcgBuilder = new PcgAlgorithm.Builder(); pcgBuilder.ResidualTolerance = 1E-6; pcgBuilder.MaxIterationsProvider = new PercentageMaxIterationsProvider(0.5); var solverBuilder = new PcgSolver.Builder(); solverBuilder.PcgAlgorithm = pcgBuilder.Build(); PcgSolver solver = solverBuilder.BuildSolver(model); // Problem type var provider = new ProblemStructural(model, solver); // Analyzers var childAnalyzer = new LinearAnalyzer(model, solver, provider); var parentAnalyzer = new StaticAnalyzer(model, solver, provider, childAnalyzer); //NewmarkDynamicAnalyzer parentAnalyzer = new NewmarkDynamicAnalyzer(provider, childAnalyzer, linearSystems, 0.25, 0.5, 0.28, 3.36); // Request output childAnalyzer.LogFactories[subdomainID] = new LinearAnalyzerLogFactory(new int[] { 0 }); // Run the anlaysis parentAnalyzer.Initialize(); parentAnalyzer.Solve(); // Check output DOFSLog log = (DOFSLog)childAnalyzer.Logs[subdomainID][0]; //There is a list of logs for each subdomain and we want the first one Assert.Equal(253.132375961535, log.DOFValues[0], 8); }
public ElasticPlaneStrainVonMises(ElasticMaterial2D material) { this.E = material.YoungModulus; this.v = material.PoissonRatio; }
public void TestQuad4LinearCantileverExample() { // Model and node creation var model = new Model(); model.NodesDictionary.Add(1, new Node { ID = 1, X = 0.0, Y = 0.0, Z = 0.0 }); model.NodesDictionary.Add(2, new Node { ID = 2, X = 10.0, Y = 0.0, Z = 0.0 }); model.NodesDictionary.Add(3, new Node { ID = 3, X = 10.0, Y = 10.0, Z = 0.0 }); model.NodesDictionary.Add(4, new Node { ID = 4, X = 0.0, Y = 10.0, Z = 0.0 }); // Constrain bottom nodes of the model and add loads model.NodesDictionary[1].Constraints.AddRange(new[] { DOFType.X, DOFType.Y }); model.NodesDictionary[4].Constraints.AddRange(new[] { DOFType.X, DOFType.Y }); model.Loads.Add(new Load() { Amount = 500, Node = model.NodesDictionary[2], DOF = DOFType.X }); model.Loads.Add(new Load() { Amount = 500, Node = model.NodesDictionary[3], DOF = DOFType.X }); // Create Quad4 element and its material var material = new ElasticMaterial2D(StressState2D.PlaneStress) { YoungModulus = 3.76, PoissonRatio = 0.3779 }; var quad = new Quad4(material) { Thickness = 1 }; // Create the element connectivity var element = new Element() { ID = 1, ElementType = quad }; element.AddNode(model.NodesDictionary[1]); element.AddNode(model.NodesDictionary[2]); element.AddNode(model.NodesDictionary[3]); element.AddNode(model.NodesDictionary[4]); // Add quad element to the element and subdomains dictionary of the model model.ElementsDictionary.Add(element.ID, element); model.ConnectDataStructures(); // Setup var linearSystem = new SkylineLinearSystem(model.Forces); var solver = new SolverSkyline(linearSystem); var provider = new ProblemStructural(model); var childAnalyzer = new LinearAnalyzer(solver); var parentAnalyzer = new StaticAnalyzer(provider, childAnalyzer, linearSystem); parentAnalyzer.BuildMatrices(); parentAnalyzer.Initialize(); parentAnalyzer.Solve(); var expectedSolution = new double[] { 253.13237596153559, 66.567582057178811, 253.13237596153553, -66.567582057178811 }; for (int i = 0; i < expectedSolution.Length; i++) { Assert.Equal(expectedSolution[i], linearSystem.Solution[i], 12); } }
private static void TestCantileverBeamGeneral() { // Define the materials double thickness = 1.0; var material = new ElasticMaterial2D(StressState2D.PlaneStress) { YoungModulus = youngModulus, PoissonRatio = 0.3 }; var dynamicProperties = new DynamicMaterial(1.0, 0.0, 0.0, true); // Model with 1 subdomain var model = new Model(); model.SubdomainsDictionary.Add(subdomainID, new Subdomain(subdomainID)); // Generate mesh int numElementsX = 32, numElementsY = 20; double lengthX = numElementsX; double depthY = numElementsY; var mesher = new UniformMeshGenerator2D <Node>(0, 0, lengthX, depthY, numElementsX, numElementsY); (IReadOnlyList <Node> nodes, IReadOnlyList <CellConnectivity <Node> > connectivity) = mesher.CreateMesh((id, x, y, z) => new Node(id: id, x: x, y: y, z: z)); // Add nodes to the model for (int n = 0; n < nodes.Count; ++n) { model.NodesDictionary.Add(n, nodes[n]); } // Add Quad4 elements to the model var factory = new ContinuumElement2DFactory(thickness, material, dynamicProperties); for (int e = 0; e < connectivity.Count; ++e) { ContinuumElement2D element = factory.CreateElement(connectivity[e].CellType, connectivity[e].Vertices); var elementWrapper = new Element() { ID = e, ElementType = element }; foreach (Node node in element.Nodes) { elementWrapper.AddNode(node); } model.ElementsDictionary.Add(e, elementWrapper); model.SubdomainsDictionary[subdomainID].Elements.Add(elementWrapper); } // Clamp boundary condition at left edge double tol = 1E-10; //TODO: this should be chosen w.r.t. the element size along X foreach (var node in model.Nodes.Where(node => Math.Abs(node.X) <= tol)) { node.Constraints.Add(new Constraint() { DOF = StructuralDof.TranslationX, Amount = 0.0 }); node.Constraints.Add(new Constraint() { DOF = StructuralDof.TranslationY, Amount = 0.0 }); } // Apply concentrated load at the bottom right corner double load = 1.0; var cornerNode = model.Nodes.Where( node => (Math.Abs(node.X - lengthX) <= tol) && (Math.Abs(node.Y - depthY) <= tol)); Assert.True(cornerNode.Count() == 1); model.Loads.Add(new Load() { Amount = load, Node = cornerNode.First(), DOF = StructuralDof.TranslationY }); // Define the solver SkylineSolver solver = (new SkylineSolver.Builder()).BuildSolver(model); // Define the fem analysis and the filter double filterAreaRadius = 1.2; var fem = new LinearFemAnalysis2DGeneral(model, solver); var filter = new ProximityDensityFilter2D(model, filterAreaRadius); // Run the test TestCantileverBeam(fem, filter); }
public Quad4(ElasticMaterial2D material, IElementDofEnumerator dofEnumerator) : this(material) { this.dofEnumerator = dofEnumerator; }
public static void WriteStiffnessOfContinuum2DStructure() { // ____ ____ // | | | // |____|____| // | | | // |____|____| // Model with 1 subdomain var model = new Model(); model.SubdomainsDictionary.Add(subdomainID, new Subdomain(subdomainID)); // Material double thickness = 1.0; var material = new ElasticMaterial2D(StressState2D.PlaneStress) { YoungModulus = 2.1E7, PoissonRatio = 0.3 }; var dynamicProperties = new DynamicMaterial(1.0, 0.0, 0.0, true); // Generate mesh double domainLength = 2.0; double domainHeight = 2.4; var meshGenerator = new UniformMeshGenerator2D <Node>(0.0, 0.0, domainLength, domainHeight, 10, 10); (IReadOnlyList <Node> vertices, IReadOnlyList <CellConnectivity <Node> > cells) = meshGenerator.CreateMesh((id, x, y, z) => new Node(id: id, x: x, y: y, z: z)); // Add nodes to the model for (int n = 0; n < vertices.Count; ++n) { model.NodesDictionary.Add(n, vertices[n]); } // Add Quad4 elements to the model var factory = new ContinuumElement2DFactory(thickness, material, dynamicProperties); for (int e = 0; e < cells.Count; ++e) { ContinuumElement2D element = factory.CreateElement(cells[e].CellType, cells[e].Vertices); var elementWrapper = new Element() { ID = e, ElementType = element }; foreach (Node node in element.Nodes) { elementWrapper.AddNode(node); } model.ElementsDictionary.Add(e, elementWrapper); model.SubdomainsDictionary[subdomainID].Elements.Add(elementWrapper); } // Solver var solverBuilder = new SkylineSolver.Builder(); SkylineSolver solver = solverBuilder.BuildSolver(model); // Structural problem provider var provider = new ProblemStructural(model, solver); // Linear static analysis var childAnalyzer = new LinearAnalyzer(model, solver, provider); var parentAnalyzer = new StaticAnalyzer(model, solver, provider, childAnalyzer); // Run the analysis to build the stiffness matrix parentAnalyzer.Initialize(); parentAnalyzer.BuildMatrices(); // Print the stiffness matrix //var writer = new MatlabWriter(); var writer = new RawArraysWriter(); writer.WriteToMultipleFiles((SkylineMatrix)solver.LinearSystems[subdomainID].Matrix, outputDirectory + @"\quad4_20x20_stiffness.txt"); }