diff --git a/examples/ahead/nonoverlap/bracket/bracket-1.g b/examples/ahead/nonoverlap/bracket/bracket-1.g new file mode 100644 index 00000000..cdccc5c1 Binary files /dev/null and b/examples/ahead/nonoverlap/bracket/bracket-1.g differ diff --git a/examples/ahead/nonoverlap/bracket/bracket-2.g b/examples/ahead/nonoverlap/bracket/bracket-2.g new file mode 100644 index 00000000..fdc975a5 Binary files /dev/null and b/examples/ahead/nonoverlap/bracket/bracket-2.g differ diff --git a/examples/ahead/nonoverlap/bracket/bracket-tet-tet2.jou b/examples/ahead/nonoverlap/bracket/bracket-tet-tet2.jou new file mode 100644 index 00000000..13941ba6 --- /dev/null +++ b/examples/ahead/nonoverlap/bracket/bracket-tet-tet2.jou @@ -0,0 +1,81 @@ +reset +#left part of Omega +brick x 0.2 y 0.2 z 0.01 +#movie volume 1 -2 -2 0 +create Cylinder height 1 radius 0.075 +#move Volume 2 midpoint location curve 9 include_merged +subtract volume 2 from volume 1 +brick x 0.01 y 0.2 z 0.2 +#move Volume 3 midpoint location curve 8 include_merged +volume 3 move -0.1 0 0 +unite volume 1 volume 3 + +webcut volume 1 with plane xplane offset 0.0 + + +delete volume 1 + +block 1 volume all +block 1 name 'left' + +sideset 1 surface 32 33 +sideset 1 name "left-frontSS" + +nodeset 1 surface 16 +nodeset 1 name "left-backNS" +nodeset 2 surface 32 33 +nodeset 2 name "left-frontNS" +nodeset 3 volume all +nodeset 3 name "left-nsall" + +volume all scheme Tetmesh +volume 4 size auto factor 7 +#volume all size auto factor 10 +block 1 element type TETRA4 +mesh volume all +#refine volume all numsplit 1 +export mesh "bracket-1.g" overwrite + +reset +#right part of Omega +brick x 0.2 y 0.2 z 0.01 +#movie volume 1 -2 -2 0 +create Cylinder height 1 radius 0.075 +#move Volume 2 midpoint location curve 9 include_merged +subtract volume 2 from volume 1 +brick x 0.01 y 0.2 z 0.2 +#move Volume 3 midpoint location curve 8 include_merged +volume 3 move -0.1 0 0 +unite volume 1 volume 3 + +webcut volume 1 with plane xplane offset 0.0 +delete volume 4 + +block 1 volume all +block 1 name 'right' + +sideset 1 surface 26 25 +sideset 1 name "right-backSS" + +nodeset 1 surface 26 25 +nodeset 1 name "right-backNS" +nodeset 2 surface 6 +nodeset 2 name "right-frontNS" +nodeset 3 volume all +nodeset 3 name "right-nsall" + +volume all scheme Tetmesh +volume all size auto factor 7 +#volume all size auto factor 14 +block 1 element type TETRA4 +mesh volume all +refine volume all numsplit 1 +export mesh "bracket-2.g" overwrite + + + + + + + + diff --git a/examples/ahead/nonoverlap/bracket/dynamic/bracket-1.yaml b/examples/ahead/nonoverlap/bracket/dynamic/bracket-1.yaml new file mode 100644 index 00000000..c9c5d35b --- /dev/null +++ b/examples/ahead/nonoverlap/bracket/dynamic/bracket-1.yaml @@ -0,0 +1,40 @@ +type: single +input mesh file: ../bracket-1.g +output mesh file: bracket-1.e +model: + type: solid mechanics + material: + blocks: + left: hyperelastic + hyperelastic: + model: neohookean + elastic modulus: 200.0e+09 + Poisson's ratio: 0.25 + density: 7800.0 +time integrator: + type: Newmark + β: 0.49 + γ: 0.9 +boundary conditions: + Dirichlet: + - node set: left-backNS + component: x + function: "0.0" + - node set: left-backNS + component: y + function: "0.0" + - node set: left-backNS + component: z + function: "0.0" + Schwarz nonoverlap: + - side set: left-frontSS + source: bracket-2 + source block: right + source side set: right-backSS +solver: + type: Hessian minimizer + step: full Newton + minimum iterations: 1 + maximum iterations: 16 + relative tolerance: 1.0e-10 + absolute tolerance: 1.0e-06 diff --git a/examples/ahead/nonoverlap/bracket/dynamic/bracket-2.yaml b/examples/ahead/nonoverlap/bracket/dynamic/bracket-2.yaml new file mode 100644 index 00000000..2a6b0906 --- /dev/null +++ b/examples/ahead/nonoverlap/bracket/dynamic/bracket-2.yaml @@ -0,0 +1,41 @@ +type: single +input mesh file: ../bracket-2.g +output mesh file: bracket-2.e +model: + type: solid mechanics + material: + blocks: + right: hyperelastic + hyperelastic: + model: neohookean + elastic modulus: 200.0e+09 + Poisson's ratio: 0.25 + density: 7800.0 +time integrator: + type: Newmark + β: 0.49 + γ: 0.9 +initial conditions: + velocity: + - node set: right-nsall + component: x + function: "0.0" + - node set: right-nsall + component: y + function: "0.0" + - node set: right-nsall + component: z + function: "ifelse(x > 0.099, 100.0, 0.0)" +boundary conditions: + Schwarz nonoverlap: + - side set: right-backSS + source: bracket-1 + source block: left + source side set: left-frontSS +solver: + type: Hessian minimizer + step: full Newton + minimum iterations: 1 + maximum iterations: 16 + relative tolerance: 1.0e-10 + absolute tolerance: 1.0e-06 diff --git a/examples/ahead/nonoverlap/bracket/dynamic/bracket.yaml b/examples/ahead/nonoverlap/bracket/dynamic/bracket.yaml new file mode 100644 index 00000000..81e83fb9 --- /dev/null +++ b/examples/ahead/nonoverlap/bracket/dynamic/bracket.yaml @@ -0,0 +1,13 @@ +type: multi +domains: ["bracket-1.yaml", "bracket-2.yaml"] +Exodus output interval: 1 +CSV output interval: 0 +initial time: 0.0 +final time: 2.5e-3 +#final time: 20.0e-3 #original final time +time step: 1.0e-6 +minimum iterations: 1 +maximum iterations: 128 +relative tolerance: 1.0e-06 +absolute tolerance: 1.0e-06 +relaxation parameter: 0.2 diff --git a/examples/ahead/nonoverlap/clamped/clamped-1.g b/examples/ahead/nonoverlap/clamped/clamped-1.g new file mode 100644 index 00000000..92937f2b Binary files /dev/null and b/examples/ahead/nonoverlap/clamped/clamped-1.g differ diff --git a/examples/ahead/nonoverlap/clamped/clamped-2.g b/examples/ahead/nonoverlap/clamped/clamped-2.g new file mode 100644 index 00000000..e4599007 Binary files /dev/null and b/examples/ahead/nonoverlap/clamped/clamped-2.g differ diff --git a/examples/ahead/nonoverlap/laser-weld/gauge.g b/examples/ahead/nonoverlap/laser-weld/gauge.g new file mode 100644 index 00000000..e5a42d5f Binary files /dev/null and b/examples/ahead/nonoverlap/laser-weld/gauge.g differ diff --git a/examples/ahead/nonoverlap/laser-weld/holder-0.g b/examples/ahead/nonoverlap/laser-weld/holder-0.g new file mode 100644 index 00000000..c4254d83 Binary files /dev/null and b/examples/ahead/nonoverlap/laser-weld/holder-0.g differ diff --git a/examples/ahead/nonoverlap/laser-weld/holder-1.g b/examples/ahead/nonoverlap/laser-weld/holder-1.g new file mode 100644 index 00000000..f296d6ac Binary files /dev/null and b/examples/ahead/nonoverlap/laser-weld/holder-1.g differ diff --git a/examples/ahead/nonoverlap/plate/dynamic/plate-1.yaml b/examples/ahead/nonoverlap/plate/dynamic/plate-1.yaml index c7d3297a..f6fe5c25 100644 --- a/examples/ahead/nonoverlap/plate/dynamic/plate-1.yaml +++ b/examples/ahead/nonoverlap/plate/dynamic/plate-1.yaml @@ -13,8 +13,8 @@ model: density: 7800.0 time integrator: type: Newmark - β: 0.25 - γ: 0.5 + β: 0.49 + γ: 0.9 boundary conditions: Dirichlet: - node set: nsx- diff --git a/examples/ahead/nonoverlap/plate/dynamic/plate-2.yaml b/examples/ahead/nonoverlap/plate/dynamic/plate-2.yaml index 1a819526..3e1eb52b 100644 --- a/examples/ahead/nonoverlap/plate/dynamic/plate-2.yaml +++ b/examples/ahead/nonoverlap/plate/dynamic/plate-2.yaml @@ -13,8 +13,8 @@ model: density: 7800.0 time integrator: type: Newmark - β: 0.25 - γ: 0.5 + β: 0.49 + γ: 0.9 initial conditions: velocity: - node set: nsall diff --git a/examples/ahead/nonoverlap/plate/dynamic/plate.yaml b/examples/ahead/nonoverlap/plate/dynamic/plate.yaml index d6824b68..a7b6909d 100644 --- a/examples/ahead/nonoverlap/plate/dynamic/plate.yaml +++ b/examples/ahead/nonoverlap/plate/dynamic/plate.yaml @@ -9,4 +9,4 @@ minimum iterations: 1 maximum iterations: 128 relative tolerance: 1.0e-12 absolute tolerance: 1.0e-08 -relaxation parameter: 0.4 +relaxation parameter: 0.1 diff --git a/examples/ahead/nonoverlap/plate/plate-1.g b/examples/ahead/nonoverlap/plate/plate-1.g new file mode 100644 index 00000000..c8ab063c Binary files /dev/null and b/examples/ahead/nonoverlap/plate/plate-1.g differ diff --git a/examples/ahead/nonoverlap/plate/plate-2.g b/examples/ahead/nonoverlap/plate/plate-2.g new file mode 100644 index 00000000..065a3e37 Binary files /dev/null and b/examples/ahead/nonoverlap/plate/plate-2.g differ diff --git a/examples/ahead/nonoverlap/plate/plate.jou b/examples/ahead/nonoverlap/plate/plate.jou index 4ced619e..44945bf8 100644 --- a/examples/ahead/nonoverlap/plate/plate.jou +++ b/examples/ahead/nonoverlap/plate/plate.jou @@ -1,7 +1,7 @@ ${side = 0.2} ${height = 0.03} ${overlap_vol_frac = 0.0} -${h_fine = 0.01} +${h_fine = 0.05} ${h_coarse = 0.01} ${area = side * height} diff --git a/examples/ahead/nonoverlap/torsion/torsion-1.g b/examples/ahead/nonoverlap/torsion/torsion-1.g new file mode 100644 index 00000000..7e66c1c8 Binary files /dev/null and b/examples/ahead/nonoverlap/torsion/torsion-1.g differ diff --git a/examples/ahead/nonoverlap/torsion/torsion-2.g b/examples/ahead/nonoverlap/torsion/torsion-2.g new file mode 100644 index 00000000..26293f32 Binary files /dev/null and b/examples/ahead/nonoverlap/torsion/torsion-2.g differ diff --git a/examples/ahead/overlap/bracket/bracket-1-hex.g b/examples/ahead/overlap/bracket/bracket-1-hex.g new file mode 100644 index 00000000..cde5fee5 Binary files /dev/null and b/examples/ahead/overlap/bracket/bracket-1-hex.g differ diff --git a/examples/ahead/overlap/bracket/bracket-1-tet.g b/examples/ahead/overlap/bracket/bracket-1-tet.g new file mode 100644 index 00000000..f1899fb1 Binary files /dev/null and b/examples/ahead/overlap/bracket/bracket-1-tet.g differ diff --git a/examples/ahead/overlap/bracket/bracket-1.g b/examples/ahead/overlap/bracket/bracket-1.g new file mode 100644 index 00000000..57971cf7 Binary files /dev/null and b/examples/ahead/overlap/bracket/bracket-1.g differ diff --git a/examples/ahead/overlap/bracket/bracket-2-tet.g b/examples/ahead/overlap/bracket/bracket-2-tet.g new file mode 100644 index 00000000..c5222eff Binary files /dev/null and b/examples/ahead/overlap/bracket/bracket-2-tet.g differ diff --git a/examples/ahead/overlap/bracket/bracket-2.g b/examples/ahead/overlap/bracket/bracket-2.g new file mode 100644 index 00000000..34302ed0 Binary files /dev/null and b/examples/ahead/overlap/bracket/bracket-2.g differ diff --git a/examples/ahead/overlap/bracket/dynamic/bracket-1.yaml b/examples/ahead/overlap/bracket/dynamic/bracket-1.yaml index a5e9bbbf..25d11713 100644 --- a/examples/ahead/overlap/bracket/dynamic/bracket-1.yaml +++ b/examples/ahead/overlap/bracket/dynamic/bracket-1.yaml @@ -13,8 +13,8 @@ model: density: 7800.0 time integrator: type: Newmark - β: 0.25 - γ: 0.5 + β: 0.49 + γ: 0.9 boundary conditions: Dirichlet: - node set: left-backNS diff --git a/examples/ahead/overlap/bracket/dynamic/bracket-2.yaml b/examples/ahead/overlap/bracket/dynamic/bracket-2.yaml index ca0feac3..06df6e7a 100644 --- a/examples/ahead/overlap/bracket/dynamic/bracket-2.yaml +++ b/examples/ahead/overlap/bracket/dynamic/bracket-2.yaml @@ -13,8 +13,8 @@ model: density: 7800.0 time integrator: type: Newmark - β: 0.25 - γ: 0.5 + β: 0.49 + γ: 0.9 initial conditions: velocity: - node set: right-nsall diff --git a/examples/ahead/overlap/bracket/dynamic/bracket.yaml b/examples/ahead/overlap/bracket/dynamic/bracket.yaml index 3be4d7c7..5fcad544 100644 --- a/examples/ahead/overlap/bracket/dynamic/bracket.yaml +++ b/examples/ahead/overlap/bracket/dynamic/bracket.yaml @@ -7,6 +7,6 @@ final time: 2.5e-3 #final time: 20.0e-3 #original final time time step: 1.0e-6 minimum iterations: 1 -maximum iterations: 16 -relative tolerance: 1.0e-12 -absolute tolerance: 1.0e-08 +maximum iterations: 128 +relative tolerance: 1.0e-10 +absolute tolerance: 1.0e-06 diff --git a/examples/ahead/overlap/clamped/clamped-1.g b/examples/ahead/overlap/clamped/clamped-1.g new file mode 100644 index 00000000..5723b7c9 Binary files /dev/null and b/examples/ahead/overlap/clamped/clamped-1.g differ diff --git a/examples/ahead/overlap/clamped/clamped-2.g b/examples/ahead/overlap/clamped/clamped-2.g new file mode 100644 index 00000000..7699d384 Binary files /dev/null and b/examples/ahead/overlap/clamped/clamped-2.g differ diff --git a/examples/ahead/overlap/laser-weld/dynamic-opinf-fom/clamped/holder-0.yaml b/examples/ahead/overlap/laser-weld/dynamic-opinf-fom/clamped/holder-0.yaml index 856c615d..fd802ea6 100644 --- a/examples/ahead/overlap/laser-weld/dynamic-opinf-fom/clamped/holder-0.yaml +++ b/examples/ahead/overlap/laser-weld/dynamic-opinf-fom/clamped/holder-0.yaml @@ -24,7 +24,7 @@ boundary conditions: function: "0.0" - node set: nodeset_negative_y component: y - function: "-0.1 * t" + function: "-0.1 * (0.5 - 0.5 * cos(pi * t))" - node set: nodeset_negative_y component: z function: "0.0" diff --git a/examples/ahead/overlap/laser-weld/dynamic-opinf-fom/clamped/holder-1.yaml b/examples/ahead/overlap/laser-weld/dynamic-opinf-fom/clamped/holder-1.yaml index 40f0fdee..8b430402 100644 --- a/examples/ahead/overlap/laser-weld/dynamic-opinf-fom/clamped/holder-1.yaml +++ b/examples/ahead/overlap/laser-weld/dynamic-opinf-fom/clamped/holder-1.yaml @@ -24,7 +24,7 @@ boundary conditions: function: "0.0" - node set: nodeset_positive_y component: y - function: "0.1 * t" + function: "0.1 * (0.5 - 0.5 * cos(pi * t))" - node set: nodeset_positive_y component: z function: "0.0" diff --git a/examples/ahead/overlap/laser-weld/dynamic-opinf-rom/clamped/gauge.yaml b/examples/ahead/overlap/laser-weld/dynamic-opinf-rom/clamped/gauge.yaml index 59d14401..d0eef240 100644 --- a/examples/ahead/overlap/laser-weld/dynamic-opinf-rom/clamped/gauge.yaml +++ b/examples/ahead/overlap/laser-weld/dynamic-opinf-rom/clamped/gauge.yaml @@ -18,6 +18,13 @@ time integrator: β: 0.25 γ: 0.5 boundary conditions: + Dirichlet: + - node set: nodeset_negative_y + component: x + function: "0.0" + - node set: nodeset_negative_y + component: z + function: "0.0" Schwarz overlap: - side set: sideset_negative_y source: holder-0 diff --git a/examples/ahead/overlap/laser-weld/dynamic-opinf-rom/clamped/holder-0.yaml b/examples/ahead/overlap/laser-weld/dynamic-opinf-rom/clamped/holder-0.yaml index f468781a..0f3b0343 100644 --- a/examples/ahead/overlap/laser-weld/dynamic-opinf-rom/clamped/holder-0.yaml +++ b/examples/ahead/overlap/laser-weld/dynamic-opinf-rom/clamped/holder-0.yaml @@ -17,15 +17,15 @@ time integrator: γ: 0.5 boundary conditions: Dirichlet: - - node set: nodeset_negative_y - component: x - function: "0.0" + #- node set: nodeset_negative_y + # component: x + # function: "0.0" - node set: nodeset_negative_y component: y - function: "-0.1 * t" - - node set: nodeset_negative_y - component: z - function: "0.0" + function: "-0.1 * (0.5 - 0.5 * cos(pi * t))" + #- node set: nodeset_negative_y + #component: z + #function: "0.0" Schwarz overlap: - side set: sideset_positive_y source: gauge diff --git a/examples/ahead/overlap/laser-weld/dynamic-opinf-rom/clamped/holder-1.yaml b/examples/ahead/overlap/laser-weld/dynamic-opinf-rom/clamped/holder-1.yaml index 7b4c37ea..4c150244 100644 --- a/examples/ahead/overlap/laser-weld/dynamic-opinf-rom/clamped/holder-1.yaml +++ b/examples/ahead/overlap/laser-weld/dynamic-opinf-rom/clamped/holder-1.yaml @@ -18,15 +18,15 @@ time integrator: γ: 0.5 boundary conditions: Dirichlet: - - node set: nodeset_positive_y - component: x - function: "0.0" + #- node set: nodeset_positive_y + # component: x + # function: "0.0" - node set: nodeset_positive_y component: y - function: "0.1 * t" - - node set: nodeset_positive_y - component: z - function: "0.0" + function: "0.1 * (0.5 - 0.5 * cos(pi * t))" + #- node set: nodeset_positive_y + #component: z + #function: "0.0" Schwarz overlap: - side set: sideset_negative_y source: gauge diff --git a/examples/ahead/overlap/laser-weld/dynamic-opinf-rom/clamped/laser-weld.yaml b/examples/ahead/overlap/laser-weld/dynamic-opinf-rom/clamped/laser-weld.yaml index 9737144d..93bec8a5 100644 --- a/examples/ahead/overlap/laser-weld/dynamic-opinf-rom/clamped/laser-weld.yaml +++ b/examples/ahead/overlap/laser-weld/dynamic-opinf-rom/clamped/laser-weld.yaml @@ -3,8 +3,8 @@ domains: ["holder-0.yaml", "gauge.yaml", "holder-1.yaml"] Exodus output interval: 1 initial time: 0.0 final time: 0.1 -time step: 0.001 +time step: 0.0001 minimum iterations: 1 maximum iterations: 64 -relative tolerance: 1.0e-10 -absolute tolerance: 1.0e-06 +relative tolerance: 1.0e-07 +absolute tolerance: 1.0e-05 diff --git a/examples/ahead/overlap/notched-cylinder/dynamic-opinf-fom/notched-cylinder-1.g b/examples/ahead/overlap/notched-cylinder/dynamic-opinf-fom/notched-cylinder-1.g deleted file mode 100644 index 87f9f032..00000000 Binary files a/examples/ahead/overlap/notched-cylinder/dynamic-opinf-fom/notched-cylinder-1.g and /dev/null differ diff --git a/examples/ahead/overlap/notched-cylinder/dynamic-opinf-fom/notched-cylinder-1.yaml b/examples/ahead/overlap/notched-cylinder/dynamic-opinf-fom/notched-cylinder-1.yaml index 9f79f01b..b575fcfb 100644 --- a/examples/ahead/overlap/notched-cylinder/dynamic-opinf-fom/notched-cylinder-1.yaml +++ b/examples/ahead/overlap/notched-cylinder/dynamic-opinf-fom/notched-cylinder-1.yaml @@ -1,5 +1,5 @@ type: single -input mesh file: notched-cylinder-1.g +input mesh file: ../notched-cylinder-1.g output mesh file: notched-cylinder-1.e CSV output interval: 1 CSV write sidesets: true diff --git a/examples/ahead/overlap/notched-cylinder/dynamic-opinf-fom/notched-cylinder-2.g b/examples/ahead/overlap/notched-cylinder/dynamic-opinf-fom/notched-cylinder-2.g deleted file mode 100644 index 69c1eca1..00000000 Binary files a/examples/ahead/overlap/notched-cylinder/dynamic-opinf-fom/notched-cylinder-2.g and /dev/null differ diff --git a/examples/ahead/overlap/notched-cylinder/dynamic-opinf-fom/notched-cylinder-2.yaml b/examples/ahead/overlap/notched-cylinder/dynamic-opinf-fom/notched-cylinder-2.yaml index 19b95548..9ba86466 100644 --- a/examples/ahead/overlap/notched-cylinder/dynamic-opinf-fom/notched-cylinder-2.yaml +++ b/examples/ahead/overlap/notched-cylinder/dynamic-opinf-fom/notched-cylinder-2.yaml @@ -1,5 +1,5 @@ type: single -input mesh file: notched-cylinder-2.g +input mesh file: ../notched-cylinder-2.g output mesh file: notched-cylinder-2.e CSV output interval: 1 CSV write sidesets: true @@ -37,6 +37,7 @@ boundary conditions: source: notched-cylinder-1 source side set: +Z_bottomSS source block: fine + search tolerance: 5.0e-02 solver: type: Hessian minimizer step: full Newton diff --git a/examples/ahead/overlap/notched-cylinder/dynamic-opinf-fom/notched-cylinder-hex.jou b/examples/ahead/overlap/notched-cylinder/dynamic-opinf-fom/notched-cylinder-hex.jou deleted file mode 100644 index 2392db49..00000000 --- a/examples/ahead/overlap/notched-cylinder/dynamic-opinf-fom/notched-cylinder-hex.jou +++ /dev/null @@ -1,112 +0,0 @@ -reset -logging off -${set_warning_count(0)} - -${radius = 0.032} -${height = 0.064} -${neck_radius = 0.016} -${core_radius = 0.012} -${notch_radius = 0.008} -${overlap = 0.016} -${coarse_height = 0.048} -${fine_height = height - coarse_height + overlap} -${offset = fine_height + (coarse_height - overlap)/ 2.0} -${h_fine = 0.006} -${h_coarse = h_fine} -${intervals = 16} -${refinement_level = 1} - -create cylinder radius {radius} z {2.0 * (fine_height - overlap)} -create brick x {2.0 * radius} y {2.0 * radius} z {2.0 * notch_radius} -webcut volume 2 cylinder radius {neck_radius + notch_radius} axis z -delete volume 3 -create torus major {neck_radius + notch_radius} minor {notch_radius} -unite volume 2 4 -subtract volume 2 from volume 1 -webcut volume 1 with plane zplane -delete volume 5 -create cylinder radius {radius} z {overlap} -move volume 6 z {fine_height - overlap / 2.0} include_merged -create cylinder radius {radius} z {coarse_height - overlap} -move volume 7 z {offset} include_merged -webcut volume 1 with plane xplane -delete volume 8 -webcut volume 1 with plane yplane -delete volume 1 -webcut volume 7 with plane xplane -delete volume 10 -webcut volume 7 with plane yplane -delete volume 7 -webcut volume 9 with cylinder radius {core_radius} axis z center 0 0 0 -webcut volume 6 with plane xplane -delete volume 13 -webcut volume 6 with plane yplane -delete volume 6 -webcut volume 11 with cylinder radius {core_radius} axis z center 0 0 0 -webcut volume 14 with cylinder radius {core_radius} axis z center 0 0 0 -imprint volume 9 12 14 16 -merge volume 9 12 14 16 -surface 80 size {h_fine} -surface 80 scheme pave -surface 80 smooth scheme laplacian -mesh surface 80 -curve 108 71 72 76 75 106 interval {intervals} -mesh volume 9 -surface 83 size {h_fine} -surface 83 scheme pave -mesh surface 83 -volume 12 scheme sweep source surface 83 target surface 86 sweep_smooth linear sweep_transform translate propagate_bias autosmooth_target off -mesh volume 12 -block 1 volume 9 12 14 16 -surface 118 size {h_fine} -surface 118 scheme pave -surface 118 smooth scheme laplacian -mesh surface 118 -curve 106 75 166 148 interval {intervals} -mesh volume 14 -volume 16 scheme sweep source surface 86 target surface 124 sweep_smooth linear sweep_transform translate propagate_bias autosmooth_target off -mesh volume 16 -volume 14 copy 0 0 0 -volume 16 copy 0 0 0 -imprint volume 11 15 17 18 -merge volume 11 15 17 18 -surface 108 size {h_coarse} -surface 108 scheme pave -surface 108 smooth scheme laplacian -mesh surface 108 -curve 150 104 interval {intervals} -mesh volume 11 -volume 15 scheme sweep source surface 111 target surface 114 sweep_smooth linear sweep_transform translate propagate_bias autosmooth_target off -mesh volume 15 -refine volume 9 12 14 16 numsplit {refinement_level} -block 2 volume 11 15 17 18 -block 1 name "fine" -block 2 name "coarse" -nodeset 1 surface 81 83 #bottom of bottom domain -nodeset 1 name "-Z_bottom" -nodeset 2 surface 124 117 #top of bottom domain -nodeset 2 name "+Z_bottom" -nodeset 3 surface 84 80 118 122 #parallel in x, bottom domain -nodeset 3 name "-Y_bottom" -nodeset 4 surface 85 78 116 123 #parallel in y, bottom domain -nodeset 4 name "-X_bottom" -nodeset 5 surface 129 132 #bottom of top domain -nodeset 5 name "-Z_top" -nodeset 6 surface 107 114 #top of top domain -nodeset 6 name "+Z_top" -nodeset 7 surface 134 113 106 126 #parallel in y, top domain -nodeset 7 name "-X_top" -nodeset 8 surface 112 108 128 133 #parallel in x, top domain -nodeset 8 name "-Y_top" -sideset 1 surface 81 83 #bottom of bottom domain -sideset 1 name "-Z_bottomSS" -sideset 2 surface 124 117 #top of bottom domain -sideset 2 name "+Z_bottomSS" -sideset 5 surface 129 132 #bottom of top domain -sideset 5 name "-Z_topSS" -sideset 6 surface 107 114 #top of top domain -sideset 6 name "+Z_topSS" -set large exodus file off -export mesh "notched-cylinder-1.g" block 1 overwrite -export mesh "notched-cylinder-2.g" block 2 overwrite - diff --git a/examples/ahead/overlap/notched-cylinder/notched-cylinder-1-tet10.g b/examples/ahead/overlap/notched-cylinder/notched-cylinder-1-tet10.g index facd89fd..c3bf305b 100644 Binary files a/examples/ahead/overlap/notched-cylinder/notched-cylinder-1-tet10.g and b/examples/ahead/overlap/notched-cylinder/notched-cylinder-1-tet10.g differ diff --git a/examples/ahead/overlap/plate/dynamic/plate-1.yaml b/examples/ahead/overlap/plate/dynamic/plate-1.yaml index aa34ac6b..661e2f28 100644 --- a/examples/ahead/overlap/plate/dynamic/plate-1.yaml +++ b/examples/ahead/overlap/plate/dynamic/plate-1.yaml @@ -13,8 +13,8 @@ model: density: 7800.0 time integrator: type: Newmark - β: 0.25 - γ: 0.5 + β: 0.49 + γ: 0.9 boundary conditions: Dirichlet: - node set: nsx- diff --git a/examples/ahead/overlap/plate/dynamic/plate-2.yaml b/examples/ahead/overlap/plate/dynamic/plate-2.yaml index ffcc114c..09356c7f 100644 --- a/examples/ahead/overlap/plate/dynamic/plate-2.yaml +++ b/examples/ahead/overlap/plate/dynamic/plate-2.yaml @@ -13,8 +13,8 @@ model: density: 7800.0 time integrator: type: Newmark - β: 0.25 - γ: 0.5 + β: 0.49 + γ: 0.9 initial conditions: velocity: - node set: nsall diff --git a/examples/ahead/overlap/plate/plate-1.g b/examples/ahead/overlap/plate/plate-1.g new file mode 100644 index 00000000..64863deb Binary files /dev/null and b/examples/ahead/overlap/plate/plate-1.g differ diff --git a/examples/ahead/overlap/plate/plate-2.g b/examples/ahead/overlap/plate/plate-2.g new file mode 100644 index 00000000..143727c4 Binary files /dev/null and b/examples/ahead/overlap/plate/plate-2.g differ diff --git a/examples/ahead/overlap/plate/plate.jou b/examples/ahead/overlap/plate/plate.jou index e5bf1d2c..78cbf0ee 100644 --- a/examples/ahead/overlap/plate/plate.jou +++ b/examples/ahead/overlap/plate/plate.jou @@ -2,7 +2,7 @@ ${side = 0.2} ${height = 0.03} ${overlap_vol_frac = 0.25} ${h_fine = 0.01} -${h_coarse = 0.01} +${h_coarse = 0.005} ${area = side * height} ${volume = area * side} diff --git a/examples/ahead/overlap/torsion/dynamic-svk-cubic-opinf-rom/torsion-1.yaml b/examples/ahead/overlap/torsion/dynamic-svk-cubic-opinf-rom/torsion-1.yaml index 680fe915..93fd4243 100644 --- a/examples/ahead/overlap/torsion/dynamic-svk-cubic-opinf-rom/torsion-1.yaml +++ b/examples/ahead/overlap/torsion/dynamic-svk-cubic-opinf-rom/torsion-1.yaml @@ -1,5 +1,5 @@ type: single -input mesh file: ../../torsion-1.g +input mesh file: ../torsion-1.g output mesh file: torsion-1.e model: type: solid mechanics @@ -39,7 +39,7 @@ initial conditions: boundary conditions: Schwarz overlap: - side set: +Z_ss - source: torsion-2.yaml + source: torsion-2 source block: top source side set: -Z_ss solver: diff --git a/examples/ahead/overlap/torsion/dynamic-svk-cubic-opinf-rom/torsion-2.yaml b/examples/ahead/overlap/torsion/dynamic-svk-cubic-opinf-rom/torsion-2.yaml index 8310eb7f..cf26cd7b 100644 --- a/examples/ahead/overlap/torsion/dynamic-svk-cubic-opinf-rom/torsion-2.yaml +++ b/examples/ahead/overlap/torsion/dynamic-svk-cubic-opinf-rom/torsion-2.yaml @@ -1,5 +1,5 @@ type: single -input mesh file: ../../torsion-2.g +input mesh file: ../torsion-2.g output mesh file: torsion-2.e model: type: cubic opinf rom @@ -40,7 +40,7 @@ initial conditions: boundary conditions: Schwarz overlap: - side set: -Z_ss - source: torsion-1.yaml + source: torsion-1 source block: bottom source side set: +Z_ss solver: diff --git a/examples/ahead/overlap/torsion/dynamic-svk-opinf-fom/torsion-1.yaml b/examples/ahead/overlap/torsion/dynamic-svk-opinf-fom/torsion-1.yaml index 9a16b409..d69b720b 100644 --- a/examples/ahead/overlap/torsion/dynamic-svk-opinf-fom/torsion-1.yaml +++ b/examples/ahead/overlap/torsion/dynamic-svk-opinf-fom/torsion-1.yaml @@ -40,7 +40,7 @@ initial conditions: boundary conditions: Schwarz overlap: - side set: +Z_ss - source: torsion-2.yaml + source: torsion-2 source block: top source side set: -Z_ss solver: diff --git a/examples/ahead/overlap/torsion/dynamic-svk-opinf-fom/torsion-2.yaml b/examples/ahead/overlap/torsion/dynamic-svk-opinf-fom/torsion-2.yaml index e9388a78..085f676d 100644 --- a/examples/ahead/overlap/torsion/dynamic-svk-opinf-fom/torsion-2.yaml +++ b/examples/ahead/overlap/torsion/dynamic-svk-opinf-fom/torsion-2.yaml @@ -40,7 +40,7 @@ initial conditions: boundary conditions: Schwarz overlap: - side set: -Z_ss - source: torsion-1.yaml + source: torsion-1 source block: bottom source side set: +Z_ss solver: diff --git a/examples/ahead/overlap/torsion/torsion-1.g b/examples/ahead/overlap/torsion/torsion-1.g new file mode 100644 index 00000000..d8224c0b Binary files /dev/null and b/examples/ahead/overlap/torsion/torsion-1.g differ diff --git a/examples/ahead/overlap/torsion/torsion-2.g b/examples/ahead/overlap/torsion/torsion-2.g new file mode 100644 index 00000000..44ff7001 Binary files /dev/null and b/examples/ahead/overlap/torsion/torsion-2.g differ diff --git a/examples/ahead/single/bracket/bracket.g b/examples/ahead/single/bracket/bracket.g new file mode 100644 index 00000000..ff4f6ff6 Binary files /dev/null and b/examples/ahead/single/bracket/bracket.g differ diff --git a/examples/ahead/single/clamped/clamped.g b/examples/ahead/single/clamped/clamped.g new file mode 100644 index 00000000..5f98c4fb Binary files /dev/null and b/examples/ahead/single/clamped/clamped.g differ diff --git a/examples/ahead/single/laser-weld/laser-weld.g b/examples/ahead/single/laser-weld/laser-weld.g new file mode 100644 index 00000000..d94e0ef5 Binary files /dev/null and b/examples/ahead/single/laser-weld/laser-weld.g differ diff --git a/examples/ahead/single/laser-weld/quasistatic/symmetry/laser-weld.yaml b/examples/ahead/single/laser-weld/quasistatic/symmetry/laser-weld.yaml index 74301ad2..151a3265 100644 --- a/examples/ahead/single/laser-weld/quasistatic/symmetry/laser-weld.yaml +++ b/examples/ahead/single/laser-weld/quasistatic/symmetry/laser-weld.yaml @@ -31,7 +31,7 @@ boundary conditions: - node set: surface_positive_y component: y function: "0.1 * t" - - node set: surface_positive_z + - node set: surface_negative_z component: z function: "0.0" solver: diff --git a/examples/ahead/single/notched-cylinder/notched-cylinder.g b/examples/ahead/single/notched-cylinder/notched-cylinder.g new file mode 100644 index 00000000..b08f8d2a Binary files /dev/null and b/examples/ahead/single/notched-cylinder/notched-cylinder.g differ diff --git a/examples/ahead/single/plate/plate.g b/examples/ahead/single/plate/plate.g new file mode 100644 index 00000000..24e6f86b Binary files /dev/null and b/examples/ahead/single/plate/plate.g differ diff --git a/examples/ahead/single/torsion/torsion.g b/examples/ahead/single/torsion/torsion.g new file mode 100644 index 00000000..f6c061d3 Binary files /dev/null and b/examples/ahead/single/torsion/torsion.g differ diff --git a/src/simulation.jl b/src/simulation.jl index b47af8c4..79e09af7 100644 --- a/src/simulation.jl +++ b/src/simulation.jl @@ -835,11 +835,11 @@ function detect_contact(sim::MultiDomainSimulation) end resize!(sim.controller.contact_hist, sim.controller.stop + 1) sim.controller.contact_hist[sim.controller.stop + 1] = sim.controller.active_contact - write_scharz_params_csv(sim) + write_schwarz_params_csv(sim) return nothing end -function write_scharz_params_csv(sim::MultiDomainSimulation) +function write_schwarz_params_csv(sim::MultiDomainSimulation) stop = sim.controller.stop csv_interval = get(sim.params, "CSV output interval", 0) if csv_interval > 0 && stop % csv_interval == 0 diff --git a/test/runtests.jl b/test/runtests.jl index 8b09fd38..d6b0bbcd 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -12,41 +12,56 @@ using Test include("../src/Norma.jl") include("helpers.jl") -# List of all test files (ordered, with explicit index) +# List of all test files (ordered) const indexed_test_files = [ - (1, "minitensor.jl"), - (2, "interpolation.jl"), - (3, "constitutive.jl"), - (4, "single-static-solid-cube.jl"), - (5, "single-static-solid-neumann-bc.jl"), - (6, "single-implicit-dynamic-solid-cube.jl"), - (7, "single-implicit-dynamic-solid-sho.jl"), - (8, "single-implicit-dynamic-solid-clamped.jl"), - (9, "single-explicit-dynamic-solid-cube.jl"), - (10, "single-explicit-dynamic-solid-sho.jl"), - (11, "single-explicit-dynamic-solid-clamped.jl"), - (12, "tet4-static-solid-cube.jl"), - (13, "tet10-static-solid-cube.jl"), - (14, "schwarz-overlap-static-cuboid-hex8.jl"), - (15, "schwarz-nonoverlap-static-cuboid-hex8.jl"), - (16, "transfer-operators.jl"), - (17, "schwarz-contact-static-cubes.jl"), - (18, "schwarz-contact-dynamic-cubes.jl"), - (19, "solid-inclined-displacement.jl"), - (20, "opinf-schwarz-overlap-cuboid-hex8.jl"), - (21, "quadratic-opinf-schwarz-overlap-cuboid-hex8.jl"), - (22, "cubic-opinf-schwarz-overlap-cuboid-hex8.jl"), - (23, "adaptive-time-stepping.jl"), - (24, "schwarz-ahead-overlap-dynamic-notched-cylinder.jl"), - (25, "schwarz-ahead-overlap-dynamic-laser-weld.jl"), - (26, "utils.jl"), # Must go last due to FPE traps + (1, "minitensor.jl"), + (2, "interpolation.jl"), + (3, "constitutive.jl"), + (4, "single-static-solid-cube.jl"), + (5, "single-static-solid-neumann-bc.jl"), + (6, "single-implicit-dynamic-solid-cube.jl"), + (7, "single-implicit-dynamic-solid-sho.jl"), + (8, "single-implicit-dynamic-solid-clamped.jl"), + (9, "single-explicit-dynamic-solid-cube.jl"), + (10, "single-explicit-dynamic-solid-sho.jl"), + (11, "single-explicit-dynamic-solid-clamped.jl"), + (12, "tet4-static-solid-cube.jl"), + (13, "tet10-static-solid-cube.jl"), + (14, "schwarz-overlap-static-cuboid-hex8.jl"), + (15, "schwarz-nonoverlap-static-cuboid-hex8.jl"), + (16, "transfer-operators.jl"), + (17, "schwarz-contact-static-cubes.jl"), + (18, "schwarz-contact-dynamic-cubes.jl"), + (19, "solid-inclined-displacement.jl"), + (20, "opinf-schwarz-overlap-cuboid-hex8.jl"), + (21, "quadratic-opinf-schwarz-overlap-cuboid-hex8.jl"), + (22, "cubic-opinf-schwarz-overlap-cuboid-hex8.jl"), + (23, "adaptive-time-stepping.jl"), + (24, "schwarz-ahead-overlap-dynamic-clamped.jl"), + (25, "schwarz-ahead-overlap-dynamic-notched-cylinder.jl"), + (26, "schwarz-ahead-overlap-dynamic-laser-weld.jl"), + (27, "schwarz-ahead-overlap-dynamic-torsion.jl"), + (28, "schwarz-ahead-overlap-dynamic-bracket.jl"), + (29, "schwarz-ahead-overlap-dynamic-plate.jl"), + (30, "single-ahead-clamped.jl"), + (31, "single-ahead-notched-cylinder.jl"), + (32, "single-ahead-laser-weld.jl"), + (33, "single-ahead-torsion.jl"), + (34, "single-ahead-bracket.jl"), + (35, "single-ahead-plate.jl"), + (36, "schwarz-ahead-nonoverlap-dynamic-clamped.jl"), + (37, "schwarz-ahead-nonoverlap-dynamic-laser-weld.jl"), + (38, "schwarz-ahead-nonoverlap-dynamic-torsion.jl"), + (39, "schwarz-ahead-nonoverlap-dynamic-plate.jl"), + (40, "schwarz-ahead-nonoverlap-dynamic-bracket.jl"), + (41, "utils.jl"), # Must go last due to FPE traps ] # Extract test file names const all_test_files = [file for (_, file) in indexed_test_files] # Optional test indices (excluded from quick runs) -const optional_test_indices = Int[24, 25] +const optional_test_indices = Int[24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40] # Quick test set (subset of all tests) const quick_test_indices = [i for (i, _) in indexed_test_files if i ∉ optional_test_indices] diff --git a/test/schwarz-ahead-nonoverlap-dynamic-bracket.jl b/test/schwarz-ahead-nonoverlap-dynamic-bracket.jl new file mode 100644 index 00000000..918e92a4 --- /dev/null +++ b/test/schwarz-ahead-nonoverlap-dynamic-bracket.jl @@ -0,0 +1,54 @@ +# Norma: Copyright 2025 National Technology & Engineering Solutions of +# Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, +# the U.S. Government retains certain rights in this software. This software +# is released under the BSD license detailed in the file license.txt in the +# top-level Norma.jl directory. + +using YAML + +@testset "Schwarz AHeaD Non-Overlap Dynamic Bracket TET4-TET4 Dissipative Newmark" begin + cp("../examples/ahead/nonoverlap/bracket/dynamic/bracket.yaml", "bracket.yaml"; force=true) + cp("../examples/ahead/nonoverlap/bracket/dynamic/bracket-1.yaml", "bracket-1.yaml"; force=true) + cp("../examples/ahead/nonoverlap/bracket/dynamic/bracket-2.yaml", "bracket-2.yaml"; force=true) + cp("../examples/ahead/nonoverlap/bracket/bracket-1.g", "../bracket-1.g"; force=true) + cp("../examples/ahead/nonoverlap/bracket/bracket-2.g", "../bracket-2.g"; force=true) + input_file = "bracket.yaml" + params = YAML.load_file(input_file; dicttype=Norma.Parameters) + params["initial time"] = 0.0 + params["time step"] = 1.0e-6 + params["final time"] = 5.0e-5 + params["name"] = input_file + sim = Norma.run(params) + subsims = sim.subsims + model_bracket1 = subsims[1].model + model_bracket2 = subsims[2].model + + rm("bracket.yaml") + rm("bracket-1.yaml") + rm("bracket-2.yaml") + rm("../bracket-1.g") + rm("../bracket-2.g") + rm("bracket-1.e") + rm("bracket-2.e") + + min_disp_x_bracket1 = minimum(model_bracket1.current[1, :] - model_bracket1.reference[1, :]) + min_disp_y_bracket1 = minimum(model_bracket1.current[2, :] - model_bracket1.reference[2, :]) + max_disp_z_bracket1 = maximum(model_bracket1.current[3, :] - model_bracket1.reference[3, :]) + min_disp_x_bracket2 = minimum(model_bracket2.current[1, :] - model_bracket2.reference[1, :]) + min_disp_y_bracket2 = minimum(model_bracket2.current[2, :] - model_bracket2.reference[2, :]) + max_disp_z_bracket2 = maximum(model_bracket2.current[3, :] - model_bracket2.reference[3, :]) + avg_stress_bracket1 = average_components(model_bracket1.stress) + avg_stress_bracket2 = average_components(model_bracket2.stress) + + @test min_disp_x_bracket1 ≈ -2.292363909493874e-5 atol = 1e-12 + @test min_disp_y_bracket1 ≈ -2.6772610574016253e-5 atol = 1e-12 + @test max_disp_z_bracket1 ≈ 8.406701507824004e-5 atol = 1e-8 + @test min_disp_x_bracket2 ≈ -0.00010879133317491518 atol = 1e-12 + @test min_disp_y_bracket2 ≈ -4.821150003511687e-5 atol = 1e-12 + @test max_disp_z_bracket2 ≈ 0.0008416546150997427 atol = 1e-8 + @test avg_stress_bracket1 ≈ [1.4344587897170822e6 147404.28440152534 80028.09147772216 1331.5200561233653 -4.470431261192811e6 -102990.28645337945] atol = 1.0e1 + @test avg_stress_bracket2 ≈ [-887460.5393152214 320509.9388991009 -380020.14019136556 -350857.5055218009 1.0378814655089243e6 -1.285348432558279e6] atol = 1.0e1 + @test sim.controller.schwarz_iters ≈ [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 4, 4, 5, 7, 8, 9, 9, 9, 9, 8, 8, 8, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9] atol = 0 + +end + diff --git a/test/schwarz-ahead-nonoverlap-dynamic-clamped.jl b/test/schwarz-ahead-nonoverlap-dynamic-clamped.jl new file mode 100644 index 00000000..5ea71010 --- /dev/null +++ b/test/schwarz-ahead-nonoverlap-dynamic-clamped.jl @@ -0,0 +1,130 @@ +# Norma: Copyright 2025 National Technology & Engineering Solutions of +# Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, +# the U.S. Government retains certain rights in this software. This software +# is released under the BSD license detailed in the file license.txt in the +# top-level Norma.jl directory. + +using YAML + +@testset "AHeaD Non-Overlap Dynamic Clamped HEX8" begin + cp("../examples/ahead/nonoverlap/clamped/dynamic/clamped.yaml", "clamped.yaml"; force=true) + cp("../examples/ahead/nonoverlap/clamped/dynamic/clamped-1.yaml", "clamped-1.yaml"; force=true) + cp("../examples/ahead/nonoverlap/clamped/dynamic/clamped-2.yaml", "clamped-2.yaml"; force=true) + cp("../examples/ahead/nonoverlap/clamped/clamped-1.g", "../clamped-1.g"; force=true) + cp("../examples/ahead/nonoverlap/clamped/clamped-2.g", "../clamped-2.g"; force=true) + input_file = "clamped.yaml" + params = YAML.load_file(input_file; dicttype=Norma.Parameters) + params["initial time"] = 0.0 + t = 1.0e-4 + params["time step"] = 1.0e-6 + params["final time"] = t + + params["name"] = input_file + sim = Norma.run(params) + subsims = sim.subsims + model_clamped0 = subsims[1].model + model_clamped1 = subsims[2].model + + rm("clamped.yaml") + rm("clamped-1.yaml") + rm("clamped-2.yaml") + rm("../clamped-1.g") + rm("../clamped-2.g") + rm("clamped-1.e") + rm("clamped-2.e") + + z0 = model_clamped0.reference[3,:] + disp0_x = model_clamped0.current[1,:] - model_clamped0.reference[1,:] + disp0_y = model_clamped0.current[2,:] - model_clamped0.reference[2,:] + disp0_z = model_clamped0.current[3,:] - model_clamped0.reference[3,:] + velo0_x = model_clamped0.velocity[1,:] + velo0_y = model_clamped0.velocity[2,:] + velo0_z = model_clamped0.velocity[3,:] + acce0_x = model_clamped0.acceleration[1,:] + acce0_y = model_clamped0.acceleration[2,:] + acce0_z = model_clamped0.acceleration[3,:] + + z1 = model_clamped1.reference[3,:] + disp1_x = model_clamped1.current[1,:] - model_clamped1.reference[1,:] + disp1_y = model_clamped1.current[2,:] - model_clamped1.reference[2,:] + disp1_z = model_clamped1.current[3,:] - model_clamped1.reference[3,:] + velo1_x = model_clamped1.velocity[1,:] + velo1_y = model_clamped1.velocity[2,:] + velo1_z = model_clamped1.velocity[3,:] + acce1_x = model_clamped1.acceleration[1,:] + acce1_y = model_clamped1.acceleration[2,:] + acce1_z = model_clamped1.acceleration[3,:] + + c = sqrt(1e9/1e3); + a = 0.001; + b = 0.0; + s = 0.02; + T = 1.0e-3; + + #Create and populate exact solution vectors - Omega1 + n0 = size(z0)[1] + disp0_z_exact = zeros(Float64, n0) + velo0_z_exact = zeros(Float64, n0) + acce0_z_exact = zeros(Float64, n0) + for i in 1:n0 + disp0_z_exact[i] = 1/2*a*(exp(-(z0[i]-c*t-b)^2/2/s^2) + exp(-(z0[i]+c*t-b)^2/2/s^2)) - 1/2*a*(exp(-(z0[i]-c*(T-t)-b)^2/2/s^2) + exp(-(z0[i]+c*(T-t)-b)^2/2/s^2)) + velo0_z_exact[i] = c/2*a/s^2*((z0[i]-c*t-b)*exp(-(z0[i]-c*t-b)^2/2/s^2) - (z0[i]+c*t-b)*exp(-(z0[i]+c*t-b)^2/2/s^2)) + c/2*a/s^2*((z0[i]-c*(T-t)-b)*exp(-(z0[i]-c*(T-t)-b)^2/2/s^2) - (z0[i]+c*(T-t)-b)*exp(-(z0[i]+c*(T-t)-b)^2/2/s^2)) + acce0_z_exact[i] = 1/2*a*(-c^2/s^2*exp(-1/2*(z0[i]-c*t-b)^2/s^2)+1/s^4*c^2*((z0[i]-c*t-b)^2)*exp(-1/2*(z0[i]-c*t-b)^2/s^2)-c^2/s^2*exp(-1/2*(z0[i]+c*t-b)^2/s^2)+1/s^4*c^2*((z0[i]+c*t-b)^2)*exp(-1/2*(z0[i]+c*t-b)^2/s^2)) - 1/2*a*(-c^2/s^2*exp(-1/2*(z0[i]-c*(T-t)-b)^2/s^2)+1/s^4*c^2*((z0[i]-c*(T-t)-b)^2)*exp(-1/2*(z0[i]-c*(T-t)-b)^2/s^2)-c^2/s^2*exp(-1/2*(z0[i]+c*(T-t)-b)^2/s^2)+1/s^4*c^2*((z0[i]+c*(T-t)-b)^2)*exp(-1/2*(z0[i]+c*(T-t)-b)^2/s^2)) + end + disp0_z_err = norm(disp0_z_exact - disp0_z) + disp0_z_norm = norm(disp0_z_exact) + disp0_z_relerr = disp0_z_err / disp0_z_norm + velo0_z_err = norm(velo0_z_exact - velo0_z) + velo0_z_norm = norm(velo0_z_exact) + velo0_z_relerr = velo0_z_err / velo0_z_norm + acce0_z_err = norm(acce0_z_exact - acce0_z) + acce0_z_norm = norm(acce0_z_exact) + acce0_z_relerr = acce0_z_err / acce0_z_norm + + @test disp0_z_relerr ≈ 0.023301214198427324 atol = 1e-12 + @test velo0_z_relerr ≈ 0.04367879603325008 atol = 1e-12 + @test acce0_z_relerr ≈ 0.11666137089499143 atol = 1e-6 + @test norm(disp0_x) ≈ 0.0 atol = 1.0e-18 + @test norm(disp0_y) ≈ 0.0 atol = 1.0e-18 + @test norm(velo0_x) ≈ 0.0 atol = 1.0e-18 + @test norm(velo0_y) ≈ 0.0 atol = 1.0e-18 + @test norm(acce0_x) ≈ 0.0 atol = 1.0e-18 + @test norm(acce0_y) ≈ 0.0 atol = 1.0e-18 + + #Create and populate exact solution vectors - Omega2 + n1 = size(z1)[1] + disp1_z_exact = zeros(Float64, n1) + velo1_z_exact = zeros(Float64, n1) + acce1_z_exact = zeros(Float64, n1) + for i in 1:n1 + disp1_z_exact[i] = 1/2*a*(exp(-(z1[i]-c*t-b)^2/2/s^2) + exp(-(z1[i]+c*t-b)^2/2/s^2)) - 1/2*a*(exp(-(z1[i]-c*(T-t)-b)^2/2/s^2) + exp(-(z1[i]+c*(T-t)-b)^2/2/s^2)) + velo1_z_exact[i] = c/2*a/s^2*((z1[i]-c*t-b)*exp(-(z1[i]-c*t-b)^2/2/s^2) - (z1[i]+c*t-b)*exp(-(z1[i]+c*t-b)^2/2/s^2)) + c/2*a/s^2*((z1[i]-c*(T-t)-b)*exp(-(z1[i]-c*(T-t)-b)^2/2/s^2) - (z1[i]+c*(T-t)-b)*exp(-(z1[i]+c*(T-t)-b)^2/2/s^2)) + acce1_z_exact[i] = 1/2*a*(-c^2/s^2*exp(-1/2*(z1[i]-c*t-b)^2/s^2)+1/s^4*c^2*((z1[i]-c*t-b)^2)*exp(-1/2*(z1[i]-c*t-b)^2/s^2)-c^2/s^2*exp(-1/2*(z1[i]+c*t-b)^2/s^2)+1/s^4*c^2*((z1[i]+c*t-b)^2)*exp(-1/2*(z1[i]+c*t-b)^2/s^2)) - 1/2*a*(-c^2/s^2*exp(-1/2*(z1[i]-c*(T-t)-b)^2/s^2)+1/s^4*c^2*((z1[i]-c*(T-t)-b)^2)*exp(-1/2*(z1[i]-c*(T-t)-b)^2/s^2)-c^2/s^2*exp(-1/2*(z1[i]+c*(T-t)-b)^2/s^2)+1/s^4*c^2*((z1[i]+c*(T-t)-b)^2)*exp(-1/2*(z1[i]+c*(T-t)-b)^2/s^2)) + end + disp1_z_err = norm(disp1_z_exact - disp1_z) + disp1_z_norm = norm(disp1_z_exact) + disp1_z_relerr = disp1_z_err / disp1_z_norm + velo1_z_err = norm(velo1_z_exact - velo1_z) + velo1_z_norm = norm(velo1_z_exact) + velo1_z_relerr = velo1_z_err / velo1_z_norm + acce1_z_err = norm(acce1_z_exact - acce1_z) + acce1_z_norm = norm(acce1_z_exact) + acce1_z_relerr = acce1_z_err / acce1_z_norm + + @test disp1_z_relerr ≈ 0.034101038908999154 atol = 1e-12 + @test velo1_z_relerr ≈ 0.06959872860732548 atol = 1e-12 + @test acce1_z_relerr ≈ 0.13000885748946542 atol = 1e-6 + @test norm(disp1_x) ≈ 0.0 atol = 1.0e-18 + @test norm(disp1_y) ≈ 0.0 atol = 1.0e-18 + @test norm(velo1_x) ≈ 0.0 atol = 1.0e-18 + @test norm(velo1_y) ≈ 0.0 atol = 1.0e-18 + @test norm(acce1_x) ≈ 0.0 atol = 1.0e-18 + @test norm(acce1_y) ≈ 0.0 atol = 1.0e-18 + + @test sim.controller.schwarz_iters ≈ [2, 2, 2, 2, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 11, 11, 11, 10, 6] atol = 0 + +end + + + + diff --git a/test/schwarz-ahead-nonoverlap-dynamic-laser-weld.jl b/test/schwarz-ahead-nonoverlap-dynamic-laser-weld.jl new file mode 100644 index 00000000..82ef4165 --- /dev/null +++ b/test/schwarz-ahead-nonoverlap-dynamic-laser-weld.jl @@ -0,0 +1,69 @@ +# Norma: Copyright 2025 National Technology & Engineering Solutions of +# Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, +# the U.S. Government retains certain rights in this software. This software +# is released under the BSD license detailed in the file license.txt in the +# top-level Norma.jl directory. + +using YAML + +@testset "Schwarz AHeaD Non-Overlap Dynamic Laser Weld HEX8-HEX8 Symmetry BCs" begin + cp("../examples/ahead/nonoverlap/laser-weld/dynamic/symmetry/laser-weld.yaml", "laser-weld.yaml"; force=true) + cp("../examples/ahead/nonoverlap/laser-weld/dynamic/symmetry/holder-0.yaml", "holder-0.yaml"; force=true) + cp("../examples/ahead/nonoverlap/laser-weld/dynamic/symmetry/holder-1.yaml", "holder-1.yaml"; force=true) + cp("../examples/ahead/nonoverlap/laser-weld/dynamic/symmetry/gauge.yaml", "gauge.yaml"; force=true) + cp("../examples/ahead/nonoverlap/laser-weld/holder-0.g", "../../holder-0.g"; force=true) + cp("../examples/ahead/nonoverlap/laser-weld/holder-1.g", "../../holder-1.g"; force=true) + cp("../examples/ahead/nonoverlap/laser-weld/gauge.g", "../../gauge.g"; force=true) + input_file = "laser-weld.yaml" + params = YAML.load_file(input_file; dicttype=Norma.Parameters) + params["initial time"] = 0.0 + params["time step"] = 0.01 + params["final time"] = 0.05 + params["name"] = input_file + sim = Norma.run(params) + subsims = sim.subsims + model_holder0 = subsims[1].model + model_gauge = subsims[2].model + model_holder1 = subsims[3].model + + rm("laser-weld.yaml") + rm("holder-0.yaml") + rm("holder-1.yaml") + rm("gauge.yaml") + rm("../../holder-0.g") + rm("../../holder-1.g") + rm("../../gauge.g") + rm("holder-0.e") + rm("holder-1.e") + rm("gauge.e") + + min_disp_x_holder0 = minimum(model_holder0.current[1, :] - model_holder0.reference[1, :]) + min_disp_y_holder0 = minimum(model_holder0.current[2, :] - model_holder0.reference[2, :]) + max_disp_z_holder0 = maximum(model_holder0.current[3, :] - model_holder0.reference[3, :]) + min_disp_x_gauge = minimum(model_gauge.current[1, :] - model_gauge.reference[1, :]) + min_disp_y_gauge = minimum(model_gauge.current[2, :] - model_gauge.reference[2, :]) + max_disp_z_gauge = maximum(model_gauge.current[3, :] - model_gauge.reference[3, :]) + min_disp_x_holder1 = minimum(model_holder1.current[1, :] - model_holder1.reference[1, :]) + min_disp_y_holder1 = minimum(model_holder1.current[2, :] - model_holder1.reference[2, :]) + max_disp_z_holder1 = maximum(model_holder1.current[3, :] - model_holder1.reference[3, :]) + avg_stress_holder0 = average_components(model_holder0.stress) + avg_stress_gauge = average_components(model_gauge.stress) + avg_stress_holder1 = average_components(model_holder1.stress) + + @test min_disp_x_holder0 ≈ -4.8524923688300636e-5 atol = 1e-12 + @test min_disp_y_holder0 ≈ -0.0006155829702431115 atol = 1e-12 + @test max_disp_z_holder0 ≈ 0.0 atol = 1e-12 + @test min_disp_x_gauge ≈ -7.768426106180559e-5 atol = 1e-12 + @test min_disp_y_gauge ≈ -0.00027640414578330996 atol = 1e-12 + @test max_disp_z_gauge ≈ 4.4372026740832626e-5 atol = 1e-12 + @test min_disp_x_holder1 ≈ -4.8953646255081584e-5 atol = 1e-12 + @test min_disp_y_holder1 ≈ 0.00023478463555726137 atol = 1e-12 + @test max_disp_z_holder1 ≈ 0.0 atol = 1e-12 + @test avg_stress_holder0 ≈ [-243.0717661305563 1.7798335903690055e6 -49963.13502708086 -46273.081927730775 1209.6636290360905 1525.1001490585427] atol = + 1.0e1 + @test avg_stress_gauge ≈ [16219.565177010196 1.845519057684895e6 122146.1419563506 4904.312109770015 29899.525543416865 94.33582939764187] atol = + 1.0e1 + @test avg_stress_holder1 ≈ [-1056.0441890865773 1.7715466435733493e6 -54239.702779201296 50590.033301702606 1620.6847557192993 -1375.575102437882] atol = + 1.0e1 + @test sim.controller.schwarz_iters ≈ [26, 38, 44, 48, 51] atol = 0 +end diff --git a/test/schwarz-ahead-nonoverlap-dynamic-notched-cylinder.jl b/test/schwarz-ahead-nonoverlap-dynamic-notched-cylinder.jl new file mode 100644 index 00000000..8e7ce561 --- /dev/null +++ b/test/schwarz-ahead-nonoverlap-dynamic-notched-cylinder.jl @@ -0,0 +1,65 @@ +# Norma: Copyright 2025 National Technology & Engineering Solutions of +# Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, +# the U.S. Government retains certain rights in this software. This software +# is released under the BSD license detailed in the file license.txt in the +# top-level Norma.jl directory. + +using YAML + +@testset "Schwarz AHeaD Non-Overlap Dynamic Notched Cylinder HEX8-HEX8" begin + cp("../examples/ahead/nonoverlap/notched-cylinder/dynamic/notched-cylinder.yaml", "notched-cylinder.yaml"; force=true) + cp( + "../examples/ahead/nonoverlap/notched-cylinder/dynamic/notched-cylinder-1.yaml", + "notched-cylinder-1.yaml"; + force=true, + ) + cp( + "../examples/ahead/nonoverlap/notched-cylinder/dynamic/notched-cylinder-2.yaml", + "notched-cylinder-2.yaml"; + force=true, + ) + cp("../examples/ahead/nonoverlap/notched-cylinder/notched-cylinder-1.g", "../notched-cylinder-1.g"; force=true) + cp("../examples/ahead/nonoverlap/notched-cylinder/notched-cylinder-2.g", "../notched-cylinder-2.g"; force=true) + input_file = "notched-cylinder.yaml" + params = YAML.load_file(input_file; dicttype=Norma.Parameters) + params["initial time"] = 0.0 + params["time step"] = 0.01 + params["final time"] = 0.05 + params["name"] = input_file + sim = Norma.run(params) + subsims = sim.subsims + model_1 = subsims[1].model + model_2 = subsims[2].model + + rm("notched-cylinder.yaml") + rm("notched-cylinder-1.yaml") + rm("notched-cylinder-2.yaml") + rm("../notched-cylinder-1.g") + rm("../notched-cylinder-2.g") + rm("notched-cylinder-1.e") + rm("notched-cylinder-2.e") + + min_disp_x_1 = minimum(model_1.current[1, :] - model_1.reference[1, :]) + min_disp_y_1 = minimum(model_1.current[2, :] - model_1.reference[2, :]) + max_disp_z_1 = maximum(model_1.current[3, :] - model_1.reference[3, :]) + min_disp_x_2 = minimum(model_2.current[1, :] - model_2.reference[1, :]) + min_disp_y_2 = minimum(model_2.current[2, :] - model_2.reference[2, :]) + min_disp_z_2 = minimum(model_2.current[3, :] - model_2.reference[3, :]) + avg_stress_1 = average_components(model_1.stress) + avg_stress_2 = average_components(model_2.stress) + + @test min_disp_x_1 ≈ -1.6007099461888552e-5 atol = 1e-12 + @test min_disp_y_1 ≈ -1.6007073405502337e-5 atol = 1e-12 + @test max_disp_z_1 ≈ 0.00011007952600178977 atol = 1e-12 + @test min_disp_x_2 ≈ -1.6186344441136702e-5 atol = 1e-12 + @test min_disp_y_2 ≈ -1.618628933883204e-5 atol = 1e-12 + @test min_disp_z_2 ≈ 5.1726659805836905e-5 atol = 1e-12 + @test avg_stress_1 ≈ + [119658.24151708037 119759.96550264646 2.105505961105632e6 280369.0355588143 281504.50820556487 57168.0765508701] atol = + 1.0e1 + @test avg_stress_2 ≈ + [-101340.89672529901 -101446.28712096746 1.5977255795638144e6 121800.33493609141 122483.30918545111 37064.478126464295] atol = + 1.0e1 + @test sim.controller.schwarz_iters ≈ [1, 1, 1, 1, 4, 4, 4, 4, 5, 5] atol = 0 +end + diff --git a/test/schwarz-ahead-nonoverlap-dynamic-plate.jl b/test/schwarz-ahead-nonoverlap-dynamic-plate.jl new file mode 100644 index 00000000..f7cd9e4c --- /dev/null +++ b/test/schwarz-ahead-nonoverlap-dynamic-plate.jl @@ -0,0 +1,54 @@ +# Norma: Copyright 2025 National Technology & Engineering Solutions of +# Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, +# the U.S. Government retains certain rights in this software. This software +# is released under the BSD license detailed in the file license.txt in the +# top-level Norma.jl directory. + +using YAML + +@testset "Schwarz AHeaD Non-Overlap Dynamic Plate HEX8-HEX8 Dissipative Newmark" begin + cp("../examples/ahead/nonoverlap/plate/dynamic/plate.yaml", "plate.yaml"; force=true) + cp("../examples/ahead/nonoverlap/plate/dynamic/plate-1.yaml", "plate-1.yaml"; force=true) + cp("../examples/ahead/nonoverlap/plate/dynamic/plate-2.yaml", "plate-2.yaml"; force=true) + cp("../examples/ahead/nonoverlap/plate/plate-1.g", "../plate-1.g"; force=true) + cp("../examples/ahead/nonoverlap/plate/plate-2.g", "../plate-2.g"; force=true) + input_file = "plate.yaml" + params = YAML.load_file(input_file; dicttype=Norma.Parameters) + params["initial time"] = 0.0 + params["time step"] = 1.0e-5 + params["final time"] = 5.0e-4 + params["name"] = input_file + sim = Norma.run(params) + subsims = sim.subsims + model_plate1 = subsims[1].model + model_plate2 = subsims[2].model + + rm("plate.yaml") + rm("plate-1.yaml") + rm("plate-2.yaml") + rm("../plate-1.g") + rm("../plate-2.g") + rm("plate-1.e") + rm("plate-2.e") + + min_disp_x_plate1 = minimum(model_plate1.current[1, :] - model_plate1.reference[1, :]) + min_disp_y_plate1 = minimum(model_plate1.current[2, :] - model_plate1.reference[2, :]) + max_disp_z_plate1 = maximum(model_plate1.current[3, :] - model_plate1.reference[3, :]) + min_disp_x_plate2 = minimum(model_plate2.current[1, :] - model_plate2.reference[1, :]) + min_disp_y_plate2 = minimum(model_plate2.current[2, :] - model_plate2.reference[2, :]) + max_disp_z_plate2 = maximum(model_plate2.current[3, :] - model_plate2.reference[3, :]) + avg_stress_plate1 = average_components(model_plate1.stress) + avg_stress_plate2 = average_components(model_plate2.stress) + + @test min_disp_x_plate1 ≈ -5.2251935992955734e-5 atol = 1e-12 + @test min_disp_y_plate1 ≈ -2.6616926060499257e-5 atol = 1e-12 + @test max_disp_z_plate1 ≈ 0.0001981244917465038 atol = 1e-12 + @test min_disp_x_plate2 ≈ -9.305900913551823e-5 atol = 1e-12 + @test min_disp_y_plate2 ≈ -4.800795014556214e-5 atol = 1e-12 + @test max_disp_z_plate2 ≈ 0.0007216778269555964 atol = 1e-12 + @test avg_stress_plate1 ≈ [977595.9630637506 85772.43956109945 141163.5317646388 -49663.11299128937 3.137536668989802e6 3493.7573966998607] atol = 1.0e1 + @test avg_stress_plate2 ≈ [540844.912808216 -117477.17517570367 -138702.5759558706 30518.477639077442 7.223736578711799e6 12844.149940346517] atol = 1.0e1 + @test sim.controller.schwarz_iters ≈ [54, 65, 66, 73, 77, 74, 70, 72, 75, 76, 75, 73, 71, 68, 65, 63, 62, 62, 63, 66, 68, 69, 68, 66, 64, 63, 63, 63, 64, 64, 64, 65, 65, 65, 64, 64, 64, 65, 66, 67, 67, 67, 67, 67, 66, 66, 64, 63, 61, 59] atol = 0 + +end + diff --git a/test/schwarz-ahead-nonoverlap-dynamic-torsion.jl b/test/schwarz-ahead-nonoverlap-dynamic-torsion.jl new file mode 100644 index 00000000..27f076de --- /dev/null +++ b/test/schwarz-ahead-nonoverlap-dynamic-torsion.jl @@ -0,0 +1,54 @@ +# Norma: Copyright 2025 National Technology & Engineering Solutions of +# Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, +# the U.S. Government retains certain rights in this software. This software +# is released under the BSD license detailed in the file license.txt in the +# top-level Norma.jl directory. + +using YAML + +@testset "Schwarz AHeaD Non-Overlap Dynamic Torsion HEX8-HEX8" begin + cp("../examples/ahead/nonoverlap/torsion/dynamic/torsion.yaml", "torsion.yaml"; force=true) + cp("../examples/ahead/nonoverlap/torsion/dynamic/torsion-1.yaml", "torsion-1.yaml"; force=true) + cp("../examples/ahead/nonoverlap/torsion/dynamic/torsion-2.yaml", "torsion-2.yaml"; force=true) + cp("../examples/ahead/nonoverlap/torsion/torsion-1.g", "../torsion-1.g"; force=true) + cp("../examples/ahead/nonoverlap/torsion/torsion-2.g", "../torsion-2.g"; force=true) + input_file = "torsion.yaml" + params = YAML.load_file(input_file; dicttype=Norma.Parameters) + params["initial time"] = 0.0 + params["time step"] = 1.0e-6 + params["final time"] = 5.0e-5 + params["name"] = input_file + sim = Norma.run(params) + subsims = sim.subsims + model_torsion1 = subsims[1].model + model_torsion2 = subsims[2].model + + rm("torsion.yaml") + rm("torsion-1.yaml") + rm("torsion-2.yaml") + rm("../torsion-1.g") + rm("../torsion-2.g") + rm("torsion-1.e") + rm("torsion-2.e") + + min_disp_x_torsion1 = minimum(model_torsion1.current[1, :] - model_torsion1.reference[1, :]) + min_disp_y_torsion1 = minimum(model_torsion1.current[2, :] - model_torsion1.reference[2, :]) + max_disp_z_torsion1 = maximum(model_torsion1.current[3, :] - model_torsion1.reference[3, :]) + min_disp_x_torsion2 = minimum(model_torsion2.current[1, :] - model_torsion2.reference[1, :]) + min_disp_y_torsion2 = minimum(model_torsion2.current[2, :] - model_torsion2.reference[2, :]) + max_disp_z_torsion2 = maximum(model_torsion2.current[3, :] - model_torsion2.reference[3, :]) + avg_stress_torsion1 = average_components(model_torsion1.stress) + avg_stress_torsion2 = average_components(model_torsion2.stress) + + @test min_disp_x_torsion1 ≈ -0.005190915825901907 atol = 1e-12 + @test min_disp_y_torsion1 ≈ -0.0051909158259019 atol = 1e-12 + @test max_disp_z_torsion1 ≈ 0.00011253980579573053 atol = 1e-12 + @test min_disp_x_torsion2 ≈ -0.005191500055775754 atol = 1e-12 + @test min_disp_y_torsion2 ≈ -0.005191500055775934 atol = 1e-12 + @test max_disp_z_torsion2 ≈ 2.234108562854109e-5 atol = 1e-12 + @test avg_stress_torsion1 ≈ [1.7705537665662847e6 1.7706066742399093e6 736180.8008143709 -238.39535563270692 365.22587280095036 -2.557130848843019] atol = 1.0e1 + @test avg_stress_torsion2 ≈ [1.4257262240109073e6 1.4257762858988189e6 549384.8122747836 -69.31989121219449 81.6909752368978 -20.893920474565377] atol = 1.0e1 + @test sim.controller.schwarz_iters ≈ [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 3] atol = 0 + +end + diff --git a/test/schwarz-ahead-overlap-dynamic-bracket.jl b/test/schwarz-ahead-overlap-dynamic-bracket.jl new file mode 100644 index 00000000..6803f735 --- /dev/null +++ b/test/schwarz-ahead-overlap-dynamic-bracket.jl @@ -0,0 +1,100 @@ +# Norma: Copyright 2025 National Technology & Engineering Solutions of +# Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, +# the U.S. Government retains certain rights in this software. This software +# is released under the BSD license detailed in the file license.txt in the +# top-level Norma.jl directory. + +using YAML + +@testset "Schwarz AHeaD Overlap Dynamic Bracket HEX8-TET4 Dissipative Newmark" begin + cp("../examples/ahead/overlap/bracket/dynamic/bracket.yaml", "bracket.yaml"; force=true) + cp("../examples/ahead/overlap/bracket/dynamic/bracket-1.yaml", "bracket-1.yaml"; force=true) + cp("../examples/ahead/overlap/bracket/dynamic/bracket-2.yaml", "bracket-2.yaml"; force=true) + cp("../examples/ahead/overlap/bracket/bracket-1.g", "../bracket-1.g"; force=true) + cp("../examples/ahead/overlap/bracket/bracket-2.g", "../bracket-2.g"; force=true) + input_file = "bracket.yaml" + params = YAML.load_file(input_file; dicttype=Norma.Parameters) + params["initial time"] = 0.0 + params["time step"] = 1.0e-5 + params["final time"] = 5.0e-4 + params["name"] = input_file + sim = Norma.run(params) + subsims = sim.subsims + model_bracket1 = subsims[1].model + model_bracket2 = subsims[2].model + + rm("bracket.yaml") + rm("bracket-1.yaml") + rm("bracket-2.yaml") + rm("../bracket-1.g") + rm("../bracket-2.g") + rm("bracket-1.e") + rm("bracket-2.e") + + min_disp_x_bracket1 = minimum(model_bracket1.current[1, :] - model_bracket1.reference[1, :]) + min_disp_y_bracket1 = minimum(model_bracket1.current[2, :] - model_bracket1.reference[2, :]) + max_disp_z_bracket1 = maximum(model_bracket1.current[3, :] - model_bracket1.reference[3, :]) + min_disp_x_bracket2 = minimum(model_bracket2.current[1, :] - model_bracket2.reference[1, :]) + min_disp_y_bracket2 = minimum(model_bracket2.current[2, :] - model_bracket2.reference[2, :]) + max_disp_z_bracket2 = maximum(model_bracket2.current[3, :] - model_bracket2.reference[3, :]) + avg_stress_bracket1 = average_components(model_bracket1.stress) + avg_stress_bracket2 = average_components(model_bracket2.stress) + + @test min_disp_x_bracket1 ≈ -5.230704712576306e-5 atol = 1e-12 + @test min_disp_y_bracket1 ≈ -5.933993412379768e-6 atol = 1e-12 + @test max_disp_z_bracket1 ≈ 0.00014337338409010306 atol = 1e-12 + @test min_disp_x_bracket2 ≈ -0.0005079636241489688 atol = 1e-12 + @test min_disp_y_bracket2 ≈ -5.188214899938537e-5 atol = 1e-12 + @test max_disp_z_bracket2 ≈ 0.007592937380626189 atol = 1e-12 + @test avg_stress_bracket1 ≈ [-443291.51669701113 19019.88910771844 25134.91272134775 39068.427259961936 1.0434914230313826e7 1.5174866682280425e6] atol = 1.0e1 + @test avg_stress_bracket2 ≈ [-4.213214851786042e6 89029.68204894006 2.680554292983087e6 -774307.7048034652 1.735630636595213e7 416093.38218943775] atol = 1.0e1 + @test sim.controller.schwarz_iters ≈ [3, 6, 8, 10, 11, 11, 10, 12, 12, 14, 15, 15, 11, 14, 15, 16, 15, 14, 13, 10, 10, 11, 11, 10, 9, 8, 6, 8, 9, 10, 10, 11, 11, 10, 10, 9, 7, 9, 11, 11, 12, 12, 11, 9, 9, 11, 12, 12, 12, 11] atol = 0 + +end + +@testset "Schwarz AHeaD Overlap Dynamic Bracket TET4-TET4 Dissipative Newmark" begin + cp("../examples/ahead/overlap/bracket/dynamic/bracket.yaml", "bracket.yaml"; force=true) + cp("../examples/ahead/overlap/bracket/dynamic/bracket-1.yaml", "bracket-1.yaml"; force=true) + cp("../examples/ahead/overlap/bracket/dynamic/bracket-2.yaml", "bracket-2.yaml"; force=true) + cp("../examples/ahead/overlap/bracket/bracket-1-tet.g", "../bracket-1.g"; force=true) + cp("../examples/ahead/overlap/bracket/bracket-2-tet.g", "../bracket-2.g"; force=true) + input_file = "bracket.yaml" + params = YAML.load_file(input_file; dicttype=Norma.Parameters) + params["initial time"] = 0.0 + params["time step"] = 1.0e-5 + params["final time"] = 5.0e-4 + params["name"] = input_file + sim = Norma.run(params) + subsims = sim.subsims + model_bracket1 = subsims[1].model + model_bracket2 = subsims[2].model + + rm("bracket.yaml") + rm("bracket-1.yaml") + rm("bracket-2.yaml") + rm("../bracket-1.g") + rm("../bracket-2.g") + rm("bracket-1.e") + rm("bracket-2.e") + + min_disp_x_bracket1 = minimum(model_bracket1.current[1, :] - model_bracket1.reference[1, :]) + min_disp_y_bracket1 = minimum(model_bracket1.current[2, :] - model_bracket1.reference[2, :]) + max_disp_z_bracket1 = maximum(model_bracket1.current[3, :] - model_bracket1.reference[3, :]) + min_disp_x_bracket2 = minimum(model_bracket2.current[1, :] - model_bracket2.reference[1, :]) + min_disp_y_bracket2 = minimum(model_bracket2.current[2, :] - model_bracket2.reference[2, :]) + max_disp_z_bracket2 = maximum(model_bracket2.current[3, :] - model_bracket2.reference[3, :]) + avg_stress_bracket1 = average_components(model_bracket1.stress) + avg_stress_bracket2 = average_components(model_bracket2.stress) + + @test min_disp_x_bracket1 ≈ -0.00013489122345448565 atol = 1e-12 + @test min_disp_y_bracket1 ≈ -6.88670267136593e-5 atol = 1e-12 + @test max_disp_z_bracket1 ≈ 0.0019608960014893886 atol = 1e-12 + @test min_disp_x_bracket2 ≈ -0.00017674720316077086 atol = 1e-12 + @test min_disp_y_bracket2 ≈ -7.039442537440377e-5 atol = 1e-12 + @test max_disp_z_bracket2 ≈ 0.0037945898323606952 atol = 1e-12 + @test avg_stress_bracket1 ≈ [928393.0804969968 484726.67620943306 -86368.14791471219 39681.35369128554 2.8561263044046783e6 -84999.59564231828] atol = 1.0e1 + @test avg_stress_bracket2 ≈ [-498781.1969274577 380458.68521612795 342043.85822372086 18008.589711749457 1.654179334345221e6 -231776.00506447483] atol = 1.0e1 + @test sim.controller.schwarz_iters ≈ [3, 3, 4, 4, 4, 3, 3, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 3, 3] atol = 0 + +end + diff --git a/test/schwarz-ahead-overlap-dynamic-clamped.jl b/test/schwarz-ahead-overlap-dynamic-clamped.jl new file mode 100644 index 00000000..6f312058 --- /dev/null +++ b/test/schwarz-ahead-overlap-dynamic-clamped.jl @@ -0,0 +1,130 @@ +# Norma: Copyright 2025 National Technology & Engineering Solutions of +# Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, +# the U.S. Government retains certain rights in this software. This software +# is released under the BSD license detailed in the file license.txt in the +# top-level Norma.jl directory. + +using YAML + +@testset "AHeaD Overlap Dynamic Clamped HEX8" begin + cp("../examples/ahead/overlap/clamped/dynamic/clamped.yaml", "clamped.yaml"; force=true) + cp("../examples/ahead/overlap/clamped/dynamic/clamped-1.yaml", "clamped-1.yaml"; force=true) + cp("../examples/ahead/overlap/clamped/dynamic/clamped-2.yaml", "clamped-2.yaml"; force=true) + cp("../examples/ahead/overlap/clamped/clamped-1.g", "../clamped-1.g"; force=true) + cp("../examples/ahead/overlap/clamped/clamped-2.g", "../clamped-2.g"; force=true) + input_file = "clamped.yaml" + params = YAML.load_file(input_file; dicttype=Norma.Parameters) + params["initial time"] = 0.0 + t = 1.0e-4 + params["time step"] = 1.0e-6 + params["final time"] = t + + params["name"] = input_file + sim = Norma.run(params) + subsims = sim.subsims + model_clamped0 = subsims[1].model + model_clamped1 = subsims[2].model + + rm("clamped.yaml") + rm("clamped-1.yaml") + rm("clamped-2.yaml") + rm("../clamped-1.g") + rm("../clamped-2.g") + rm("clamped-1.e") + rm("clamped-2.e") + + z0 = model_clamped0.reference[3,:] + disp0_x = model_clamped0.current[1,:] - model_clamped0.reference[1,:] + disp0_y = model_clamped0.current[2,:] - model_clamped0.reference[2,:] + disp0_z = model_clamped0.current[3,:] - model_clamped0.reference[3,:] + velo0_x = model_clamped0.velocity[1,:] + velo0_y = model_clamped0.velocity[2,:] + velo0_z = model_clamped0.velocity[3,:] + acce0_x = model_clamped0.acceleration[1,:] + acce0_y = model_clamped0.acceleration[2,:] + acce0_z = model_clamped0.acceleration[3,:] + + z1 = model_clamped1.reference[3,:] + disp1_x = model_clamped1.current[1,:] - model_clamped1.reference[1,:] + disp1_y = model_clamped1.current[2,:] - model_clamped1.reference[2,:] + disp1_z = model_clamped1.current[3,:] - model_clamped1.reference[3,:] + velo1_x = model_clamped1.velocity[1,:] + velo1_y = model_clamped1.velocity[2,:] + velo1_z = model_clamped1.velocity[3,:] + acce1_x = model_clamped1.acceleration[1,:] + acce1_y = model_clamped1.acceleration[2,:] + acce1_z = model_clamped1.acceleration[3,:] + + c = sqrt(1e9/1e3); + a = 0.001; + b = 0.0; + s = 0.02; + T = 1.0e-3; + + #Create and populate exact solution vectors + n0 = size(z0)[1] + disp0_z_exact = zeros(Float64, n0) + velo0_z_exact = zeros(Float64, n0) + acce0_z_exact = zeros(Float64, n0) + for i in 1:n0 + disp0_z_exact[i] = 1/2*a*(exp(-(z0[i]-c*t-b)^2/2/s^2) + exp(-(z0[i]+c*t-b)^2/2/s^2)) - 1/2*a*(exp(-(z0[i]-c*(T-t)-b)^2/2/s^2) + exp(-(z0[i]+c*(T-t)-b)^2/2/s^2)) + velo0_z_exact[i] = c/2*a/s^2*((z0[i]-c*t-b)*exp(-(z0[i]-c*t-b)^2/2/s^2) - (z0[i]+c*t-b)*exp(-(z0[i]+c*t-b)^2/2/s^2)) + c/2*a/s^2*((z0[i]-c*(T-t)-b)*exp(-(z0[i]-c*(T-t)-b)^2/2/s^2) - (z0[i]+c*(T-t)-b)*exp(-(z0[i]+c*(T-t)-b)^2/2/s^2)) + acce0_z_exact[i] = 1/2*a*(-c^2/s^2*exp(-1/2*(z0[i]-c*t-b)^2/s^2)+1/s^4*c^2*((z0[i]-c*t-b)^2)*exp(-1/2*(z0[i]-c*t-b)^2/s^2)-c^2/s^2*exp(-1/2*(z0[i]+c*t-b)^2/s^2)+1/s^4*c^2*((z0[i]+c*t-b)^2)*exp(-1/2*(z0[i]+c*t-b)^2/s^2)) - 1/2*a*(-c^2/s^2*exp(-1/2*(z0[i]-c*(T-t)-b)^2/s^2)+1/s^4*c^2*((z0[i]-c*(T-t)-b)^2)*exp(-1/2*(z0[i]-c*(T-t)-b)^2/s^2)-c^2/s^2*exp(-1/2*(z0[i]+c*(T-t)-b)^2/s^2)+1/s^4*c^2*((z0[i]+c*(T-t)-b)^2)*exp(-1/2*(z0[i]+c*(T-t)-b)^2/s^2)) + end + disp0_z_err = norm(disp0_z_exact - disp0_z) + disp0_z_norm = norm(disp0_z_exact) + disp0_z_relerr = disp0_z_err / disp0_z_norm + velo0_z_err = norm(velo0_z_exact - velo0_z) + velo0_z_norm = norm(velo0_z_exact) + velo0_z_relerr = velo0_z_err / velo0_z_norm + acce0_z_err = norm(acce0_z_exact - acce0_z) + acce0_z_norm = norm(acce0_z_exact) + acce0_z_relerr = acce0_z_err / acce0_z_norm + + @test disp0_z_relerr ≈ 0.022031767756555413 atol = 1e-12 + @test velo0_z_relerr ≈ 0.04874736761742479 atol = 1e-12 + @test acce0_z_relerr ≈ 0.11433470809918797 atol = 1e-6 + @test norm(disp0_x) ≈ 0.0 atol = 0.0 + @test norm(disp0_y) ≈ 0.0 atol = 0.0 + @test norm(velo0_x) ≈ 0.0 atol = 0.0 + @test norm(velo0_y) ≈ 0.0 atol = 0.0 + @test norm(acce0_x) ≈ 0.0 atol = 0.0 + @test norm(acce0_y) ≈ 0.0 atol = 0.0 + + #Create and populate exact solution vectors + n1 = size(z1)[1] + disp1_z_exact = zeros(Float64, n1) + velo1_z_exact = zeros(Float64, n1) + acce1_z_exact = zeros(Float64, n1) + for i in 1:n1 + disp1_z_exact[i] = 1/2*a*(exp(-(z1[i]-c*t-b)^2/2/s^2) + exp(-(z1[i]+c*t-b)^2/2/s^2)) - 1/2*a*(exp(-(z1[i]-c*(T-t)-b)^2/2/s^2) + exp(-(z1[i]+c*(T-t)-b)^2/2/s^2)) + velo1_z_exact[i] = c/2*a/s^2*((z1[i]-c*t-b)*exp(-(z1[i]-c*t-b)^2/2/s^2) - (z1[i]+c*t-b)*exp(-(z1[i]+c*t-b)^2/2/s^2)) + c/2*a/s^2*((z1[i]-c*(T-t)-b)*exp(-(z1[i]-c*(T-t)-b)^2/2/s^2) - (z1[i]+c*(T-t)-b)*exp(-(z1[i]+c*(T-t)-b)^2/2/s^2)) + acce1_z_exact[i] = 1/2*a*(-c^2/s^2*exp(-1/2*(z1[i]-c*t-b)^2/s^2)+1/s^4*c^2*((z1[i]-c*t-b)^2)*exp(-1/2*(z1[i]-c*t-b)^2/s^2)-c^2/s^2*exp(-1/2*(z1[i]+c*t-b)^2/s^2)+1/s^4*c^2*((z1[i]+c*t-b)^2)*exp(-1/2*(z1[i]+c*t-b)^2/s^2)) - 1/2*a*(-c^2/s^2*exp(-1/2*(z1[i]-c*(T-t)-b)^2/s^2)+1/s^4*c^2*((z1[i]-c*(T-t)-b)^2)*exp(-1/2*(z1[i]-c*(T-t)-b)^2/s^2)-c^2/s^2*exp(-1/2*(z1[i]+c*(T-t)-b)^2/s^2)+1/s^4*c^2*((z1[i]+c*(T-t)-b)^2)*exp(-1/2*(z1[i]+c*(T-t)-b)^2/s^2)) + end + disp1_z_err = norm(disp1_z_exact - disp1_z) + disp1_z_norm = norm(disp1_z_exact) + disp1_z_relerr = disp1_z_err / disp1_z_norm + velo1_z_err = norm(velo1_z_exact - velo1_z) + velo1_z_norm = norm(velo1_z_exact) + velo1_z_relerr = velo1_z_err / velo1_z_norm + acce1_z_err = norm(acce1_z_exact - acce1_z) + acce1_z_norm = norm(acce1_z_exact) + acce1_z_relerr = acce1_z_err / acce1_z_norm + + @test disp1_z_relerr ≈ 0.02203176775652283 atol = 1e-12 + @test velo1_z_relerr ≈ 0.0487473676174047 atol = 1e-12 + @test acce1_z_relerr ≈ 0.11433470809930901 atol = 1e-6 + @test norm(disp1_x) ≈ 0.0 atol = 0.0 + @test norm(disp1_y) ≈ 0.0 atol = 0.0 + @test norm(velo1_x) ≈ 0.0 atol = 0.0 + @test norm(velo1_y) ≈ 0.0 atol = 0.0 + @test norm(acce1_x) ≈ 0.0 atol = 0.0 + @test norm(acce1_y) ≈ 0.0 atol = 0.0 + + @test sim.controller.schwarz_iters ≈ [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] atol = 0 + +end + + + + diff --git a/test/schwarz-ahead-overlap-dynamic-laser-weld.jl b/test/schwarz-ahead-overlap-dynamic-laser-weld.jl index f858c7c7..957044ca 100644 --- a/test/schwarz-ahead-overlap-dynamic-laser-weld.jl +++ b/test/schwarz-ahead-overlap-dynamic-laser-weld.jl @@ -6,7 +6,7 @@ using YAML -@testset "Schwarz AHeaD Overlap Dynamic Laser Weld" begin +@testset "Schwarz AHeaD Overlap Dynamic Laser Weld HEX8-HEX8 Clamped BCs" begin cp("../examples/ahead/overlap/laser-weld/dynamic/clamped/laser-weld.yaml", "laser-weld.yaml"; force=true) cp("../examples/ahead/overlap/laser-weld/dynamic/clamped/holder-0.yaml", "holder-0.yaml"; force=true) cp("../examples/ahead/overlap/laser-weld/dynamic/clamped/holder-1.yaml", "holder-1.yaml"; force=true) @@ -50,23 +50,23 @@ using YAML avg_stress_gauge = average_components(model_gauge.stress) avg_stress_holder1 = average_components(model_holder1.stress) - @test min_disp_x_holder0 ≈ -3.0733236697749744e-5 atol = 1e-6 - @test min_disp_y_holder0 ≈ -0.0006155829702431115 atol = 1e-6 - @test max_disp_z_holder0 ≈ 0.00020594161227460822 atol = 1e-6 - @test min_disp_x_gauge ≈ -6.11625728770826e-5 atol = 1e-6 - @test min_disp_y_gauge ≈ -0.0005587147296370887 atol = 1e-6 - @test min_disp_z_gauge ≈ 2.3880604363396563e-5 atol = 1e-6 - @test min_disp_x_holder1 ≈ -3.0734132231508005e-5 atol = 1e-6 - @test min_disp_y_holder1 ≈ 0.00025514717233354745 atol = 1e-6 - @test max_disp_z_holder1 ≈ 0.0002059887389275507 atol = 1e-6 + @test min_disp_x_holder0 ≈ -3.0733236697749744e-5 atol = 1e-12 + @test min_disp_y_holder0 ≈ -0.0006155829702431115 atol = 1e-12 + @test max_disp_z_holder0 ≈ 0.00020594161227460822 atol = 1e-12 + @test min_disp_x_gauge ≈ -6.11625728770826e-5 atol = 1e-12 + @test min_disp_y_gauge ≈ -0.0005587147296370887 atol = 1e-12 + @test min_disp_z_gauge ≈ 2.3880604363396563e-5 atol = 1e-12 + @test min_disp_x_holder1 ≈ -3.0734132231508005e-5 atol = 1e-12 + @test min_disp_y_holder1 ≈ 0.00025514717233354745 atol = 1e-12 + @test max_disp_z_holder1 ≈ 0.0002059887389275507 atol = 1e-12 @test avg_stress_holder0 ≈ [56175.3792091251 1.6118582225707504e6 56432.31379334061 -2152.420453309265 3.3326750781270676e-9 1.2065091337850238e-8] atol = - 1e1 + 1.0e1 @test avg_stress_gauge ≈ [12641.620130337215 1.6499174233606872e6 28966.287163254172 -179.1767306388687 -1.3967327005127079e-9 -1.079985106175825e-9] atol = - 1e1 + 1.0e1 @test avg_stress_holder1 ≈ [56175.5776544634 1.611857519176203e6 56430.374623511234 2138.110887978947 5.693916591553716e-9 -8.169333644521733e-8] atol = - 1e1 + 1.0e1 @test sim.controller.schwarz_iters ≈ [23, 27, 29, 30, 31] atol = 0 end diff --git a/test/schwarz-ahead-overlap-dynamic-notched-cylinder.jl b/test/schwarz-ahead-overlap-dynamic-notched-cylinder.jl index db2412eb..bcfd35ff 100644 --- a/test/schwarz-ahead-overlap-dynamic-notched-cylinder.jl +++ b/test/schwarz-ahead-overlap-dynamic-notched-cylinder.jl @@ -56,10 +56,10 @@ using YAML @test min_disp_z_2 ≈ 5.1726659805836905e-5 atol = 1e-6 @test avg_stress_1 ≈ [119658.24151708037 119759.96550264646 2.105505961105632e6 280369.0355588143 281504.50820556487 57168.0765508701] atol = - 1e1 + 1.0e1 @test avg_stress_2 ≈ [-101340.89672529901 -101446.28712096746 1.5977255795638144e6 121800.33493609141 122483.30918545111 37064.478126464295] atol = - 1e1 + 1.0e1 @test sim.controller.schwarz_iters ≈ [1, 1, 1, 1, 4, 4, 4, 4, 5, 5] atol = 0 end @@ -105,17 +105,17 @@ end avg_stress_1 = average_components(model_1.stress) avg_stress_2 = average_components(model_2.stress) - @test min_disp_x_1 ≈ -1.6007099461888552e-5 atol = 1e-6 - @test min_disp_y_1 ≈ -1.6007073405502337e-5 atol = 1e-6 - @test max_disp_z_1 ≈ 0.00010485387156757009 atol = 1e-6 - @test min_disp_x_2 ≈ -1.6186344441136702e-5 atol = 1e-6 - @test min_disp_y_2 ≈ -1.618628933883204e-5 atol = 1e-6 - @test min_disp_z_2 ≈ 4.895828234158239e-5 atol = 1e-6 + @test min_disp_x_1 ≈ -1.6651285885280198e-5 atol = 1e-12 + @test min_disp_y_1 ≈ -1.662806113268689e-5 atol = 1e-12 + @test max_disp_z_1 ≈ 0.00010485387156757009 atol = 1e-12 + @test min_disp_x_2 ≈ -1.6461199941086857e-5 atol = 1e-12 + @test min_disp_y_2 ≈ -1.643006006920439e-5 atol = 1e-12 + @test min_disp_z_2 ≈ 4.895828234158239e-5 atol = 1e-12 @test avg_stress_1 ≈ [74920.96247178296 72298.92321097263 1.678913240195309e6 259770.47737702358 271427.7166969666 76184.88555466678] atol = - 1e1 + 1.0e1 @test avg_stress_2 ≈ [-89472.31510791164 -89526.66568169543 1.6857645398230806e6 114694.99228486177 114706.49638144106 34816.156918097106] atol = - 1e1 - @test sim.controller.schwarz_iters ≈ [1, 1, 1, 1, 1, 3, 3, 3, 3, 3] + 1.0e1 + @test sim.controller.schwarz_iters ≈ [1, 1, 1, 1, 1, 3, 3, 3, 3, 3] atol = 0 end diff --git a/test/schwarz-ahead-overlap-dynamic-plate.jl b/test/schwarz-ahead-overlap-dynamic-plate.jl new file mode 100644 index 00000000..f1b92676 --- /dev/null +++ b/test/schwarz-ahead-overlap-dynamic-plate.jl @@ -0,0 +1,54 @@ +# Norma: Copyright 2025 National Technology & Engineering Solutions of +# Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, +# the U.S. Government retains certain rights in this software. This software +# is released under the BSD license detailed in the file license.txt in the +# top-level Norma.jl directory. + +using YAML + +@testset "Schwarz AHeaD Overlap Dynamic Plate HEX8-HEX8 Dissipative Newmark" begin + cp("../examples/ahead/overlap/plate/dynamic/plate.yaml", "plate.yaml"; force=true) + cp("../examples/ahead/overlap/plate/dynamic/plate-1.yaml", "plate-1.yaml"; force=true) + cp("../examples/ahead/overlap/plate/dynamic/plate-2.yaml", "plate-2.yaml"; force=true) + cp("../examples/ahead/overlap/plate/plate-1.g", "../plate-1.g"; force=true) + cp("../examples/ahead/overlap/plate/plate-2.g", "../plate-2.g"; force=true) + input_file = "plate.yaml" + params = YAML.load_file(input_file; dicttype=Norma.Parameters) + params["initial time"] = 0.0 + params["time step"] = 1.0e-5 + params["final time"] = 5.0e-4 + params["name"] = input_file + sim = Norma.run(params) + subsims = sim.subsims + model_plate1 = subsims[1].model + model_plate2 = subsims[2].model + + rm("plate.yaml") + rm("plate-1.yaml") + rm("plate-2.yaml") + rm("../plate-1.g") + rm("../plate-2.g") + rm("plate-1.e") + rm("plate-2.e") + + min_disp_x_plate1 = minimum(model_plate1.current[1, :] - model_plate1.reference[1, :]) + min_disp_y_plate1 = minimum(model_plate1.current[2, :] - model_plate1.reference[2, :]) + max_disp_z_plate1 = maximum(model_plate1.current[3, :] - model_plate1.reference[3, :]) + min_disp_x_plate2 = minimum(model_plate2.current[1, :] - model_plate2.reference[1, :]) + min_disp_y_plate2 = minimum(model_plate2.current[2, :] - model_plate2.reference[2, :]) + max_disp_z_plate2 = maximum(model_plate2.current[3, :] - model_plate2.reference[3, :]) + avg_stress_plate1 = average_components(model_plate1.stress) + avg_stress_plate2 = average_components(model_plate2.stress) + + @test min_disp_x_plate1 ≈ -9.921851879713967e-5 atol = 1e-12 + @test min_disp_y_plate1 ≈ -1.2983244377276493e-5 atol = 1e-12 + @test max_disp_z_plate1 ≈ 0.0006671119244265724 atol = 1e-12 + @test min_disp_x_plate2 ≈ -9.931932093781848e-5 atol = 1e-12 + @test min_disp_y_plate2 ≈ -1.6908937976650718e-5 atol = 1e-12 + @test max_disp_z_plate2 ≈ 0.0011022795117623524 atol = 1e-12 + @test avg_stress_plate1 ≈ [471598.3029312377 3758.0552427898924 -58910.05950477131 -1.3093161657870484e-6 2.154745935704122e7 5.258888212175896e-6] atol = 1.0e1 + @test avg_stress_plate2 ≈ [253926.84478024076 -22969.447947428558 -3377.0523740657545 -1.8554517555458006e-7 3.0969903938841815e6 6.773073467532717e-8] atol = 1.0e1 + @test sim.controller.schwarz_iters ≈ [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5] atol = 0 + +end + diff --git a/test/schwarz-ahead-overlap-dynamic-torsion.jl b/test/schwarz-ahead-overlap-dynamic-torsion.jl new file mode 100644 index 00000000..9b4c1739 --- /dev/null +++ b/test/schwarz-ahead-overlap-dynamic-torsion.jl @@ -0,0 +1,54 @@ +# Norma: Copyright 2025 National Technology & Engineering Solutions of +# Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, +# the U.S. Government retains certain rights in this software. This software +# is released under the BSD license detailed in the file license.txt in the +# top-level Norma.jl directory. + +using YAML + +@testset "Schwarz AHeaD Overlap Dynamic Torsion HEX8-HEX8" begin + cp("../examples/ahead/overlap/torsion/dynamic/torsion.yaml", "torsion.yaml"; force=true) + cp("../examples/ahead/overlap/torsion/dynamic/torsion-1.yaml", "torsion-1.yaml"; force=true) + cp("../examples/ahead/overlap/torsion/dynamic/torsion-2.yaml", "torsion-2.yaml"; force=true) + cp("../examples/ahead/overlap/torsion/torsion-1.g", "../torsion-1.g"; force=true) + cp("../examples/ahead/overlap/torsion/torsion-2.g", "../torsion-2.g"; force=true) + input_file = "torsion.yaml" + params = YAML.load_file(input_file; dicttype=Norma.Parameters) + params["initial time"] = 0.0 + params["time step"] = 1.0e-6 + params["final time"] = 5.0e-5 + params["name"] = input_file + sim = Norma.run(params) + subsims = sim.subsims + model_torsion1 = subsims[1].model + model_torsion2 = subsims[2].model + + rm("torsion.yaml") + rm("torsion-1.yaml") + rm("torsion-2.yaml") + rm("../torsion-1.g") + rm("../torsion-2.g") + rm("torsion-1.e") + rm("torsion-2.e") + + min_disp_x_torsion1 = minimum(model_torsion1.current[1, :] - model_torsion1.reference[1, :]) + min_disp_y_torsion1 = minimum(model_torsion1.current[2, :] - model_torsion1.reference[2, :]) + max_disp_z_torsion1 = maximum(model_torsion1.current[3, :] - model_torsion1.reference[3, :]) + min_disp_x_torsion2 = minimum(model_torsion2.current[1, :] - model_torsion2.reference[1, :]) + min_disp_y_torsion2 = minimum(model_torsion2.current[2, :] - model_torsion2.reference[2, :]) + max_disp_z_torsion2 = maximum(model_torsion2.current[3, :] - model_torsion2.reference[3, :]) + avg_stress_torsion1 = average_components(model_torsion1.stress) + avg_stress_torsion2 = average_components(model_torsion2.stress) + + @test min_disp_x_torsion1 ≈ -0.00519091582590191 atol = 1e-12 + @test min_disp_y_torsion1 ≈ -0.005190915825902 atol = 1e-12 + @test max_disp_z_torsion1 ≈ 0.00011253980579578604 atol = 1e-12 + @test min_disp_x_torsion2 ≈ -0.005191500055775736 atol = 1e-12 + @test min_disp_y_torsion2 ≈ -0.005191500055775792 atol = 1e-12 + @test max_disp_z_torsion2 ≈ 2.2341085628874158e-5 atol = 1e-12 + @test avg_stress_torsion1 ≈ [1.3260219514935364e6 1.3260219514935361e6 576316.5244135461 -3.2615768456404716e-8 -5.842014161316911e-8 1.2785433985603353e-8] atol = 1.0e1 + @test avg_stress_torsion2 ≈ [1.0718954459446592e6 1.071895445944704e6 438030.2044997991 2.0449806470423936e-8 2.283971601476272e-8 5.4674490002071255e-8] atol = 1.0e1 + @test sim.controller.schwarz_iters ≈ [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3] atol = 0 + +end + diff --git a/test/schwarz-iters.txt b/test/schwarz-iters.txt new file mode 100644 index 00000000..af061a44 --- /dev/null +++ b/test/schwarz-iters.txt @@ -0,0 +1 @@ + 3 , 6 , 8 , 10 , 11 , 11 , 10 , 12 , 12 , 14 , 15 , 15 , 11 , 14 , 15 , 16 , 15 , 14 , 13 , 10 , 10 , 11 , 11 , 10 , 9 , 8 , 6 , 8 , 9 , 10 , 10 , 11 , 11 , 10 , 10 , 9 , 7 , 9 , 11 , 11 , 12 , 12 , 11 , 9 , 9 , 11 , 12 , 12 , 12 , 11 , 3 , 3 , 4 , 4 , 4 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 4 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 3 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 3 , 3 diff --git a/test/single-ahead-bracket.jl b/test/single-ahead-bracket.jl new file mode 100644 index 00000000..bc22e4dc --- /dev/null +++ b/test/single-ahead-bracket.jl @@ -0,0 +1,37 @@ +# Norma: Copyright 2025 National Technology & Engineering Solutions of +# Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, +# the U.S. Government retains certain rights in this software. This software +# is released under the BSD license detailed in the file license.txt in the +# top-level Norma.jl directory. + +using YAML + +@testset "AHeaD Single Dynamic Bracket HEX8" begin + cp("../examples/ahead/single/bracket/dynamic/bracket.yaml", "bracket.yaml"; force=true) + cp("../examples/ahead/single/bracket/bracket.g", "../bracket.g"; force=true) + input_file = "bracket.yaml" + params = YAML.load_file(input_file; dicttype=Norma.Parameters) + params["time integrator"]["initial time"] = 0.0 + params["time integrator"]["time step"] = 1.0e-5 + params["time integrator"]["final time"] = 5.0e-4 + params["name"] = input_file + sim = Norma.run(params) + model = sim.model + + rm("bracket.yaml") + rm("../bracket.g") + rm("bracket.e") + + min_disp_x = minimum(model.current[1, :] - model.reference[1, :]) + min_disp_y = minimum(model.current[2, :] - model.reference[2, :]) + max_disp_z = maximum(model.current[3, :] - model.reference[3, :]) + avg_stress = average_components(model.stress) + + println(avg_stress) + + @test min_disp_x ≈ -0.0008933290654759424 atol = 1e-12 + @test min_disp_y ≈ -0.0001655247963407644 atol = 1e-12 + @test max_disp_z ≈ 0.0101486664023163 atol = 1e-12 + @test avg_stress ≈ [-8.971263149258394e6 6.383924802446201e6 -476409.7156016053 304437.4306066531 3.0513844880209036e7 -4.0955010966046983e6] atol = 1.0e1 +end + diff --git a/test/single-ahead-clamped.jl b/test/single-ahead-clamped.jl new file mode 100644 index 00000000..a9541c2a --- /dev/null +++ b/test/single-ahead-clamped.jl @@ -0,0 +1,74 @@ +# Norma: Copyright 2025 National Technology & Engineering Solutions of +# Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, +# the U.S. Government retains certain rights in this software. This software +# is released under the BSD license detailed in the file license.txt in the +# top-level Norma.jl directory. + +using YAML + +@testset "AHeaD Single Dynamic Clamped HEX8" begin + cp("../examples/ahead/single/clamped/dynamic/clamped.yaml", "clamped.yaml"; force=true) + cp("../examples/ahead/single/clamped/clamped.g", "../clamped.g"; force=true) + input_file = "clamped.yaml" + params = YAML.load_file(input_file; dicttype=Norma.Parameters) + params["time integrator"]["initial time"] = 0.0 + t = 1.0e-4 + params["time integrator"]["time step"] = 1.0e-6 + params["time integrator"]["final time"] = t + + params["name"] = input_file + sim = Norma.run(params) + model = sim.model + + rm("clamped.yaml") + rm("../clamped.g") + rm("clamped.e") + + z = model.reference[3,:] + disp_x = model.current[1,:] - model.reference[1,:] + disp_y = model.current[2,:] - model.reference[2,:] + disp_z = model.current[3,:] - model.reference[3,:] + velo_x = model.velocity[1,:] + velo_y = model.velocity[2,:] + velo_z = model.velocity[3,:] + acce_x = model.acceleration[1,:] + acce_y = model.acceleration[2,:] + acce_z = model.acceleration[3,:] + + c = sqrt(1e9/1e3); + a = 0.001; + b = 0.0; + s = 0.02; + T = 1.0e-3; + + #Create and populate exact solution vectors + n = size(z)[1] + disp_z_exact = zeros(Float64, n) + velo_z_exact = zeros(Float64, n) + acce_z_exact = zeros(Float64, n) + for i in 1:n + disp_z_exact[i] = 1/2*a*(exp(-(z[i]-c*t-b)^2/2/s^2) + exp(-(z[i]+c*t-b)^2/2/s^2)) - 1/2*a*(exp(-(z[i]-c*(T-t)-b)^2/2/s^2) + exp(-(z[i]+c*(T-t)-b)^2/2/s^2)) + velo_z_exact[i] = c/2*a/s^2*((z[i]-c*t-b)*exp(-(z[i]-c*t-b)^2/2/s^2) - (z[i]+c*t-b)*exp(-(z[i]+c*t-b)^2/2/s^2)) + c/2*a/s^2*((z[i]-c*(T-t)-b)*exp(-(z[i]-c*(T-t)-b)^2/2/s^2) - (z[i]+c*(T-t)-b)*exp(-(z[i]+c*(T-t)-b)^2/2/s^2)) + acce_z_exact[i] = 1/2*a*(-c^2/s^2*exp(-1/2*(z[i]-c*t-b)^2/s^2)+1/s^4*c^2*((z[i]-c*t-b)^2)*exp(-1/2*(z[i]-c*t-b)^2/s^2)-c^2/s^2*exp(-1/2*(z[i]+c*t-b)^2/s^2)+1/s^4*c^2*((z[i]+c*t-b)^2)*exp(-1/2*(z[i]+c*t-b)^2/s^2)) - 1/2*a*(-c^2/s^2*exp(-1/2*(z[i]-c*(T-t)-b)^2/s^2)+1/s^4*c^2*((z[i]-c*(T-t)-b)^2)*exp(-1/2*(z[i]-c*(T-t)-b)^2/s^2)-c^2/s^2*exp(-1/2*(z[i]+c*(T-t)-b)^2/s^2)+1/s^4*c^2*((z[i]+c*(T-t)-b)^2)*exp(-1/2*(z[i]+c*(T-t)-b)^2/s^2)) + end + disp_z_err = norm(disp_z_exact - disp_z) + disp_z_norm = norm(disp_z_exact) + disp_z_relerr = disp_z_err / disp_z_norm + velo_z_err = norm(velo_z_exact - velo_z) + velo_z_norm = norm(velo_z_exact) + velo_z_relerr = velo_z_err / velo_z_norm + acce_z_err = norm(acce_z_exact - acce_z) + acce_z_norm = norm(acce_z_exact) + acce_z_relerr = acce_z_err / acce_z_norm + + @test disp_z_relerr ≈ 0.02203179834481467 atol = 1e-12 + @test velo_z_relerr ≈ 0.048747445420986746 atol = 1e-12 + @test acce_z_relerr ≈ 0.11433498445981101 atol = 1e-6 + @test norm(disp_x) ≈ 0.0 atol = 0.0 + @test norm(disp_y) ≈ 0.0 atol = 0.0 + @test norm(velo_x) ≈ 0.0 atol = 0.0 + @test norm(velo_y) ≈ 0.0 atol = 0.0 + @test norm(acce_x) ≈ 0.0 atol = 0.0 + @test norm(acce_y) ≈ 0.0 atol = 0.0 +end + diff --git a/test/single-ahead-laser-weld.jl b/test/single-ahead-laser-weld.jl new file mode 100644 index 00000000..0f894297 --- /dev/null +++ b/test/single-ahead-laser-weld.jl @@ -0,0 +1,61 @@ +# Norma: Copyright 2025 National Technology & Engineering Solutions of +# Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, +# the U.S. Government retains certain rights in this software. This software +# is released under the BSD license detailed in the file license.txt in the +# top-level Norma.jl directory. + +using YAML + +@testset "AHeaD Single Dynamic Laser Weld HEX8 Clamped BCs" begin + cp("../examples/ahead/single/laser-weld/dynamic/clamped/laser-weld.yaml", "laser-weld.yaml"; force=true) + cp("../examples/ahead/single/laser-weld/laser-weld.g", "../../laser-weld.g"; force=true) + input_file = "laser-weld.yaml" + params = YAML.load_file(input_file; dicttype=Norma.Parameters) + params["time integrator"]["initial time"] = 0.0 + params["time integrator"]["time step"] = 0.01 + params["time integrator"]["final time"] = 0.05 + params["name"] = input_file + sim = Norma.run(params) + model = sim.model + + rm("laser-weld.yaml") + rm("../../laser-weld.g") + rm("laser-weld.e") + + min_disp_x = minimum(model.current[1, :] - model.reference[1, :]) + min_disp_y = minimum(model.current[2, :] - model.reference[2, :]) + max_disp_z = maximum(model.current[3, :] - model.reference[3, :]) + avg_stress = average_components(model.stress) + + @test min_disp_x ≈ -6.297730171953009e-5 atol = 1e-12 + @test min_disp_y ≈ -0.0006155829702431115 atol = 1e-12 + @test max_disp_z ≈ 0.0007221807237683814 atol = 1e-12 + @test avg_stress ≈ [15742.885247375629 1.6479602309168996e6 20705.484327184666 -14.635248791516172 1.5557909225756466e-8 3.578215426191114e-8] atol = 1e-6 +end + +@testset "AHeaD Single Quasistatic Laser Weld HEX8 Symmetry BCs" begin + cp("../examples/ahead/single/laser-weld/quasistatic/symmetry/laser-weld.yaml", "laser-weld.yaml"; force=true) + cp("../examples/ahead/single/laser-weld/laser-weld.g", "../../laser-weld.g"; force=true) + input_file = "laser-weld.yaml" + params = YAML.load_file(input_file; dicttype=Norma.Parameters) + params["time integrator"]["initial time"] = 0.0 + params["time integrator"]["time step"] = 0.1 + params["time integrator"]["final time"] = 0.5 + params["name"] = input_file + sim = Norma.run(params) + model = sim.model + + rm("laser-weld.yaml") + rm("../../laser-weld.g") + rm("laser-weld.e") + + min_disp_x = minimum(model.current[1, :] - model.reference[1, :]) + min_disp_y = minimum(model.current[2, :] - model.reference[2, :]) + max_disp_z = maximum(model.current[3, :] - model.reference[3, :]) + avg_stress = average_components(model.stress) + + @test min_disp_x ≈ -0.006324585400834512 atol = 1e-12 + @test min_disp_y ≈ -0.04999999999999999 atol = 1e-12 + @test max_disp_z ≈ 0.0014201639297437146 atol = 1e-12 + @test avg_stress ≈ [-124951.56298187797 1.3542079941106066e8 1.5670276966246015e6 1132.7823840653277 920346.061777385 2765.970872725516] atol = 1.0e1 +end diff --git a/test/single-ahead-notched-cylinder.jl b/test/single-ahead-notched-cylinder.jl new file mode 100644 index 00000000..37cd43bd --- /dev/null +++ b/test/single-ahead-notched-cylinder.jl @@ -0,0 +1,61 @@ +# Norma: Copyright 2025 National Technology & Engineering Solutions of +# Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, +# the U.S. Government retains certain rights in this software. This software +# is released under the BSD license detailed in the file license.txt in the +# top-level Norma.jl directory. + +using YAML + +@testset "AHeaD Single Dynamic Notched Cylinder HEX8" begin + cp("../examples/ahead/single/notched-cylinder/dynamic/notched-cylinder.yaml", "notched-cylinder.yaml"; force=true) + cp("../examples/ahead/single/notched-cylinder/notched-cylinder.g", "../notched-cylinder.g"; force=true) + input_file = "notched-cylinder.yaml" + params = YAML.load_file(input_file; dicttype=Norma.Parameters) + params["time integrator"]["initial time"] = 0.0 + params["time integrator"]["time step"] = 0.01 + params["time integrator"]["final time"] = 0.1 + params["name"] = input_file + sim = Norma.run(params) + model = sim.model + + rm("notched-cylinder.yaml") + rm("../notched-cylinder.g") + rm("notched-cylinder.e") + + min_disp_x = minimum(model.current[1, :] - model.reference[1, :]) + min_disp_y = minimum(model.current[2, :] - model.reference[2, :]) + max_disp_z = maximum(model.current[3, :] - model.reference[3, :]) + avg_stress = average_components(model.stress) + + @test min_disp_x ≈ -1.9074596682447376e-5 atol = 1e-12 + @test min_disp_y ≈ -1.907460302130043e-5 atol = 1e-12 + @test max_disp_z ≈ 0.0001566191478555093 atol = 1e-12 + @test avg_stress ≈ [50251.61286085953 50251.86478138371 2.3769801501592183e6 241114.77959964555 240866.46234339915 55675.444425864385] atol = 1e-6 +end + +@testset "AHeaD Single Quasistatic Notched Cylinder HEX8" begin + cp("../examples/ahead/single/notched-cylinder/quasistatic/notched-cylinder.yaml", "notched-cylinder.yaml"; force=true) + cp("../examples/ahead/single/notched-cylinder/notched-cylinder.g", "../notched-cylinder.g"; force=true) + input_file = "notched-cylinder.yaml" + params = YAML.load_file(input_file; dicttype=Norma.Parameters) + params["time integrator"]["initial time"] = 0.0 + params["time integrator"]["time step"] = 0.1 + params["time integrator"]["final time"] = 0.5 + params["name"] = input_file + sim = Norma.run(params) + model = sim.model + + rm("notched-cylinder.yaml") + rm("../notched-cylinder.g") + rm("notched-cylinder.e") + + min_disp_x = minimum(model.current[1, :] - model.reference[1, :]) + min_disp_y = minimum(model.current[2, :] - model.reference[2, :]) + max_disp_z = maximum(model.current[3, :] - model.reference[3, :]) + avg_stress = average_components(model.stress) + + @test min_disp_x ≈ -0.00036607877763784186 atol = 1e-12 + @test min_disp_y ≈ -0.00036607891968151035 atol = 1e-12 + @test max_disp_z ≈ 0.0032000000000000015 atol = 1e-12 + @test avg_stress ≈ [917864.3278006782 917964.6350355675 4.654754063590306e7 4.923095033584741e6 4.9175174443381205e6 1.1421705828295958e6] atol = 1.0e1 +end diff --git a/test/single-ahead-plate.jl b/test/single-ahead-plate.jl new file mode 100644 index 00000000..4c54e907 --- /dev/null +++ b/test/single-ahead-plate.jl @@ -0,0 +1,35 @@ +# Norma: Copyright 2025 National Technology & Engineering Solutions of +# Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, +# the U.S. Government retains certain rights in this software. This software +# is released under the BSD license detailed in the file license.txt in the +# top-level Norma.jl directory. + +using YAML + +@testset "AHeaD Single Dynamic Plate HEX8" begin + cp("../examples/ahead/single/plate/dynamic/plate.yaml", "plate.yaml"; force=true) + cp("../examples/ahead/single/plate/plate.g", "../plate.g"; force=true) + input_file = "plate.yaml" + params = YAML.load_file(input_file; dicttype=Norma.Parameters) + params["time integrator"]["initial time"] = 0.0 + params["time integrator"]["time step"] = 1.0e-5 + params["time integrator"]["final time"] = 5.0e-4 + params["name"] = input_file + sim = Norma.run(params) + model = sim.model + + rm("plate.yaml") + rm("../plate.g") + rm("plate.e") + + min_disp_x = minimum(model.current[1, :] - model.reference[1, :]) + min_disp_y = minimum(model.current[2, :] - model.reference[2, :]) + max_disp_z = maximum(model.current[3, :] - model.reference[3, :]) + avg_stress = average_components(model.stress) + + @test min_disp_x ≈ -0.00023921480607070472 atol = 1e-12 + @test min_disp_y ≈ -6.761422572361397e-5 atol = 1e-12 + @test max_disp_z ≈ 0.0020763045671660244 atol = 1e-12 + @test avg_stress ≈ [3.4463447201854037e6 -439317.2493568888 826668.2107678552 5.351041909307241e-6 3.4931994442008644e7 -2.3629205922285715e-8] atol = 1.0e1 +end + diff --git a/test/single-ahead-torsion.jl b/test/single-ahead-torsion.jl new file mode 100644 index 00000000..bcd2d3f9 --- /dev/null +++ b/test/single-ahead-torsion.jl @@ -0,0 +1,35 @@ +# Norma: Copyright 2025 National Technology & Engineering Solutions of +# Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, +# the U.S. Government retains certain rights in this software. This software +# is released under the BSD license detailed in the file license.txt in the +# top-level Norma.jl directory. + +using YAML + +@testset "AHeaD Single Dynamic Torsion HEX8" begin + cp("../examples/ahead/single/torsion/dynamic/torsion.yaml", "torsion.yaml"; force=true) + cp("../examples/ahead/single/torsion/torsion.g", "../torsion.g"; force=true) + input_file = "torsion.yaml" + params = YAML.load_file(input_file; dicttype=Norma.Parameters) + params["time integrator"]["initial time"] = 0.0 + params["time integrator"]["time step"] = 1.0e-6 + params["time integrator"]["final time"] = 5.0e-4 + params["name"] = input_file + sim = Norma.run(params) + model = sim.model + + rm("torsion.yaml") + rm("../torsion.g") + rm("torsion.e") + + min_disp_x = minimum(model.current[1, :] - model.reference[1, :]) + min_disp_y = minimum(model.current[2, :] - model.reference[2, :]) + max_disp_z = maximum(model.current[3, :] - model.reference[3, :]) + avg_stress = average_components(model.stress) + + @test min_disp_x ≈ -0.044380857564717574 atol = 1e-12 + @test min_disp_y ≈ -0.04438085756471812 atol = 1e-12 + @test max_disp_z ≈ 8.033797118034425e-5 atol = 1e-12 + @test avg_stress ≈ [-1.3396757511504798e6 -1.33967575115108e6 457701.97380569484 1.0842104529729113e-7 3.0323481041705237e-7 1.7932685807409144e-7] atol = 1.0e1 +end +