! ============================================================
! M11 - Par de contacto 3D minimo
! Dos bloques SOLID185 con CONTA174/TARGE170, CNCHECK y POST1.
! Unidades coherentes: m, kg, s, N, Pa.
! ============================================================

/CLEAR,START
/FILNAME,m11_contact,1
/TITLE,M11 - Par de contacto 3D
/UNITS,SI

block_x=0.04
block_z=0.04
h_lower=0.02
h_upper=0.02
mesh_h=0.01
young=210E9
nu=0.30
n_substeps=10
equilibrium_tol=0.55
select_tol=mesh_h*1E-4
min_contact_elems=16
react_ratio_min=0.20
min_sets=6

! ============================================================
! CASO 1 - GAP ABIERTO
! ============================================================
initial_gap=0.0005
disp1=-0.0002

/PREP7
ET,1,SOLID185
KEYOPT,1,2,0
ET,2,CONTA174
KEYOPT,2,2,0
KEYOPT,2,12,0
KEYOPT,2,4,3
ET,3,TARGE170
MP,EX,1,young
MP,PRXY,1,nu
R,2
REAL,2
TYPE,1
MAT,1
BLOCK,0,block_x,0,h_lower,0,block_z
BLOCK,0,block_x,h_lower+initial_gap,h_lower+initial_gap+h_upper,0,block_z

div_x=MAX(1,NINT(block_x/mesh_h))
div_y=MAX(1,NINT(h_lower/mesh_h))
div_z=MAX(1,NINT(block_z/mesh_h))
MSHAPE,0,3D
MSHKEY,1
LSEL,S,LENGTH,,block_x
LESIZE,ALL,,,div_x,,1
LSEL,S,LENGTH,,h_lower
LESIZE,ALL,,,div_y,,1
LSEL,S,LENGTH,,block_z
LESIZE,ALL,,,div_z,,1
ALLSEL,ALL
VMESH,ALL

*GET,n_nodes,NODE,0,COUNT
*GET,n_solid,ELEM,0,COUNT

SELTOL,select_tol
ASEL,S,LOC,Y,h_lower
NSLA,S,1
ESLN,S
TYPE,3
REAL,2
MAT,1
ESURF
ASEL,S,LOC,Y,h_lower+initial_gap
NSLA,S,1
ESLN,S
TYPE,2
REAL,2
MAT,1
ESURF
ALLSEL,ALL
SELTOL,

ESEL,S,TYPE,,2
*GET,n_conta,ELEM,0,COUNT
ESEL,S,TYPE,,3
*GET,n_targe,ELEM,0,COUNT
ALLSEL,ALL

SELTOL,select_tol
NSEL,S,LOC,Y,0
CM,bottom_nodes,NODE
*GET,n_bottom,NODE,0,COUNT
NSEL,S,LOC,Y,h_lower+initial_gap+h_upper
CM,top_nodes,NODE
ALLSEL,ALL
SELTOL,
FINISH

/SOLU
ANTYPE,STATIC
NLGEOM,ON
NEQIT,25
CNVTOL,F,,0.005,,,MINREF,1
CNCHECK,AUTO
CMSEL,S,bottom_nodes
D,ALL,ALL,0
ALLSEL,ALL
CMSEL,S,top_nodes
D,ALL,UY,disp1
D,ALL,UX,0
D,ALL,UZ,0
ALLSEL,ALL
AUTOTS,OFF
KBC,0
NSUBST,n_substeps
OUTRES,ALL,ALL
SOLVE
FINISH

/POST1
*GET,n_sets1,ACTIVE,0,SET,NSET
SET,LAST
rfy1=0
CMSEL,S,bottom_nodes
node_id=0
*DO,j,1,n_bottom
  node_id=NDNEXT(node_id)
  *GET,rfy_node,NODE,node_id,RF,FY
  rfy1=rfy1+rfy_node
*ENDDO
ALLSEL,ALL
FINISH

react1=young*block_x*block_z*ABS(disp1)/h_upper
closed1=0
*IF,ABS(rfy1),GT,react_ratio_min*react1,THEN
  closed1=1
*ENDIF
ferr1=ABS(rfy1)/MAX(react1,1)

s1gap=0.0005
s1disp=disp1
s1rfy=rfy1
s1closed=closed1
s1sets=n_sets1
s1ferr=ferr1

PARSAV,ALL,m11_state,par

! ============================================================
! CASO 2 - CIERRE DE CONTACTO
! ============================================================
/CLEAR,NOSTART
/FILNAME,m11_close,1
/TITLE,M11 - Cierre de contacto
/UNITS,SI
PARRES,NEW,m11_state,par
initial_gap=0.0005
disp2=-0.0012
select_tol=mesh_h*1E-4

