Isogeometric Analysis in MOOSE
This example illustrates using Isogeometric Analysis (IGA) within MOOSE framework to perform a simulation. This example simulates loads applied to a "c-frame" to determine the maximum principal stress.
Creating IGA Mesh
To create the mesh file included in this example a Coreform Cubit license is needed. Coreform Cubit is a product released and maintained by Coreform, LLC. A free to use Cubit Learn license can be acquired.
The following is not required to run the example, but is required to generate the input mesh that is included in the example. To execute the Cubit journal file in batch from the command line use the following command:
coreform_cubit -batch cframe_build.jou
Within the journal file, see Listing 1, there are unique commands that will generate a uspline on the discretized mesh.
Line 35 sets the degree and continuity of the uspline
As of this writing, the max degree supported by libMesh is 2.
All continuity must equal p-1 where p is the degree.
Line 36 constructs the uspline using the geometry as a basis.
Line 37 fits the uspline that was built to the geometry.
Listing 1: Complete Coreform Cubit file for generating IGA input mesh
import step "c-frame.step" heal
remove surface 15 17 21 19 22 23 16 25 18 20 24 26 14 35 38 33 34 36 37 7 8 4 5 6 1 2 10 12 3 9 13 11 80 77 81 88 79 86 90 78 76 89 87 75 91 85 29 28 30 27 31 32 62 60 57 58 48 45 47 50 49 46 54 53 51 56 52 55 41 39 42 43 40 44 68 66 extend
remove surface 93 extend
remove surface 94 extend
webcut volume 1 with sheet extended from surface 99 98 96 preview
webcut volume 1 with sheet extended from surface 99 98 96
webcut volume all with sheet extended from surface 92 59
webcut volume 6 4 3 5 1 2 with sheet extended from surface 67 61
webcut volume 1 16 2 15 with plane vertex 52 vertex 215 vertex 10 preview
webcut volume 1 16 2 15 with plane vertex 52 vertex 215 vertex 10
create vertex on curve 14 fraction 0.5 from start
create vertex on curve 77 fraction 0.5 from start
create vertex on curve 32 fraction 0.5 from start
webcut volume 16 2 15 with plane vertex 270 vertex 269 vertex 271
webcut volume 1 with plane vertex 270 vertex 269 vertex 271 preview
webcut volume 1 with plane vertex 270 vertex 269 vertex 271
delete Vertex 271 269 270
imprint all
merge all
volume all redistribute nodes off
volume all scheme Sweep Vector 1 0 0
volume all scheme Sweep Vector 1 0 0 sweep transform least squares
volume all autosmooth target on fixed imprints off smart smooth off
volume all size 0.5
mesh volume all
block 1 vol all
sideset 2 surf 194 203 196
sideset 3 Surface 146 155 148
block 1 element type hex27 #Quadratic FEA elements
export mesh "CFrame_FEA_05_deg2.e" overwrite #FEA Export
set uspline vol all deg 2 cont 1
build uspline vol all as 1
fit uspline 1
export uspline 1 exodus "CFrame_IGA_05"
(moose/modules/solid_mechanics/examples/cframe_iga/cframe_build.jou)MOOSE-IGA Simulation
Performing the simulation utilizing the mesh created above does not require much with respect to the MOOSE input, simply load the mesh from a file and select utilize the RATIONAL_BERNSTEIN element family as shown in Listing 2. Exporting using the VTK format (vtk = true
) input will output in a format that will capture the higher-order nature of the IGA based elements using Paraview visualization.
Listing 2: Complete input file for running example problem with IGA in MOOSE.
[GlobalParams<<<{"href": "../../../syntax/GlobalParams/index.html"}>>>]
displacements = 'disp_x disp_y disp_z'
[]
[Mesh<<<{"href": "../../../syntax/Mesh/index.html"}>>>]
[igafile]
type = FileMeshGenerator<<<{"description": "Read a mesh from a file.", "href": "../../../source/meshgenerators/FileMeshGenerator.html"}>>>
file<<<{"description": "The filename to read."}>>> = cframe_iga_coarse.e
clear_spline_nodes<<<{"description": "If clear_spline_nodes=true, IsoGeometric Analyis spline nodes and constraints are removed from an IGA mesh, after which only C^0 Rational-Bernstein-Bezier elements will remain."}>>> = true
[]
[]
[Variables<<<{"href": "../../../syntax/Variables/index.html"}>>>]
[disp_x]
order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = SECOND
family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = RATIONAL_BERNSTEIN
[]
[disp_y]
order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = SECOND
family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = RATIONAL_BERNSTEIN
[]
[disp_z]
order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = SECOND
family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = RATIONAL_BERNSTEIN
[]
[]
[Kernels<<<{"href": "../../../syntax/Kernels/index.html"}>>>]
[SolidMechanics<<<{"href": "../../../syntax/Kernels/SolidMechanics/index.html"}>>>]
#Stress divergence kernels
displacements<<<{"description": "The nonlinear displacement variables for the problem"}>>> = 'disp_x disp_y disp_z'
[]
[]
[AuxVariables<<<{"href": "../../../syntax/AuxVariables/index.html"}>>>]
[von_mises]
#Dependent variable used to visualize the von Mises stress
order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = SECOND
family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
[]
[Max_Princ]
#Dependent variable used to visualize the Hoop stress
order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = SECOND
family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
[]
[stress_xx]
order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = SECOND
family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
[]
[stress_yy]
order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = SECOND
family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
[]
[stress_zz]
order<<<{"description": "Specifies the order of the FE shape function to use for this variable (additional orders not listed are allowed)"}>>> = SECOND
family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = MONOMIAL
[]
[]
[AuxKernels<<<{"href": "../../../syntax/AuxKernels/index.html"}>>>]
[von_mises_kernel]
#Calculates the von mises stress and assigns it to von_mises
type = RankTwoScalarAux<<<{"description": "Compute a scalar property of a RankTwoTensor", "href": "../../../source/auxkernels/RankTwoScalarAux.html"}>>>
variable<<<{"description": "The name of the variable that this object applies to"}>>> = von_mises
rank_two_tensor<<<{"description": "The rank two material tensor name"}>>> = stress
scalar_type<<<{"description": "Type of scalar output"}>>> = VonMisesStress
[]
[MaxPrin]
type = RankTwoScalarAux<<<{"description": "Compute a scalar property of a RankTwoTensor", "href": "../../../source/auxkernels/RankTwoScalarAux.html"}>>>
variable<<<{"description": "The name of the variable that this object applies to"}>>> = Max_Princ
rank_two_tensor<<<{"description": "The rank two material tensor name"}>>> = stress
scalar_type<<<{"description": "Type of scalar output"}>>> = MaxPrincipal
[]
[stress_xx]
type = RankTwoAux<<<{"description": "Access a component of a RankTwoTensor", "href": "../../../source/auxkernels/RankTwoAux.html"}>>>
index_i<<<{"description": "The index i of ij for the tensor to output (0, 1, 2)"}>>> = 0
index_j<<<{"description": "The index j of ij for the tensor to output (0, 1, 2)"}>>> = 0
rank_two_tensor<<<{"description": "The rank two material tensor name"}>>> = stress
variable<<<{"description": "The name of the variable that this object applies to"}>>> = stress_xx
[]
[stress_yy]
type = RankTwoAux<<<{"description": "Access a component of a RankTwoTensor", "href": "../../../source/auxkernels/RankTwoAux.html"}>>>
index_i<<<{"description": "The index i of ij for the tensor to output (0, 1, 2)"}>>> = 1
index_j<<<{"description": "The index j of ij for the tensor to output (0, 1, 2)"}>>> = 1
rank_two_tensor<<<{"description": "The rank two material tensor name"}>>> = stress
variable<<<{"description": "The name of the variable that this object applies to"}>>> = stress_yy
[]
[stress_zz]
type = RankTwoAux<<<{"description": "Access a component of a RankTwoTensor", "href": "../../../source/auxkernels/RankTwoAux.html"}>>>
index_i<<<{"description": "The index i of ij for the tensor to output (0, 1, 2)"}>>> = 2
index_j<<<{"description": "The index j of ij for the tensor to output (0, 1, 2)"}>>> = 2
rank_two_tensor<<<{"description": "The rank two material tensor name"}>>> = stress
variable<<<{"description": "The name of the variable that this object applies to"}>>> = stress_zz
[]
[]
[BCs<<<{"href": "../../../syntax/BCs/index.html"}>>>]
[Pressure<<<{"href": "../../../syntax/BCs/Pressure/index.html"}>>>]
[load]
#Applies the pressure
boundary<<<{"description": "The list of boundary IDs from the mesh where the pressure will be applied"}>>> = '3'
factor<<<{"description": "The factor to use in computing the pressure"}>>> = 2000 # psi
[]
[]
[anchor_x]
#Anchors the bottom and sides against deformation in the x-direction
type = DirichletBC<<<{"description": "Imposes the essential boundary condition $u=g$, where $g$ is a constant, controllable value.", "href": "../../../source/bcs/DirichletBC.html"}>>>
variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = disp_x
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = '2'
value<<<{"description": "Value of the BC"}>>> = 0.0
[]
[anchor_y]
#Anchors the bottom and sides against deformation in the y-direction
type = DirichletBC<<<{"description": "Imposes the essential boundary condition $u=g$, where $g$ is a constant, controllable value.", "href": "../../../source/bcs/DirichletBC.html"}>>>
variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = disp_y
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = '2'
value<<<{"description": "Value of the BC"}>>> = 0.0
[]
[anchor_z]
#Anchors the bottom and sides against deformation in the z-direction
type = DirichletBC<<<{"description": "Imposes the essential boundary condition $u=g$, where $g$ is a constant, controllable value.", "href": "../../../source/bcs/DirichletBC.html"}>>>
variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = disp_z
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = '2'
value<<<{"description": "Value of the BC"}>>> = 0.0
[]
[]
[Materials<<<{"href": "../../../syntax/Materials/index.html"}>>>]
[elasticity_tensor_AL]
#Creates the elasticity tensor using concrete parameters
youngs_modulus<<<{"description": "Young's modulus of the material."}>>> = 24e6 #psi
poissons_ratio<<<{"description": "Poisson's ratio for the material."}>>> = 0.33
type = ComputeIsotropicElasticityTensor<<<{"description": "Compute a constant isotropic elasticity tensor.", "href": "../../../source/materials/ComputeIsotropicElasticityTensor.html"}>>>
[]
[strain]
#Computes the strain, assuming small strains
type = ComputeSmallStrain<<<{"description": "Compute a small strain.", "href": "../../../source/materials/ComputeSmallStrain.html"}>>>
displacements<<<{"description": "The displacements appropriate for the simulation geometry and coordinate system"}>>> = 'disp_x disp_y disp_z'
[]
[stress]
#Computes the stress, using linear elasticity
type = ComputeLinearElasticStress<<<{"description": "Compute stress using elasticity for small strains", "href": "../../../source/materials/ComputeLinearElasticStress.html"}>>>
[]
[density_AL]
#Defines the density of steel
type = GenericConstantMaterial<<<{"description": "Declares material properties based on names and values prescribed by input parameters.", "href": "../../../source/materials/GenericConstantMaterial.html"}>>>
prop_names<<<{"description": "The names of the properties this material will have"}>>> = density
prop_values<<<{"description": "The values associated with the named properties"}>>> = 6.99e-4 # lbm/in^3
[]
[]
[Preconditioning<<<{"href": "../../../syntax/Preconditioning/index.html"}>>>]
[SMP]
#Creates the entire Jacobian, for the Newton solve
type = SMP<<<{"description": "Single matrix preconditioner (SMP) builds a preconditioner using user defined off-diagonal parts of the Jacobian.", "href": "../../../source/preconditioners/SingleMatrixPreconditioner.html"}>>>
full<<<{"description": "Set to true if you want the full set of couplings between variables simply for convenience so you don't have to set every off_diag_row and off_diag_column combination."}>>> = true
[]
[]
[Postprocessors<<<{"href": "../../../syntax/Postprocessors/index.html"}>>>]
[max_principal_stress]
type = PointValue<<<{"description": "Compute the value of a variable at a specified location", "href": "../../../source/postprocessors/PointValue.html"}>>>
point<<<{"description": "The physical point where the solution will be evaluated."}>>> = '0.000000 -1.500000 -4.3'
variable<<<{"description": "The name of the variable that this postprocessor operates on."}>>> = Max_Princ
use_displaced_mesh<<<{"description": "Whether or not this object should use the displaced mesh for computation. Note that in the case this is true but no displacements are provided in the Mesh block the undisplaced mesh will still be used."}>>> = false
[]
[maxPrincStress]
type = ElementExtremeValue<<<{"description": "Finds either the min or max elemental value of a variable over the domain.", "href": "../../../source/postprocessors/ElementExtremeValue.html"}>>>
variable<<<{"description": "The name of the variable that this postprocessor operates on"}>>> = Max_Princ
[]
[]
[Executioner<<<{"href": "../../../syntax/Executioner/index.html"}>>>]
# We solve a steady state problem using Newton's iteration
type = Steady
solve_type = NEWTON
nl_rel_tol = 1e-9
l_max_its = 300
l_tol = 1e-4
nl_max_its = 30
petsc_options_iname = '-pc_type -pc_hypre_type -ksp_gmres_restart'
petsc_options_value = 'hypre boomeramg 31'
[]
[Outputs<<<{"href": "../../../syntax/Outputs/index.html"}>>>]
vtk<<<{"description": "Output the results using the default settings for VTKOutput output"}>>> = true
[]
(moose/modules/solid_mechanics/examples/cframe_iga/cframe_iga.i)
Figure 1: Maximum principal stress for "c-frame" example utilizing IGA in MOOSE.