diff --git a/src/Mod/Fem/femsolver/elmer/equations/elasticity.py b/src/Mod/Fem/femsolver/elmer/equations/elasticity.py index fc93fe34d2..cdf1e7520a 100644 --- a/src/Mod/Fem/femsolver/elmer/equations/elasticity.py +++ b/src/Mod/Fem/femsolver/elmer/equations/elasticity.py @@ -44,49 +44,119 @@ class Proxy(linear.Proxy, equationbase.ElasticityProxy): def __init__(self, obj): super(Proxy, self).__init__(obj) - obj.addProperty( - "App::PropertyBool", - "DoFrequencyAnalysis", - "Elasticity", - "" - ) - obj.addProperty( - "App::PropertyInteger", - "EigenmodesCount", - "Elasticity", - "" - ) + obj.addProperty( "App::PropertyBool", "CalculateStrains", "Elasticity", - "" + "Compute the strain tensor" ) obj.addProperty( "App::PropertyBool", "CalculateStresses", "Elasticity", - "" + "Compute stress tensor and vanMises" ) obj.addProperty( "App::PropertyBool", "CalculatePrincipal", "Elasticity", - "" + "Compute principal stress components" ) obj.addProperty( "App::PropertyBool", "CalculatePangle", "Elasticity", - "" + "Compute principal stress angles" ) - obj.EigenmodesCount = 5 + obj.addProperty( + "App::PropertyBool", + "ConstantBulkSystem", + "Elasticity", + "See Elmer manual for info" + ) + obj.addProperty( + "App::PropertyBool", + "DisplaceMesh", + "Elasticity", + "If mesh is deformed by displacement field.\nSet to False for 'Eigen Analysis'." + ) + obj.addProperty( + "App::PropertyBool", + "EigenAnalysis", + "Elasticity", + "If true, modal analysis" + ) + obj.addProperty( + "App::PropertyInteger", + "EigenSystemValues", + "Elasticity", + "Number of lowest eigen modes" + ) + obj.addProperty( + "App::PropertyBool", + "FixDisplacement", + "Elasticity", + "If displacements or forces are set,\nthereby model lumping is used" + ) + obj.addProperty( + "App::PropertyBool", + "GeometricStiffness", + "Elasticity", + "Consider geometric stiffness" + ) + obj.addProperty( + "App::PropertyBool", + "Incompressible", + "Elasticity", + "Computation of incompressible material in connection\nwith viscoelastic Maxwell material and a custom 'Variable'" + ) + obj.addProperty( + "App::PropertyBool", + "MaxwellMaterial", + "Elasticity", + "Compute viscoelastic material model" + ) + obj.addProperty( + "App::PropertyBool", + "ModelLumping", + "Elasticity", + "Use model lumping" + ) + obj.addProperty( + "App::PropertyFile", + "ModelLumpingFilename", + "Elasticity", + "File to save results from model lumping to" + ) + obj.addProperty( + "App::PropertyBool", + "StabilityAnalysis", + "Elasticity", + "If true, 'Eigen Analysis' is stability analysis.\nOtherwise modal analysis is performed." + ) + obj.addProperty( + "App::PropertyBool", + "UpdateTransientSystem", + "Elasticity", + "See Elmer manual for info" + ) + obj.addProperty( + "App::PropertyString", + "Variable", + "Elasticity", + "Only change this if 'Incompressible' is set to true\naccording to the Elmer manual." + ) + + obj.EigenSystemValues = 5 obj.Priority = 10 obj.CalculatePrincipal = True + obj.DisplaceMesh = True # according to the Elmer tutorial and forum, for stresses direct solving # is recommended -> test showed 10 times faster and even more accurate obj.LinearSolverType = "Direct" obj.LinearDirectMethod = "Umfpack" + obj.Variable = "Displacement" class ViewProxy(linear.ViewProxy, equationbase.ElasticityViewProxy): diff --git a/src/Mod/Fem/femsolver/elmer/writer.py b/src/Mod/Fem/femsolver/elmer/writer.py index ddc28f1590..b649a09b7c 100644 --- a/src/Mod/Fem/femsolver/elmer/writer.py +++ b/src/Mod/Fem/femsolver/elmer/writer.py @@ -583,22 +583,145 @@ class Writer(object): def _getElasticitySolver(self, equation): s = self._createLinearSolver(equation) + # check if we need to update the equation + self._updateElasticitySolver(equation) + # output the equation parameters s["Equation"] = "Stress Solver" # equation.Name s["Procedure"] = sifio.FileAttr("StressSolve/StressSolver") - s["Variable"] = self._getUniqueVarName("Displacement") + s["Variable"] = equation.Variable s["Variable DOFs"] = 3 - s["Eigen Analysis"] = equation.DoFrequencyAnalysis - s["Eigen System Values"] = equation.EigenmodesCount s["Calculate Strains"] = equation.CalculateStrains s["Calculate Stresses"] = equation.CalculateStresses s["Calculate Principal"] = equation.CalculatePrincipal s["Calculate Pangle"] = equation.CalculatePangle - s["Displace mesh"] = False - s["Exec Solver"] = "Always" + s["Constant Bulk System"] = equation.ConstantBulkSystem + s["Displace mesh"] = equation.DisplaceMesh + s["Eigen Analysis"] = equation.EigenAnalysis + s["Eigen System Values"] = equation.EigenSystemValues + s["Fix Displacement"] = equation.FixDisplacement + s["Geometric Stiffness"] = equation.GeometricStiffness + s["Incompressible"] = equation.Incompressible + s["Maxwell Material"] = equation.MaxwellMaterial + s["Model Lumping"] = equation.ModelLumping + s["Model Lumping Filename"] = equation.ModelLumpingFilename s["Optimize Bandwidth"] = True + s["Stability Analysis"] = equation.StabilityAnalysis s["Stabilize"] = equation.Stabilize + s["Update Transient System"] = equation.UpdateTransientSystem return s + def _updateElasticitySolver(self, equation): + # updates older Elasticity equations + if not hasattr(equation, "Variable"): + equation.addProperty( + "App::PropertyString", + "Variable", + "Elasticity", + "Only change this if 'Incompressible' is set to true\naccording to the Elmer manual." + ) + equation.Variable = "Displacement" + if hasattr(equation, "Bubbles"): + # Bubbles was removed because it is unused by Elmer for the stress solver + equation.removeProperty("Bubbles") + if not hasattr(equation, "ConstantBulkSystem"): + equation.addProperty( + "App::PropertyBool", + "ConstantBulkSystem", + "Elasticity", + "See Elmer manual for info") + if not hasattr(equation, "DisplaceMesh"): + equation.addProperty( + "App::PropertyBool", + "DisplaceMesh", + "Elasticity", + "If mesh is deformed by displacement field.\nSet to False for 'Eigen Analysis'." + ) + # DisplaceMesh is true except if DoFrequencyAnalysis is true + equation.DisplaceMesh = True + if hasattr(equation, "DoFrequencyAnalysis"): + if equation.DoFrequencyAnalysis == True: + equation.DisplaceMesh = False + if not hasattr(equation, "EigenAnalysis"): + # DoFrequencyAnalysis was renamed to EigenAnalysis + # to follow the Elmer manual + equation.addProperty( + "App::PropertyBool", + "EigenAnalysis", + "Elasticity", + "If true, modal analysis" + ) + if hasattr(equation, "DoFrequencyAnalysis"): + equation.EigenAnalysis = equation.DoFrequencyAnalysis + equation.removeProperty("DoFrequencyAnalysis") + if not hasattr(equation, "EigenSystemValues"): + # EigenmodesCount was renamed to EigenSystemValues + # to follow the Elmer manual + equation.addProperty( + "App::PropertyInteger", + "EigenSystemValues", + "Elasticity", + "Number of lowest eigen modes" + ) + if hasattr(equation, "EigenmodesCount"): + equation.EigenSystemValues = equation.EigenmodesCount + equation.removeProperty("EigenmodesCount") + if not hasattr(equation, "FixDisplacement"): + equation.addProperty( + "App::PropertyBool", + "FixDisplacement", + "Elasticity", + "If displacements or forces are set,\nthereby model lumping is used" + ) + if not hasattr(equation, "GeometricStiffness"): + equation.addProperty( + "App::PropertyBool", + "GeometricStiffness", + "Elasticity", + "Consider geometric stiffness" + ) + if not hasattr(equation, "Incompressible"): + equation.addProperty( + "App::PropertyBool", + "Incompressible", + "Elasticity", + "Computation of incompressible material in connection\nwith viscoelastic Maxwell material and a custom 'Variable'" + ) + if not hasattr(equation, "MaxwellMaterial"): + equation.addProperty( + "App::PropertyBool", + "MaxwellMaterial", + "Elasticity", + "Compute viscoelastic material model" + ) + if not hasattr(equation, "ModelLumping"): + equation.addProperty( + "App::PropertyBool", + "ModelLumping", + "Elasticity", + "Use model lumping" + ) + if not hasattr(equation, "ModelLumpingFilename"): + equation.addProperty( + "App::PropertyFile", + "ModelLumpingFilename", + "Elasticity", + "File to save results from model lumping to" + ) + if not hasattr(equation, "StabilityAnalysis"): + equation.addProperty( + "App::PropertyBool", + "StabilityAnalysis", + "Elasticity", + "If true, 'Eigen Analysis' is stability analysis.\nOtherwise modal analysis is performed." + ) + if not hasattr(equation, "UpdateTransientSystem"): + equation.addProperty( + "App::PropertyBool", + "UpdateTransientSystem", + "Elasticity", + "See Elmer manual for info" + ) + def _handleElasticityConstants(self): pass @@ -688,7 +811,7 @@ class Writer(object): density_needed = False for equation in self.solver.Group: if femutils.is_of_type(equation, "Fem::EquationElmerElasticity"): - if equation.DoFrequencyAnalysis is True: + if equation.EigenAnalysis is True: density_needed = True break # there could be a second equation without frequency gravObj = self._getSingleMember("Fem::ConstraintSelfWeight") diff --git a/src/Mod/Fem/femtest/data/elmer/box_static_0_mm.sif b/src/Mod/Fem/femtest/data/elmer/box_static_0_mm.sif index 984a0b85df..78d8e21bcd 100644 --- a/src/Mod/Fem/femtest/data/elmer/box_static_0_mm.sif +++ b/src/Mod/Fem/femtest/data/elmer/box_static_0_mm.sif @@ -9,20 +9,28 @@ Solver 1 Calculate Principal = Logical True Calculate Strains = Logical False Calculate Stresses = Logical False - Displace mesh = Logical False + Constant Bulk System = Logical False + Displace mesh = Logical True Eigen Analysis = Logical False Eigen System Values = Integer 5 Equation = String "Stress Solver" - Exec Solver = String "Always" + Fix Displacement = Logical False + Geometric Stiffness = Logical False + Incompressible = Logical False Linear System Abort Not Converged = Logical False Linear System Direct Method = String "Umfpack" Linear System Precondition Recompute = Integer 1 Linear System Residual Output = Integer 1 Linear System Solver = String "Direct" + Maxwell Material = Logical False + Model Lumping = Logical False + Model Lumping Filename = String "" Optimize Bandwidth = Logical True Procedure = File "StressSolve" "StressSolver" + Stability Analysis = Logical False Stabilize = Logical True Steady State Convergence Tolerance = Real 1e-05 + Update Transient System = Logical False Variable = String "Displacement" Variable DOFs = Integer 3 End diff --git a/src/Mod/Fem/femtest/data/elmer/ccxcantilever_faceload_0_mm.sif b/src/Mod/Fem/femtest/data/elmer/ccxcantilever_faceload_0_mm.sif index 6c1fca5982..87ec2d6ab4 100644 --- a/src/Mod/Fem/femtest/data/elmer/ccxcantilever_faceload_0_mm.sif +++ b/src/Mod/Fem/femtest/data/elmer/ccxcantilever_faceload_0_mm.sif @@ -9,20 +9,28 @@ Solver 1 Calculate Principal = Logical True Calculate Strains = Logical False Calculate Stresses = Logical False - Displace mesh = Logical False + Constant Bulk System = Logical False + Displace mesh = Logical True Eigen Analysis = Logical False Eigen System Values = Integer 5 Equation = String "Stress Solver" - Exec Solver = String "Always" + Fix Displacement = Logical False + Geometric Stiffness = Logical False + Incompressible = Logical False Linear System Abort Not Converged = Logical False Linear System Direct Method = String "Umfpack" Linear System Precondition Recompute = Integer 1 Linear System Residual Output = Integer 1 Linear System Solver = String "Direct" + Maxwell Material = Logical False + Model Lumping = Logical False + Model Lumping Filename = String "" Optimize Bandwidth = Logical True Procedure = File "StressSolve" "StressSolver" + Stability Analysis = Logical False Stabilize = Logical True Steady State Convergence Tolerance = Real 1e-05 + Update Transient System = Logical False Variable = String "Displacement" Variable DOFs = Integer 3 End diff --git a/src/Mod/Fem/femtest/data/elmer/ccxcantilever_faceload_1_si.sif b/src/Mod/Fem/femtest/data/elmer/ccxcantilever_faceload_1_si.sif index fab67202e6..d4d555741c 100644 --- a/src/Mod/Fem/femtest/data/elmer/ccxcantilever_faceload_1_si.sif +++ b/src/Mod/Fem/femtest/data/elmer/ccxcantilever_faceload_1_si.sif @@ -9,20 +9,28 @@ Solver 1 Calculate Principal = Logical True Calculate Strains = Logical False Calculate Stresses = Logical False - Displace mesh = Logical False + Constant Bulk System = Logical False + Displace mesh = Logical True Eigen Analysis = Logical False Eigen System Values = Integer 5 Equation = String "Stress Solver" - Exec Solver = String "Always" + Fix Displacement = Logical False + Geometric Stiffness = Logical False + Incompressible = Logical False Linear System Abort Not Converged = Logical False Linear System Direct Method = String "Umfpack" Linear System Precondition Recompute = Integer 1 Linear System Residual Output = Integer 1 Linear System Solver = String "Direct" + Maxwell Material = Logical False + Model Lumping = Logical False + Model Lumping Filename = String "" Optimize Bandwidth = Logical True Procedure = File "StressSolve" "StressSolver" + Stability Analysis = Logical False Stabilize = Logical True Steady State Convergence Tolerance = Real 1e-05 + Update Transient System = Logical False Variable = String "Displacement" Variable DOFs = Integer 3 End diff --git a/src/Mod/Fem/femtest/data/elmer/ccxcantilever_nodeload_0_mm.sif b/src/Mod/Fem/femtest/data/elmer/ccxcantilever_nodeload_0_mm.sif index e7d25742cd..bbde12c974 100644 --- a/src/Mod/Fem/femtest/data/elmer/ccxcantilever_nodeload_0_mm.sif +++ b/src/Mod/Fem/femtest/data/elmer/ccxcantilever_nodeload_0_mm.sif @@ -9,20 +9,28 @@ Solver 1 Calculate Principal = Logical True Calculate Strains = Logical False Calculate Stresses = Logical False - Displace mesh = Logical False + Constant Bulk System = Logical False + Displace mesh = Logical True Eigen Analysis = Logical False Eigen System Values = Integer 5 Equation = String "Stress Solver" - Exec Solver = String "Always" + Fix Displacement = Logical False + Geometric Stiffness = Logical False + Incompressible = Logical False Linear System Abort Not Converged = Logical False Linear System Direct Method = String "Umfpack" Linear System Precondition Recompute = Integer 1 Linear System Residual Output = Integer 1 Linear System Solver = String "Direct" + Maxwell Material = Logical False + Model Lumping = Logical False + Model Lumping Filename = String "" Optimize Bandwidth = Logical True Procedure = File "StressSolve" "StressSolver" + Stability Analysis = Logical False Stabilize = Logical True Steady State Convergence Tolerance = Real 1e-05 + Update Transient System = Logical False Variable = String "Displacement" Variable DOFs = Integer 3 End diff --git a/src/Mod/Fem/femtest/data/elmer/ccxcantilever_prescribeddisplacement_0_mm.sif b/src/Mod/Fem/femtest/data/elmer/ccxcantilever_prescribeddisplacement_0_mm.sif index ef7c7b0643..bb840a3520 100644 --- a/src/Mod/Fem/femtest/data/elmer/ccxcantilever_prescribeddisplacement_0_mm.sif +++ b/src/Mod/Fem/femtest/data/elmer/ccxcantilever_prescribeddisplacement_0_mm.sif @@ -9,20 +9,28 @@ Solver 1 Calculate Principal = Logical True Calculate Strains = Logical False Calculate Stresses = Logical False - Displace mesh = Logical False + Constant Bulk System = Logical False + Displace mesh = Logical True Eigen Analysis = Logical False Eigen System Values = Integer 5 Equation = String "Stress Solver" - Exec Solver = String "Always" + Fix Displacement = Logical False + Geometric Stiffness = Logical False + Incompressible = Logical False Linear System Abort Not Converged = Logical False Linear System Direct Method = String "Umfpack" Linear System Precondition Recompute = Integer 1 Linear System Residual Output = Integer 1 Linear System Solver = String "Direct" + Maxwell Material = Logical False + Model Lumping = Logical False + Model Lumping Filename = String "" Optimize Bandwidth = Logical True Procedure = File "StressSolve" "StressSolver" + Stability Analysis = Logical False Stabilize = Logical True Steady State Convergence Tolerance = Real 1e-05 + Update Transient System = Logical False Variable = String "Displacement" Variable DOFs = Integer 3 End