Skip to content

Commit d68b3ce

Browse files
committed
support metalforming
1 parent e74811e commit d68b3ce

36 files changed

+19437
-3346
lines changed

examples/Metalforming/README.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Metalforming examples
2+
~~~~~~~~~~~~~~~~~~~~~
3+
4+
These examples show how to create Metalforming models.
Lines changed: 290 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,290 @@
1+
"""
2+
Metalforming
3+
============
4+
This example shows how to use the PyDYNA ``pre`` service to create
5+
a Metalforming model. The executable file for LS-DYNA is
6+
``ls-dyna_smp_d_R13.0_365-gf8a97bda2a_winx64_ifort190.exe``.
7+
8+
"""
9+
###############################################################################
10+
# Perform required imports
11+
# ~~~~~~~~~~~~~~~~~~~~~~~~
12+
# Peform the required imports.
13+
import os
14+
import sys
15+
16+
17+
from ansys.dyna.core.pre import launch_dyna
18+
from ansys.dyna.core.pre.dynamech import (
19+
DynaMech,
20+
PartSet,
21+
Curve,
22+
ShellPart,
23+
NodeSet,
24+
Contact,
25+
Motion,
26+
ContactSurface,
27+
ShellFormulation,
28+
ContactType,
29+
ContactCategory,
30+
AnalysisType,
31+
MetalFormingAnalysis,
32+
DOF,
33+
BulkViscosity,
34+
EnergyFlag,
35+
HourglassControl,
36+
)
37+
from ansys.dyna.core.pre.dynamaterial import (
38+
MatRigid,
39+
MatTransverselyAnisotropicElasticPlastic,
40+
)
41+
from ansys.dyna.core.pre import examples
42+
from ansys.dyna.core.pre.misc import check_valid_ip
43+
# sphinx_gallery_thumbnail_path = '_static/pre/explicit/ball_plate.png'
44+
45+
###############################################################################
46+
# Start the ``pre`` service
47+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
48+
# Before starting the ``pre`` service, you must ensure that the Docker container
49+
# for this service has been started. For more information, see "Start the Docker
50+
# container for the ``pre`` service" in https://dyna.docs.pyansys.com/version/stable/index.html.
51+
#
52+
# The ``pre`` service can also be started locally, please download the latest version of
53+
# ansys-pydyna-pre-server.zip package from https://github.com/ansys/pydyna/releases and start it
54+
# refering to the README.rst file in this server package.
55+
#
56+
# Once the ``pre`` service is running, you can connect a client to it using
57+
# the host name and port. This code uses the default localhost and port
58+
# (``"localhost"`` and ``"50051"`` respectively).
59+
#
60+
hostname = "localhost"
61+
if len(sys.argv) > 1 and check_valid_ip(sys.argv[1]):
62+
hostname = sys.argv[1]
63+
solution = launch_dyna(ip = hostname)
64+
65+
###############################################################################
66+
# Start the solution workflow
67+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~
68+
# NODES and ELEMENTS are read in from the ``model.k`` file. This file
69+
# also has the *PART* defined in it, but the section and material fields are
70+
# empty to begin with.
71+
#
72+
fns = []
73+
path = examples.mf_simple_roll + os.sep
74+
fns.append(path+"model.k")
75+
solution.open_files(fns)
76+
77+
###############################################################################
78+
# Create database and control cards
79+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
80+
# For the D3plots, set simulation termination time, simulation timestep, and
81+
# output frequency.
82+
83+
solution.set_termination(termination_time=0.05)
84+
85+
mf = DynaMech(AnalysisType.NONE)
86+
solution.add(mf)
87+
88+
mfanalysis = MetalFormingAnalysis()
89+
mfanalysis.set_springback(PartSet([1]),100)
90+
mfanalysis.set_rigid_body_nodes_fast_update(fast_update=1)
91+
mf.add(mfanalysis)
92+
93+
mf.set_timestep(timestep_size_for_mass_scaled=-7e-7)
94+
mf.set_accuracy()
95+
mf.set_bulk_viscosity(bulk_viscosity_type=BulkViscosity.STANDARD_BULK_VISCOSITY_SHELL)
96+
mf.set_energy(hourglass_energy=EnergyFlag.COMPUTED,
97+
rigidwall_energy=EnergyFlag.NOT_COMPUTED,
98+
sliding_interface_energy=EnergyFlag.COMPUTED
99+
)
100+
mf.set_hourglass(HourglassControl.FLANAGAN_BELYTSCHKO_EXACT_VOLUME_INTEGRATION_SOLID)
101+
mf.set_output(print_suppression_d3hsp=True)
102+
mf.create_control_shell(esort=1,istupd=1)
103+
mf.create_control_contact(initial_penetration_check = 2,
104+
shlthk = 1,
105+
penalty_stiffness_option = 4,
106+
orien = 4,
107+
penetration_check_multiplier = 1.0)
108+
mf.set_adaptive(time_interval_refinement=2.5e-4,
109+
adaptive_error_tolerance=5.0,
110+
adaptive_type = 2,
111+
generate_adaptive_mesh_at_exit = 1,
112+
min_shell_size = 1.83,
113+
h_adaptivity_pass_flag = 1,
114+
shell_h_adapt = 5.0,
115+
fission_control_flag = -1,
116+
)
117+
118+
###############################################################################
119+
# Define materials
120+
# ~~~~~~~~~~~~~~~~
121+
# The ``dynamaterials`` class is used to define these materials: ``MAT_RIGID``,
122+
# ``MAT_TRANSVERSELY_ANISOTROPIC_ELASTIC_PLASTIC``,
123+
124+
mat_upper_punch = MatRigid(
125+
mass_density=7.83e-9,
126+
young_modulus=2.07e5,
127+
poisson_ratio=0.28,
128+
center_of_mass_constraint=1,
129+
translational_constraint=7,
130+
rotational_constraint=6,
131+
)
132+
mat_lower_cavity = MatRigid(
133+
mass_density=7.83e-9,
134+
young_modulus=2.07e5,
135+
poisson_ratio=0.28,
136+
center_of_mass_constraint=1,
137+
translational_constraint=7,
138+
rotational_constraint=6,
139+
)
140+
mat_binder = MatRigid(
141+
mass_density=7.83e-9,
142+
young_modulus=2.07e5,
143+
poisson_ratio=0.28,
144+
center_of_mass_constraint=1,
145+
translational_constraint=7,
146+
rotational_constraint=7,
147+
)
148+
crv = Curve(x=[0, 1],y=[0, 13])
149+
matblank = MatTransverselyAnisotropicElasticPlastic(
150+
mass_density=7.9e-09,
151+
young_modulus=2.07e5,
152+
yield_stress=201.3,
153+
anisotropic_hardening_parameter=-1.5930001,
154+
curve_stress = crv)
155+
156+
157+
###############################################################################
158+
# Define section properties and assign materials
159+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
160+
# Now that you have materials with the material ID corresponding to
161+
# the Part ID, you can assign these materials to the
162+
# parts. You can also define section properties, element
163+
# formulations, and constraints.
164+
#
165+
166+
blank = ShellPart(1)
167+
blank.set_element_formulation(ShellFormulation.FULLY_INTEGRATED_FAST)
168+
blank.set_material(matblank)
169+
blank.set_thickness(1.5)
170+
blank.set_integration_points(5)
171+
blank.set_shear_factor(0.833)
172+
mf.parts.add(blank)
173+
174+
upper_punch = ShellPart(2)
175+
upper_punch.set_material(mat_upper_punch)
176+
upper_punch.set_element_formulation(ShellFormulation.BELYTSCHKO_TSAY)
177+
upper_punch.set_integration_points(3)
178+
mf.parts.add(upper_punch)
179+
180+
lower_cavity = ShellPart(3)
181+
lower_cavity.set_material(mat_lower_cavity)
182+
lower_cavity.set_element_formulation(ShellFormulation.BELYTSCHKO_TSAY)
183+
lower_cavity.set_integration_points(3)
184+
mf.parts.add(lower_cavity)
185+
186+
upper_binder = ShellPart(4)
187+
upper_binder.set_material(mat_binder)
188+
upper_binder.set_element_formulation(ShellFormulation.BELYTSCHKO_TSAY)
189+
upper_binder.set_integration_points(3)
190+
mf.parts.add(upper_binder)
191+
192+
lower_binder = ShellPart(5)
193+
lower_binder.set_material(mat_binder)
194+
lower_binder.set_element_formulation(ShellFormulation.BELYTSCHKO_TSAY)
195+
lower_binder.set_integration_points(3)
196+
mf.parts.add(lower_binder)
197+
198+
199+
###############################################################################
200+
# Define one_way_surface_to_surface contacts
201+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
202+
203+
mfcontact = Contact(type=ContactType.FORMING, category=ContactCategory.ONE_WAY_SURFACE_TO_SURFACE)
204+
mfcontact.set_friction_coefficient(static=0.125, dynamic=0)
205+
mfcontact.set_extra_coefficient(viscous_damping = 20)
206+
surf1 = ContactSurface(PartSet([1]),save_interface_force = 1)
207+
surf2 = ContactSurface(PartSet([2]),save_interface_force = 1)
208+
mfcontact.set_slave_surface(surf1)
209+
mfcontact.set_master_surface(surf2)
210+
mf.contacts.add(mfcontact)
211+
212+
mfcontact = Contact(type=ContactType.FORMING, category=ContactCategory.ONE_WAY_SURFACE_TO_SURFACE)
213+
mfcontact.set_friction_coefficient(static=0.125, dynamic=0)
214+
mfcontact.set_extra_coefficient(viscous_damping = 20)
215+
surf1 = ContactSurface(PartSet([1]),save_interface_force = 1)
216+
surf2 = ContactSurface(PartSet([3]),save_interface_force = 1)
217+
mfcontact.set_slave_surface(surf1)
218+
mfcontact.set_master_surface(surf2)
219+
mf.contacts.add(mfcontact)
220+
221+
mfcontact = Contact(type=ContactType.FORMING, category=ContactCategory.ONE_WAY_SURFACE_TO_SURFACE)
222+
mfcontact.set_friction_coefficient(static=0.125, dynamic=0)
223+
mfcontact.set_extra_coefficient(viscous_damping = 20)
224+
surf1 = ContactSurface(PartSet([1]),save_interface_force = 1)
225+
surf2 = ContactSurface(PartSet([4]),save_interface_force = 1)
226+
mfcontact.set_slave_surface(surf1)
227+
mfcontact.set_master_surface(surf2)
228+
mf.contacts.add(mfcontact)
229+
230+
mfcontact = Contact(type=ContactType.FORMING, category=ContactCategory.ONE_WAY_SURFACE_TO_SURFACE)
231+
mfcontact.set_friction_coefficient(static=0.125, dynamic=0)
232+
mfcontact.set_extra_coefficient(viscous_damping = 20)
233+
surf1 = ContactSurface(PartSet([1]),save_interface_force = 1)
234+
surf2 = ContactSurface(PartSet([5]),save_interface_force = 1)
235+
mfcontact.set_slave_surface(surf1)
236+
mfcontact.set_master_surface(surf2)
237+
mf.contacts.add(mfcontact)
238+
239+
###############################################################################
240+
# Define nodal single point constraints.
241+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
242+
# Constrain the nodes in a list of single point constraints (spc).
243+
244+
spc = [600,593]
245+
mf.boundaryconditions.create_spc(NodeSet(spc),tx = False, tz = False,ry=False)
246+
247+
mf.boundaryconditions.create_imposed_motion(
248+
PartSet([2]),
249+
Curve(x=[0,100], y=[600,600]),
250+
dof=DOF.Y_ROTATIONAL,
251+
motion=Motion.VELOCITY,
252+
scalefactor=-1,
253+
)
254+
mf.boundaryconditions.create_imposed_motion(
255+
PartSet([3]),
256+
Curve(x=[0,100], y=[600,600]),
257+
dof=DOF.Y_ROTATIONAL,
258+
motion=Motion.VELOCITY,
259+
scalefactor=1,
260+
)
261+
###############################################################################
262+
# Define applied forces.
263+
# ~~~~~~~~~~~~~~~~~~~~~~~~~
264+
265+
mf.loads.create_nodal_force(
266+
NodeSet([695,696,697,698,694,693,692]),
267+
load_curve = Curve(x=[0,0.015,0.016,100],y=[100,100,0,0])
268+
)
269+
270+
###############################################################################
271+
# Define database outputs
272+
# ~~~~~~~~~~~~~~~~~~~~~~~
273+
# Define the frequency for the D3PLOT file and write out the input file.
274+
#
275+
solution.set_output_database(glstat=0.00025, matsum=0.00025, rcforc=0.00025)
276+
solution.create_database_binary(dt=5e-4)
277+
serverpath = solution.save_file()
278+
279+
###############################################################################
280+
# Download output file
281+
# ~~~~~~~~~~~~~~~~~~~~
282+
# Download output file from Docker image for the server to
283+
# your local ``<working directory>/output/`` location.
284+
285+
serveroutfile = '/'.join((serverpath,"model.k"))
286+
downloadpath = os.path.join(os.getcwd(), "output")
287+
if not os.path.exists(downloadpath):
288+
os.makedirs(downloadpath)
289+
downloadfile = os.path.join(downloadpath,"model.k")
290+
solution.download(serveroutfile,downloadfile)

0 commit comments

Comments
 (0)