! TITLE: msh_algorithm2.mac (MESH) ! ! ! Added code to assign material attributes to volumes or areas. ! ! OBJECTIVE: ! ! This sub-macro is a mesh algorithm for automatic free or mapped meshing ! of areas or volumes and maximizing brick meshing capability. ! ! ! COMMAND SYNTAX: ! ! (1) (2) (3) (4) (5) (6) (7) ! MSH_ALGORITHM, perflsz, perfmsh, mstyp, mshdens, elmszovr, atargov, etpa, ! ! etpv, elmnl, elmxl, mtrl, rl, ecs, volsel, radrot, ! (8) (9) (10) (11) (12) (13) (14) (15) ! ! varcang, ell ! (16) (17) ! ! ! ARGUMENTS: ! ! (1) perflsz = perform line sizing options: ! ! 0 = do not perform line sizing ! 1 = perform line sizing (over-ride previous line sizing) ! -1 = perform line sizing (DO NOT over-ride previous line ! sizing) ! ! (2) perfmsh = perform mesh options: ! ! 0 = do not perform meshing operation ! ! 1 = perform area mesh operation only ! ! 2 = perform volume mesh operation only (use area ! sweeping; i.e., using the VSWEEP command) ! ! 3 = perform area and volume mesh operations ! (using area sweeping; i.e., using the VSWEEP ! command) ! ! 4 = free volume mesh ! ! 5 = transition mesh ! ! (3) mstyp = mesh type: ! ! 0 (or blank) = free mesh ! ! 1 = map mesh ! ! (4) mshdens = mesh density. If the desired mesh density is coarse or ! fine, then this parameter will create the desired mesh. ! ! If the desired mesh density is fine, the line sizing ! algorithm will size all the lines that are less than or ! equal to 2.5 times the minimum element edge length, ESIZE, ! to having only 1 element along its edge length. ! ! If the desired mesh density is coarse, the line sizing ! algorithm will size all the lines that are less than or ! equal to 3 times the minimum element edge length, ESIZE, ! to having 2 or 3 elements along its edge length, depending ! on the algorithm criteria. ! ! This will aid in selecting the proper mesh relevant to the ! type of analysis being performed (e.g., in stress analysis, ! the desired mesh density may need to be fine; in dynamic ! analysis, it may suffice that the required mesh density to ! be coarse). ! ! 0 (or blank) = fine mesh density [default] ! ! 1 = coarse mesh density ! ! n = user defined divisions for all lines less ! than or equal to 3.0*ESZ_. ! ! If MSHDENS is assigned any numerical value (n) other ! than 0 or 1, then any line that is less than or equal ! to 3 times ESIZE is sized that numerical value line ! divisions. ! ! (5) elmszovr = element sizing over-ride parameter. In volume sweeping ! operations (PERFMSH=2 and PERFMSH=3), the number of ! elements swept in a volume length is normally calcu- ! lated by the algorithm based on an optimum element as- ! pect ratio approximately equal to 1. However, if a ! desired number of elements is specified in this par- ! ameter, then this value will over-ride the calculated ! value and sweep this number of elements. ! ! If ELMSZVOR is a negative number, then the algorithm ! will sweep the volume a number of elements with a user ! specified aspect ratio (the numerical value of ELMSZVOR) ! that are able to be fit along the volume sweep length. ! (e.g., if ELMSZVOR = -3, then the elements along the ! sweep length will be 3 times longer than ELMNL) ! ! (6) atargov = area target over-ride parameter. In the case where the ! source and target areas of the VSWEEP operation share a ! common keypoint(s), the algorithm will fail and the area ! target must be specified by the user. Specifying the ! target area, ATARGOV, will over-ride the target selec- ! tion algorithm and sweep the volume in question from the ! selected mesh area to the target area, ATARGOV. When ! using this option, VOLSEL must be specified; i.e., the ! volume that is to be swept must be specified by VOLSEL. ! ! (7) etpa = element type to be used for area meshing ! ! (8) etpv = element type to be used for volume meshing ! ! (9) elmnl = element minimum edge length ! ! (10) elmxl = element maximum edge length ! ! (11) mtrl = material properties # to be used in meshing operations ! ! (12) rl = real constant set #, if applicable ! ! (13) ecs = coordinate system # for associated elements (element ! coordinate systems) ! ! (14) volsel = If the selected area(s) for meshing are attached to more ! than one volume, the desired volume for meshing is speci- ! fied in this parameter. In this case, each volume will ! have to be meshed separately with the MSH_ALGORITHM ! command. ! ! (15) radrot = user specified radius of rotation at which the number of ! elements, swept through a known volume arc angle, VARCANG, ! may be calculated. This parameter is specified when sweep- ! ing a rotated volume, and allows for control of the number ! of elements in an arc angle. ! ! (16) varcang = volume arc angle of a rotated volume(s) ! ! (17) ell = element longitudinal length. This parameter specifies the ! element edge length used to calculate the number of elements ! swept along the length of a rotated volume. This may be used ! in adjoining rotated volumes with different element edge ! lengths specified in their meshes. This allows for all ! volumes to have the same number of swept elements, allowing ! their meshes to interface. This is only valid when RADROT ! and VARCANG are specified. ! ! ! DESCRIPTION: ! ! This sub-macro allows for uniform automatic free meshing of areas and volumes ! to maximize brick meshing capability, and keeping element aspect ratios and ! angles to reasonable values. Only the areas that are to be free meshed should ! be selected for the free meshing operations. ! ! For mapped meshing, the area must have 4 sides, in which case the algor- ! ithm will size the lines based on the specified minimum element edge ! length parameter 'elmnl'. Only the areas that are to be map meshed should ! be selected for mapped mesh operations. Fot either free or mapped area ! meshing only, use option PERFMSH=1. If line sizing is desired, but no ! meshing operation, then use options PERFLSZ=1 and PERFMSH=0. See the ! argument descriptions below for all available options. ! ! When meshing a volume(s) using option PERFMSH=2, an area or set of areas ! must be selected that have pre-existing meshes. The algorithm will then ! determine the opposite side of the volume that each selected area is ! attached to, and sweep the mesh accordingly. ! ! When meshing a volume(s) using option PERFMSH=3, an area or set of areas ! must be selected for area meshing. The algorithm will then mesh the select- ! ed areas, determine the opposite side of the volume, and sweep the mesh ! accordingly. ! ! If a selected area is attached to more than one volume, the algorithm will ! sweep both volumes (if possible). However, the user may specify the ! desired volume to mesh by specifying the argument, 'VOLSEL'. In this case, ! each volume that is specified by 'VOLSEL' must be meshed separately using ! this command; i.e., area and/or volume mesh one area at a time. (See below) ! ! If volume free meshing or volume transition meshing is desired, then op- ! tions PERFMSH=4 or PERFMSH=5, respectively, may be chosen. If either of ! these options are specified, then the only other arguments necessary for ! this command are: ! ! etpv (element type for volume meshing) ! elmnl (element minimum edge length) ! elmxl (element maximum edge length) ! ! When sweeping elements through a set of volumes that were created by rot- ! ating a set of areas about an axis, it is necessary that all of the volumes ! contain the same number of elements through their swept arc angles, regard- ! less of their different arc lengths. To acheive this end, the last two arg- ! uments, RADROT and VARCANG, should be specified. RADROT allows the user to ! choose the radius at which the most square elements may be created. This ! is done to 'average out' the effect of volume element stretching as a re- ! sult of volume sweeping through a range of radii at a given arc angle. The ! arc angle that the volumes were rotated through is specified in VARCANG. ! By using these arguments, the user can control the element 'stretching' en- ! countered in a rotated volume, and localize it such that it is minimized ! throughout. Again, if a selected area (or areas) is attached to more than ! one volume, the algorithm will sweep both volumes, but the user may specify ! the desired volume to mesh by specifying the argument, 'VOLSEL'. Each vol- ! ume that is specified by 'VOLSEL' must be meshed separately using this ! command. ! ! In the case where it is desired to know the ELMNL value used in a preceding ! mesh operation, a parameter, ELLHNDOF (ELement Length HaND-OFf), stores the ! ELMNL value of the last MSH_ALGORITHM operation. This parameter "hands_off" ! this value to a future MSH_ALGORITHM operation. It is used for an ESIZE ! parameter in a sweep operation if a line is shared by two different vol- ! umes. If this shared line is already meshed in an area of one volume, and ! elements are swept along its length in the other volume, this parameter ! will allow for the elements sized in the area mesh to merge with the ele- ! ments of the swept volume by keeping the number of elements swept equal to ! the number of elements sized in the area mesh operation operation. ! ! ** NOTE: All mapped meshing should be performed prior to ! the free meshing operations. Be sure that you have ! a proper selected set prior to execution of this ! command or the operation will fail, resulting in ! exiting from the ANSYS session. ! ! ! *get,prkey_,active,0,prkey /nopr ! perflsz=arg1 perfmsh=arg2 mstyp=arg3 mshdens=arg4 elmszovr=arg5 atargov=arg6 etpa=arg7 etpv=arg8 elmnl=arg9 elmxl=ar10 ! *if,attrmat_,eq,0,then mtrl=ar11 *else *if,ar11,eq,0,then mtrl=attrmat_ *else mtrl=ar11 *endif *endif ! rl=ar12 ecs=ar13 volsel=ar14 radrot=ar15 varcang=ar16 ell_=ar17 ! ! esize,,1 ! set element size default ! *if,varcang,ne,0,then *if,radrot,ne,0,then *if,ell_,ne,0,then _sarc=radrot*(pi/2) _nelm90=nint(_sarc/ell_) _nelmrot=nint(varcang/(90/_nelm90)) *else _sarc=radrot*(pi/2) _nelm90=nint(_sarc/elmnl) _nelmrot=nint(varcang/(90/_nelm90)) *endif *endif *endif ! ! *if,perfmsh,eq,1,then ! _astrchk=1 ! area storage check parameter _amchk=1 ! area mesh check parameter _vmschk=0 ! volume mesh by sweep check parameter _vmfchk=0 ! volume mesh by free-mesh check parameter _vmtchk=0 ! volume mesh by transition-mesh check parameter ! cm,mshaset,area ! *elseif,perfmsh,eq,2,then ! perflsz=0 _astrchk=1 _amchk=0 _vmschk=1 _vmfchk=0 _vmtchk=0 ! cm,mshaset,area ! *elseif,perfmsh,eq,3,then ! _astrchk=1 _amchk=1 _vmschk=1 _vmfchk=0 _vmtchk=0 ! cm,mshaset,area ! *elseif,perfmsh,eq,4,then ! *if,perflsz,ne,0,then *if,perflsz,eq,1,then perflsz=0 lresiz_=1 *elseif,perflsz,eq,-1,then perflsz=0 lresiz_=0 *endif *else lresiz_=1 *endif ! _vmfchk=1 _amchk=0 _astrchk=0 _vmschk=0 _vmtchk=0 cm,mshvset,volu ! *elseif,perfmsh,eq,5,then ! *if,perflsz,ne,0,then *if,perflsz,eq,1,then perflsz=0 lresiz_=1 *elseif,perflsz,eq,-1,then perflsz=0 lresiz_=0 *endif *else lresiz_=1 *endif ! _vmtchk=1 _amchk=0 _astrchk=0 _vmschk=0 _vmfchk=0 cm,mshvset,volu ! *elseif,perfmsh,eq,0,then ! *if,perflsz,eq,0,then perflsz=1 *endif ! _astrchk=1 _amchk=0 _vmschk=0 _vmfchk=0 _vmtchk=0 cm,mshaset,area ! *endif ! ! *if,perflsz,eq,0,then _slchk=0 *else *if,perflsz,eq,1,then lresiz_=1 ! resize lines check parameter *elseif,perflsz,eq,-1,then lresiz_=0 *endif ! _slchk=1 ! size lines check parameter ! *if,mstyp,eq,0,then _slfchk=1 ! size line by free-mesh check parameter _slmchk=0 ! size line by map-mesh check parameter *elseif,mstyp,eq,1,then _slfchk=0 _slmchk=1 *endif *endif ! ! *if,_astrchk,eq,1,then ! create mesh-area array ! ! entity_array,'a','msha','array' acount=ecount ! ! *endif ! (_astrchk) ! ! *if,_slchk,eq,1,then ! size lines algorithm *if,_slfchk,eq,1,then ! ! ! ! (1) (2) (3) (4) (5) ! LN_SIZE, esize, mshtyp, selctopt, mshdens, lresize, ! ln_size,elmnl,mshtyp,'msha',mshdens,lresiz_ ! ! *endif ! (_slfchk) ! ! *if,_slmchk,eq,1,then ! ! ! ! ! (1) (2) (3) (4) (5) ! LN_SIZE, esize, mshtyp, selctopt, mshdens, lresize, ! ln_size,elmnl,mshtyp,'msha',mshdens,lresiz_ ! ! *endif ! (_slmchk) *endif ! (_slchk) ! ! ! *if,_amchk,eq,1,then ! ! asel,s,area,,mshaset desize,,,,,,elmnl,elmxl, mshkey,mstyp ! entity_array,'a','mshaset_','array' ! *do,mnp_,1,ecount,1 asel,s,area,,mshaset_(mnp_,1) ! *get,amat_,area,mshaset_(mnp_,1),attr,mat *get,areal_,area,mshaset_(mnp_,1),attr,real *get,atyp_,area,mshaset_(mnp_,1),attr,type ! *if,amat_,ne,0,then *if,ar11,eq,0,then mtrl=0 *endif *endif ! *if,mtrl,eq,0,then mtrl=amat_ *endif ! *if,rl,eq,0,then rl=areal_ *endif ! *if,etpa,eq,0,then etpa=atyp_ *endif ! aatt,mtrl,rl,etpa,ecs ! amesh,mshaset_(mnp_,1) *enddo ! cmsel,s,mshaset *set,mshaset_(1), ! ! *endif ! (_amchk) ! ! ! *if,_vmschk,eq,1,then ! ! ! asel,s,area,,mshaset ! select all areas to be meshed and swept ! *do,im,1,acount,1 ! asel,s,area,,msha(im,1) ! select each area to be meshed and swept vsla,s ! select volume(s) attached to area ! *if,volsel,ne,0,then ! reselect volume to be swept, if more than 1 vsel,r,volu,,volsel *endif ! *if,atargov,eq,0,then ! entity_array,'v','vmsh_set','array' ! create array of volumes to be swept v_count=ecount ! retrieve volume count ! *do,jm,1,v_count,1 ! vsel,s,volu,,vmsh_set(jm,1) ! select volume aslv,s ! select all areas attached to volume ! entity_array,'a','v_aset','array' ! store all areas in an array a_count=ecount ! retrieve area count ! *do,jjjj,1,a_count,1 ! transpose mesh area to 1st position ! *if,v_aset(jjjj,1),eq,msha(im,1),then *if,jjjj,eq,1,then *exit *else a_hold=v_aset(1,1) v_aset(1,1)=msha(im,1) v_aset(jjjj,1)=a_hold *exit *endif *endif *enddo ! *do,jjjj,1,a_count,1 ! asel,s,area,,v_aset(jjjj,1) ! select each individual area lsla,s ! entity_array,'l','a_lset%jjjj%','array' ! store lines in an array l_cnt%jjjj%=ecount ! retrieve line count *enddo ! ! *do,jjjj,2,a_count,1 ! from array '2' to array 'a_count' ! *do,kkkk,1,l_cnt1,1 ! from element '1' of 1st to 'l_cnt1' ! *do,llll,1,l_cnt%jjjj%,1 ! from element '1' to 'l_cntN' ! *if,a_lset%jjjj%(llll,1),eq,a_lset1(kkkk,1),then ! exchk=1 ! do-loop exit check parameter *exit *else *if,(kkkk*llll),eq,(l_cnt1*l_cnt%jjjj%),then atarg=v_aset(jjjj,1) targindx=jjjj exchk=-1 *endif *endif *enddo ! *if,exchk,eq,1,then *set,exchk, *exit *endif *enddo ! *if,exchk,eq,-1,then *set,exchk, *exit *endif *enddo ! ! vsel,s,volu,,vmsh_set(jm,1) ! select all lines of mesh volume aslv,s lsla,s cm,v_lset,line ! *do,ijk,1,l_cnt1,1 ! unselect lines of mesh area lsel,u,line,,a_lset1(ijk,1) *enddo ! *do,ijk,1,l_cnt%targindx%,1 ! unselect lines of target area lsel,u,line,,a_lset%targindx%(ijk,1) *enddo ! max_enty_dim,'l' ! retrieve max length of remaining lines ! *if,max_leng,le,2.0*elmnl,then ! size lines for extrusion nelm=nelm_1 *elseif,max_leng,le,mshfctr*elmnl,then nelm=nelm_2 *else nelm=nint(max_leng/elmnl) *endif ! *if,varcang,ne,0,then ! If radius of rotation & volume arc *if,radrot,ne,0,then ! angle are specified, then size esize,,_nelmrot ! according to rotation arc length. *endif *else esize,,nelm ! Otherwise, use calculated number *endif ! for extrusion. ! *if,elmszovr,ne,0,then ! If number of elements in extrusion *if,elmszovr,gt,0,then ! is specified (over-ride calculated), esize,,elmszovr ! then use 'elmszovr' for extrusion. *elseif,elmszovr,lt,0,then ! If 'elmszovr' is negative, then ! calculate the number of elements in ! the line that will give you an aspect ! ratio equal to the absolute value of ! 'elmszovr'. nelm=nint(max_leng/((abs(elmszovr))*elmnl)) esize,,nelm *endif *endif ! *get,amat_,area,msha(im,1),attr,mat *get,areal_,area,msha(im,1),attr,real *get,aesys_,area,msha(im,1),attr,esys ! *if,rl,eq,0,then rl=areal_ *endif ! cm,vmshset_,volu vsel,s,volu,,vmsh_set(jm,1) vatt,amat_,areal_,etpv,aesys_ cmsel,s,vmshset_ ! vsweep,vmsh_set(jm,1),msha(im,1),atarg,0 ! sweep volume ! *if,jm,eq,v_count,then ! reset volume array if last volume *set,vmsh_set(1), *endif ! *do,ijk,1,a_count,1 ! reset area-lines array *set,a_lset%ijk%(1), *enddo ! *set,v_aset(1), ! reset volume-areas array *enddo *else atarg=atargov ! vsel,s,volu,,volsel aslv,s lsla,s ! asel,s,area,,msha(im,1) asel,a,area,,atarg lsla,u ! max_enty_dim,'l' ! retrieve max length of remaining lines ! *if,max_leng,le,2.0*elmnl,then ! size lines for extrusion nelm=nelm_1 *elseif,max_leng,le,mshfctr*elmnl,then nelm=nelm_2 *else nelm=nint(max_leng/elmnl) *endif ! *if,varcang,ne,0,then ! If radius of rotation & volume arc *if,radrot,ne,0,then ! angle are specified, then size esize,,_nelmrot ! according to rotation arc length. *endif *else esize,,nelm ! Otherwise, use calculated number *endif ! for extrusion. ! *if,elmszovr,ne,0,then ! If number of elements in extrusion *if,elmszovr,gt,0,then ! is specified (over-ride calculated), esize,,elmszovr ! then use 'elmszovr' for extrusion. *elseif,elmszovr,lt,0,then ! If 'elmszovr' is negative, then ! calculate the number of elements in ! the line that will give you an aspect ! ratio equal to the absolute value of ! 'elmszovr'. nelm=nint(max_leng/((abs(elmszovr))*elmnl)) esize,,nelm *endif *endif ! *get,amat_,area,msha(im,1),attr,mat *get,areal_,area,msha(im,1),attr,real *get,aesys_,area,msha(im,1),attr,esys ! *if,rl,eq,0,then rl=areal_ *endif ! cm,vmshset_,volu vsel,s,volu,,volsel vatt,amat_,areal_,etpv,aesys_ cmsel,s,vmshset_ ! vsweep,volsel,msha(im,1),atarg,0 ! sweep volume *endif *enddo ! *if,_amchk,eq,1,then *do,im_,1,acount,1 asel,s,area,,msha(im_,1) aclear,all *enddo *endif ! cmdele,vmshset_ ! ! *endif ! (_vmschk) ! ! ! *if,_vmfchk,eq,1,then ! ! ! vsel,s,volu,,mshvset aslv,s ! ! (1) (2) (3) (4) (5) ! LN_SIZE, esize, mshtyp, selctopt, mshdens, lresize, ! ln_size,elmnl,mshtyp,'a',mshdens,lresiz_ ! desize,,,,,,elmnl,elmxl, ! vsel,s,volu,,mshvset desize,,,,,,elmnl,elmxl, mshkey,0 ! entity_array,'v','mshvset_','array' ! *do,mnp_,1,ecount,1 vsel,s,volu,,mshvset_(mnp_,1) ! *get,vmat_,volu,mshvset_(mnp_,1),attr,mat *get,vreal_,volu,mshvset_(mnp_,1),attr,real *get,vtyp_,volu,mshvset_(mnp_,1),attr,type ! *if,vmat_,ne,0,then *if,ar11,eq,0,then mtrl=0 *endif *endif ! *if,mtrl,eq,0,then mtrl=vmat_ *endif ! *if,rl,eq,0,then rl=vreal_ *endif ! *if,etpv,eq,0,then etpv=vtyp_ *endif ! vatt,vmat_,vreal_,etpv,ecs ! vmesh,mshvset_(mnp_,1) *enddo ! cmsel,s,mshvset *set,mshvset_(mnp_,1) ! ! *endif ! (_vmfchk) ! ! ! *if,_vmtchk,eq,1,then ! ! ! vsel,s,volu,,mshvset aslv,s ! ! (1) (2) (3) (4) (5) ! LN_SIZE, esize, mshtyp, selctopt, mshdens, lresize, ! ln_size,elmnl,mshtyp,'a',mshdens,lresiz_ ! desize,,,,,,elmnl,elmxl, ! vsel,s,volu,,mshvset desize,,,,,,elmnl,elmxl, mshkey,0 ! entity_array,'v','mshvset_','array' ! *do,mnp_,1,ecount,1 vsel,s,volu,,mshvset_(mnp_,1) ! *get,vmat_,volu,mshvset_(mnp_,1),attr,mat *get,vreal_,volu,mshvset_(mnp_,1),attr,real *get,vtyp_,volu,mshvset_(mnp_,1),attr,type ! *if,vmat_,ne,0,then *if,ar11,eq,0,then mtrl=0 *endif *endif ! *if,mtrl,eq,0,then mtrl=vmat_ *endif ! *if,rl,eq,0,then rl=vreal_ *endif ! *if,etpv,eq,0,then etpv=vtyp_ *endif ! vatt,vmat_,vreal_,etpv,ecs ! mopt,pyra,on mshape,1,3d mshkey,0 ! vmesh,mshvset_(mnp_,1) ! mopt,defa mshape,0 *enddo ! cmsel,s,mshvset *set,mshvset_(mnp_,1) ! ! *endif ! (_vmtchk) ! ! init_entity_num ! ellhndof=elmnl ! element length hand-off variable ! *if,elmszovr,ne,0,then elszohof=abs(elmszovr) ! element size overide hand-off variable *elseif,_nelmrot,ne,0,then elszohof=_nelmrot *endif ! lplot ! ! *do,ii_,1,100,1 *set,l_cnt%ii_%, *enddo ! *set,msha(1), *set,perflsz, *set,perfmsh, *set,mstyp, *set,etpa, *set,etpv, *set,mtrl, *set,rl, *set,ecs, *set,ell_, *set,volsel, *set,atargov, *set,vmax, *set,vmin, *set,_amin, *set,opp_hld, *set,opp_lin, *set,thrd_hld, *set,thrd_lin, *set,hi_hld, *set,hi_lin, *set,frst_hld, *set,frst_lin, *set,opp_side, *set,ii_, *set,ecount, *set,v_count, *set,acount, *set,a_count, *set,radrot, *set,varcang, *set,_nelmrot, *set,elmszovr, *set,mshdens, *set,nelm_1, *set,nelm_2, *set,mshfctr, *set,xxx, *set,lleng, *set,elmnl, *set,elmxl, *set,lcount, *set,_lmin, *set,targindx, *set,max_indx, *set,max_leng, *set,max_lnum, *set,_sarc, *set,_vmschk, *set,_astrchk, *set,_amchk, *set,_slchk, *set,_vmtchk, *set,_vmfchk, *set,_slfchk, *set,_slmchk, *set,ii, *set,im, *set,im_, *set,llll, *set,jjjj, *set,kkkk, *set,lszchk_, *set,lresiz_, *set,_nelm90, cmdele,mshaset, cmdele,mshvset, ! *if,prkey_,eq,1,then /go *endif