Source code for ansys.dyna.core.pre.dynasale

"""
Airbag API
==========

Module for creating a S-ALE (Structured ALE) DYNA input deck.
"""

from enum import Enum
import logging

from .dynabase import *  # noqa : F403


[docs] class AdvectionMethod(Enum):
[docs] DONOR_CELL_WITH_HALF_INDEX_SHIFT = 1
[docs] VAN_LEER_WITH_HIS = 2
[docs] DONOR_CELL_WITH_HIS = 3
[docs] FINITE_VOLUME_METHOD = 6
[docs] class FillDirection(Enum):
[docs] INSIDE_THE_GEOMETRY = 0
[docs] OUTSIDE_THE_GEOMETRY = 1
[docs] class ControlPoint: """Provides spacing information for generating a 3D S-ALE mesh. Parameters ---------- number : int Control point node number. position : float Control point position. ratio : float Ratio for progressive mesh spacing. """ def __init__(self, number, position, ratio):
[docs] self.number = number
[docs] self.position = position
[docs] self.ratio = ratio
[docs] class StructuredMesh(BaseObj): """Generates a structured 2D or 3D mesh and invokes the S-ALE solver.""" def __init__(self, control_points_x, control_points_y, control_points_z):
[docs] self.stub = DynaBase.get_stub()
[docs] self.control_points_x = control_points_x
[docs] self.control_points_y = control_points_y
[docs] self.control_points_z = control_points_z
[docs] self.refine_factor_x = 1
[docs] self.refine_factor_y = 1
[docs] self.refine_factor_z = 1
[docs] self.fillings = []
[docs] self.type = "structured_mesh"
[docs] def fill( self, material, geometry_type="NULL", nsample=4, define_geometry_parameters=[0, 0, 0, 0, 0], inout=FillDirection.INSIDE_THE_GEOMETRY, vid=0, reference_pressure=0, ): """Perform volume-filling operations on a S-ALE mesh. Parameters ---------- material_name : string Material name. geometry_type : string Geometry type. The default is ``"Null"``. Options are: - BOXCOR - BOXCPT - CYLINDER - PARTSET - PART - PLANE - SEGSET - SPHERE nsample : int, optional Number of sampling points. The default is ``4``. define_geometry_parameters : list List of values having different definitions for different options. The default is ``[0, 0, 0, 0, 0]``. in_out : int, optional Flag for whether to fill inside or outside of the geometry. The default is ``INSIDE_THE_GEOMETRY``. vid : int, optional Flag for assigning the initial velocity to the material filling the domain. The default is ``0``. reference_pressure : Returns ------- bool ``True`` when successful, ``False`` when failed. """ self.fillings.append( [ material, geometry_type, nsample, define_geometry_parameters, inout, vid, reference_pressure, ] )
[docs] def refine(self, refine_factor_x=1, refine_factor_y=1, refine_factor_z=1): """Refine existing S-ALE meshes. Parameters ---------- refine_factor_x : int, optional Refinement factor for the x-direction. The default is ``1``. refine_factor_y : int, optional Refinement factor for the y-direction. The default is ``1``. refine_factor_z : int, optional Refinement factor for the z-direction. The default is ``1``. """ self.refine_factor_x = refine_factor_x self.refine_factor_y = refine_factor_y self.refine_factor_z = refine_factor_z
[docs] def initial_detonation(self, detonation_point): """Define a point for initiating the location of a high-explosive detonation. Parameters ---------- detonation_point : Point Coordinates (x,y,z) of the detonation point. """ self.detonation_point = detonation_point
[docs] def create(self): """Create a mesh.""" nx = [] xx = [] ratiox = [] for i in range(len(self.control_points_x)): nx.append(self.control_points_x[i].number) xx.append(self.control_points_x[i].position) ratiox.append(self.control_points_x[i].ratio) ny = [] xy = [] ratioy = [] for i in range(len(self.control_points_y)): ny.append(self.control_points_y[i].number) xy.append(self.control_points_y[i].position) ratioy.append(self.control_points_y[i].ratio) nz = [] xz = [] ratioz = [] for i in range(len(self.control_points_z)): nz.append(self.control_points_z[i].number) xz.append(self.control_points_z[i].position) ratioz.append(self.control_points_z[i].ratio) ret = self.stub.ALECreateStructuredMeshCtrlPoints( ALECreateStructuredMeshControlPointsRequest(icase=2, sfo=1, n=nx, x=xx, ratio=ratiox) ) cpidx = ret.cpid ret = self.stub.ALECreateStructuredMeshCtrlPoints( ALECreateStructuredMeshControlPointsRequest(icase=2, sfo=1, n=ny, x=xy, ratio=ratioy) ) cpidy = ret.cpid ret = self.stub.ALECreateStructuredMeshCtrlPoints( ALECreateStructuredMeshControlPointsRequest(icase=2, sfo=1, n=nz, x=xz, ratio=ratioz) ) cpidz = ret.cpid ret = self.stub.ALECreateStructuredMesh( ALECreateStructuredMeshRequest(nbid=2000001, ebid=2000001, cpidx=cpidx, cpidy=cpidy, cpidz=cpidz) ) meshid = ret.meshid partid = ret.partid logging.info(f"ALE Structured mesh {meshid} Created...") for obj in self.fillings: material = obj[0] geometry_type = obj[1] nsample = obj[2] define_geometry_parameters = obj[3] inout = obj[4] vid = obj[5] reference_pressure = obj[6] material.create(self.stub) self.stub.ALECreateStructuredMultiMaterialGroup( ALECreateStructuredMultiMatGroupRequest( nmmgnm=material.name, mid=material.material_id, eosid=material.eos_id, pref=reference_pressure, ) ) logging.info(f"Material {material.name} Created...") if geometry_type.upper() != "NULL": self.stub.ALECreateStructuredMeshVolumeFilling( ALECreateStructuredMeshVolumeFillingRequest( mshid=meshid, ammgto=material.name, nsample=nsample, geom=geometry_type.upper(), vid=vid, inout=inout.value, e=define_geometry_parameters, ) ) logging.info(f"Material {material.name} filled in Mesh {meshid}...") self.stub.ALECreateStructuredMeshRefine( ALECreateStructuredMeshRefineRequest( mshid=meshid, ifx=self.refine_factor_x, ify=self.refine_factor_y, ifz=self.refine_factor_z, ) ) logging.info(f"Mesh {meshid} Refined...") dpoint = [self.detonation_point.x, self.detonation_point.y, self.detonation_point.z] self.stub.CreateInitDetonation(InitDetonationRequest(pid=partid, coord=dpoint, lt=0)) logging.info("Location of high explosive detonation Defined...")
[docs] class DynaSALE(DynaBase): """Sets up the S-ALE simulation process.""" def __init__(self): DynaBase.__init__(self) self.stub.CreateDBSALE(DBSALERequest(switch=1))
[docs] def set_termination(self, endtime): """Set the time for ending the simulation. Parameters ---------- endtime : float Time for ending the simulation. Returns ------- bool ``True`` when successful, ``False`` when failed. """ self.stub.CreateTermination(TerminationRequest(endtim=endtime))
[docs] def set_output_interval(self, database_plot_interval): """Request binary output. Parameters ---------- database_plot_interval : float Time interval between output states. Returns ------- bool ``True`` when successful, ``False`` when failed. """ self.stub.CreateDBBinary(DBBinaryRequest(filetype="D3PLOT", dt=database_plot_interval))
[docs] def set_analysis_type( self, num_of_cycle=1, method=AdvectionMethod.DONOR_CELL_WITH_HALF_INDEX_SHIFT, background_pressure=0, ): """Set the analysis type. Parameters ---------- num_of_cycle : float, optional Total time of simulation for the fluid problem. The default is ``1``. method : float, optional Time step for the fluid problem. The default is ``DONOR_CELL_WITH_HALF_INDEX_SHIFT``. background_pressure : int, optional Reference pressure for computing the internal forces. The default is ``0``. Returns ------- bool ``True`` when successful, ``False`` when failed. """ ret = self.stub.ALECreateControl( ControlALERequest( dct=0, nadv=num_of_cycle, meth=method.value, afac=0, end=1e20, aafac=1, vfact=1e-6, pref=background_pressure, ) ) logging.info("Setup Analysis...") return ret
[docs] def set_output_database(self, matsum=0, glstat=0): """Obtain output files containing the results. Parameters ---------- matsum : float, optional Time interval between outputs of part energies. The default is ``0``. glstat : float, optional Time interval between outputs of global statistics and energies. The default is ``0``. Returns ------- bool ``True`` when successful, ``False`` when failed. """ if matsum > 0: self.stub.CreateDBAscii(DBAsciiRequest(type="MATSUM", dt=matsum, binary=1, lcur=0, ioopt=0)) if glstat > 0: self.stub.CreateDBAscii(DBAsciiRequest(type="GLSTAT", dt=glstat, binary=1, lcur=0, ioopt=0)) ret = 1 logging.info("Output Setting...") return ret
[docs] def save_file(self): """Save keyword files. Returns ------- bool ``True`` when successful, ``False`` when failed. """ self.set_energy( hourglass_energy=EnergyFlag.COMPUTED, sliding_interface_energy=EnergyFlag.COMPUTED, ) DynaBase.save_file(self)