/PREP7
ET,1,SOLID185
KEYOPT,1,2,0
ET,2,CONTA174
KEYOPT,2,2,0
KEYOPT,2,12,0
KEYOPT,2,4,3
ET,3,TARGE170
MP,EX,1,young
MP,PRXY,1,nu
R,2
REAL,2
TYPE,1
MAT,1
BLOCK,0,block_x,0,h_lower,0,block_z
BLOCK,0,block_x,h_lower+initial_gap,h_lower+initial_gap+h_upper,0,block_z
div_x=MAX(1,NINT(block_x/mesh_h))
div_y=MAX(1,NINT(h_lower/mesh_h))
div_z=MAX(1,NINT(block_z/mesh_h))
MSHAPE,0,3D
MSHKEY,1
LSEL,S,LENGTH,,block_x
LESIZE,ALL,,,div_x,,1
LSEL,S,LENGTH,,h_lower
LESIZE,ALL,,,div_y,,1
LSEL,S,LENGTH,,block_z
LESIZE,ALL,,,div_z,,1
ALLSEL,ALL
VMESH,ALL

SELTOL,select_tol
ASEL,S,LOC,Y,h_lower
NSLA,S,1
ESLN,S
TYPE,3
REAL,2
MAT,1
ESURF
ASEL,S,LOC,Y,h_lower+initial_gap
NSLA,S,1
ESLN,S
TYPE,2
REAL,2
MAT,1
ESURF
ALLSEL,ALL
SELTOL,

ESEL,S,TYPE,,2
*GET,nc2,ELEM,0,COUNT
ESEL,S,TYPE,,3
*GET,nt2,ELEM,0,COUNT
ALLSEL,ALL

SELTOL,select_tol
NSEL,S,LOC,Y,0
CM,bottom_nodes,NODE
*GET,n_bottom,NODE,0,COUNT
NSEL,S,LOC,Y,h_lower+initial_gap+h_upper
CM,top_nodes,NODE
ALLSEL,ALL
SELTOL,
FINISH

/SOLU
ANTYPE,STATIC
NLGEOM,ON
NEQIT,25
CNVTOL,F,,0.005,,,MINREF,1
CNCHECK,AUTO
CMSEL,S,bottom_nodes
D,ALL,ALL,0
ALLSEL,ALL
CMSEL,S,top_nodes
D,ALL,UY,disp2
D,ALL,UX,0
D,ALL,UZ,0
ALLSEL,ALL
AUTOTS,OFF
KBC,0
NSUBST,n_substeps
OUTRES,ALL,ALL
SOLVE
FINISH

/POST1
*GET,n_sets2,ACTIVE,0,SET,NSET
SET,LAST
rfy2=0
CMSEL,S,bottom_nodes
node_id=0
*DO,j,1,n_bottom
  node_id=NDNEXT(node_id)
  *GET,rfy_node,NODE,node_id,RF,FY
  rfy2=rfy2+rfy_node
*ENDDO
ALLSEL,ALL
FINISH

react2=young*block_x*block_z*MAX(0.0001,ABS(disp2)-0.0005)/h_upper
closed2=0
*IF,ABS(rfy2),GT,react_ratio_min*react2,THEN
  closed2=1
*ENDIF
ferr2=ABS(ABS(rfy2)-react2)/MAX(react2,1)

s2gap=0.0005
s2disp=disp2
s2rfy=rfy2
s2closed=closed2
s2sets=n_sets2
s2ferr=ferr2
s2nc=nc2
s2nt=nt2
s2react=react2

PARSAV,ALL,m11_state2,par

! ============================================================
! CASO 3 - INTERFERENCIA INICIAL
! ============================================================
/CLEAR,NOSTART
/FILNAME,m11_interf,1
/TITLE,M11 - Interferencia inicial
/UNITS,SI
PARRES,NEW,m11_state2,par
initial_gap=-0.0001
disp3=0
select_tol=mesh_h*1E-4

/PREP7
ET,1,SOLID185
KEYOPT,1,2,0
ET,2,CONTA174
KEYOPT,2,2,0
KEYOPT,2,12,0
KEYOPT,2,4,3
ET,3,TARGE170
MP,EX,1,young
MP,PRXY,1,nu
R,2
REAL,2
TYPE,1
MAT,1
BLOCK,0,block_x,0,h_lower,0,block_z
BLOCK,0,block_x,h_lower+initial_gap,h_lower+initial_gap+h_upper,0,block_z
div_x=MAX(1,NINT(block_x/mesh_h))
div_y=MAX(1,NINT(h_lower/mesh_h))
div_z=MAX(1,NINT(block_z/mesh_h))
MSHAPE,0,3D
MSHKEY,1
LSEL,S,LENGTH,,block_x
LESIZE,ALL,,,div_x,,1
LSEL,S,LENGTH,,h_lower
LESIZE,ALL,,,div_y,,1
LSEL,S,LENGTH,,block_z
LESIZE,ALL,,,div_z,,1
ALLSEL,ALL
VMESH,ALL

SELTOL,select_tol
ASEL,S,LOC,Y,h_lower
NSLA,S,1
ESLN,S
TYPE,3
REAL,2
MAT,1
ESURF
ASEL,S,LOC,Y,h_lower+initial_gap
NSLA,S,1
ESLN,S
TYPE,2
REAL,2
MAT,1
ESURF
ALLSEL,ALL
SELTOL,

SELTOL,select_tol
NSEL,S,LOC,Y,0
CM,bottom_nodes,NODE
*GET,n_bottom,NODE,0,COUNT
NSEL,S,LOC,Y,h_lower+initial_gap+h_upper
CM,top_nodes,NODE
ALLSEL,ALL
SELTOL,
FINISH

/SOLU
ANTYPE,STATIC
NLGEOM,ON
NEQIT,25
CNVTOL,F,,0.005,,,MINREF,1
CNCHECK,AUTO
CMSEL,S,bottom_nodes
D,ALL,ALL,0
ALLSEL,ALL
CMSEL,S,top_nodes
D,ALL,UY,disp3
D,ALL,UX,0
D,ALL,UZ,0
ALLSEL,ALL
AUTOTS,OFF
KBC,0
NSUBST,n_substeps
OUTRES,ALL,ALL
SOLVE
FINISH

/POST1
*GET,n_sets3,ACTIVE,0,SET,NSET
SET,LAST
rfy3=0
CMSEL,S,bottom_nodes
node_id=0
*DO,j,1,n_bottom
  node_id=NDNEXT(node_id)
  *GET,rfy_node,NODE,node_id,RF,FY
  rfy3=rfy3+rfy_node
*ENDDO
ALLSEL,ALL
FINISH

penetr3=0.0001
react3=young*block_x*block_z*penetr3/h_upper
closed3=0
*IF,ABS(rfy3),GT,react_ratio_min*react3,THEN
  closed3=1
*ENDIF
ferr3=ABS(ABS(rfy3)-react3)/MAX(react3,1)

! ============================================================
! AUDITORIA Y CONTRATO
! ============================================================
passes=1
*IF,n_nodes,LT,100,THEN
  passes=0
*ENDIF
*IF,n_solid,LT,50,THEN
  passes=0
*ENDIF
*IF,n_conta,LT,min_contact_elems,THEN
  passes=0
*ENDIF
*IF,n_targe,LT,min_contact_elems,THEN
  passes=0
*ENDIF
*IF,s2nc,NE,n_conta,THEN
  passes=0
*ENDIF
*IF,s2nt,NE,n_targe,THEN
  passes=0
*ENDIF
*IF,s1closed,NE,0,THEN
  passes=0
*ENDIF
*IF,s2closed,NE,1,THEN
  passes=0
*ENDIF
*IF,closed3,NE,1,THEN
  passes=0
*ENDIF
*IF,s1sets,LT,min_sets,THEN
  passes=0
*ENDIF
*IF,s2sets,LT,min_sets,THEN
  passes=0
*ENDIF
*IF,n_sets3,LT,min_sets,THEN
  passes=0
*ENDIF
*IF,s2ferr,GE,equilibrium_tol,THEN
  passes=0
*ENDIF

*CFOPEN,m11_contact_audit,csv
*VWRITE
('case,initial_gap_m,disp_m,n_nodes,n_solid,n_conta,n_targe,contact_closed,initial_penetration_m,force_error,n_converged,passes')
*VWRITE,1,s1gap,s1disp,n_nodes,n_solid,n_conta,n_targe,s1closed,0,s1ferr,s1sets,passes
(F3.0,',',E16.8,',',E16.8,',',F10.0,',',F10.0,',',F10.0,',',F10.0,',',F2.0,',',E16.8,',',E16.8,',',F6.0,',',F2.0)
*VWRITE,2,s2gap,s2disp,n_nodes,n_solid,s2nc,s2nt,s2closed,0,s2ferr,s2sets,passes
(F3.0,',',E16.8,',',E16.8,',',F10.0,',',F10.0,',',F10.0,',',F10.0,',',F2.0,',',E16.8,',',E16.8,',',F6.0,',',F2.0)
*VWRITE,3,-0.0001,disp3,n_nodes,n_solid,s2nc,s2nt,closed3,penetr3,ferr3,n_sets3,passes
(F3.0,',',E16.8,',',E16.8,',',F10.0,',',F10.0,',',F10.0,',',F10.0,',',F2.0,',',E16.8,',',E16.8,',',F6.0,',',F2.0)
*CFCLOS

*CFOPEN,m11_summary,csv
*VWRITE
('n_nodes,n_solid,n_conta,n_targe,react2_N,rfy2_N,force_error_close,study_passes')
*VWRITE,n_nodes,n_solid,n_conta,n_targe,s2react,s2rfy,s2ferr,passes
(F10.0,',',F10.0,',',F10.0,',',F10.0,',',E16.8,',',E16.8,',',E16.8,',',F2.0)
*CFCLOS

*IF,passes,EQ,1,THEN
  /COM,M11 CONTACT STUDY PASSED
*ELSE
  /COM,M11 CONTACT STUDY FAILED - inspect m11_contact_audit.csv and .out
  /STATUS,PARM
*ENDIF

FINISH
