!   TITLE:  cpl_nodes.mac (LOADS)
!
!
!       Updated macro to optimize for speed:
!           1. Replaced create_cs with 'clocal' command
!           2. Replaced target set array with dmin_ parameter
!
!   OBJECTIVE:
!
!   This sub-macro pairwise couples specified degrees of freedom (DOF) of
!   nodes on the surface of two separate areas.
!
!
!   COMMAND SYNTAX:
!
!                       (1)            (2)         (3)    (4)     (5)
!       CPL_NODES, 'source_aset', 'target_aset', node_cs, tol, 'dof_lab'
!
!
!   ARGUMENTS:
!
!       (1) source_aset = component group character name of area(s) com-
!                         prising the source surface.
!                         [MUST BE IN SINGLE QUOTES]
!
!       (2) target_aset = component group character name of area(s) com-
!                         prising the target surface.
!                         [MUST BE IN SINGLE QUOTES]
!
!       (3) node_cs = the coordinate system in which the nodal coordinates
!                     are to be rotated to. The local coordinate system
!                     created at each node is a cartesian coordinate sys-
!                     tem from which the tolerance band is created, and
!                     is created parallel to the NODE_CS.
!
!       (4) tol = the total width of the tolerance bands for considering a
!                 node for coupling.
!
!       (5) dof_lab = the DOF label for the coupling. (e.g., UX, UY, UZ,
!                     ROTX, ALL, etc.) See the CP command help for all
!                     options. [MUST BE IN SINGLE QUOTES]
!
!
!   DESCRIPTION:
!
!   This macro may be used to couple the DOF's of non-coincident nodes from
!   two separate and different mesh layout patterns on a pair of areas. The
!   areas must be coplanar, coincident or separated by a given distance within
!   a specified tolerance value (argument 4).
!
!   A cubical tolerance band is calculated around each node, with the nodes
!   located at the center of the cube. The tolerance band width argument, TOL,
!   is defined as the total width of the band around a node, as measured from
!   a cartesian c.s. centered at the node location. This is shown in figure 1.
!                            ___________________
!                           |   TOL             | TOL/2
!                           |       y ^         |
!                           |         |         |
!                           |         |         |
!                           |         *---> x   | TOL
!                           |      source       |
!                           |       node        |
!                           |                   |
!                           |___________________| -TOL/2
!                        -TOL/2               TOL/2
!
!                       FIGURE 1.  Tolerance band
!
!   The area(s) from each surface must be stored in component groups. One surface
!   (area(s)) component group is specified as the source surface, and the other
!   surface of areas component group a target surface.
!
!   The algorithm iterates through each node of the source set and couples the
!   specified DOF's (argument 5) with the nearest node in the target set that is
!   within the tolerance band. If there is more than 1 node in this region from
!   the target set, the algorithm will couple the node that is the least distance
!   from the source node.
!
!   The inputs of arguments 1 and 2 must be carefully defined SOURCE and TARGET
!   area component group sets with distinct user defined names.
!
!
!
*get,prkey_,active,0,prkey
/nopr
!
s_aset=arg1
t_aset=arg2
n_cs=arg3
tol_=arg4
dof_lab=arg5
!
csys,n_cs
!
cmsel,s,%s_aset%
nsla,s,1
nrotat,all
cm,s_nset,node
!
cmsel,s,%t_aset%
nsla,s,1
nrotat,all
cm,t_nset,node
!
nsel,s,node,,s_nset
entity_array,'n','s_set','array'
s_cnt=ecount
!
t2_=.5*tol_
ctcs_=csn+1
!
*do,qrs_,1,s_cnt,1
    !
    csys,n_cs
    !
    clocal,ctcs_,0,nx(s_set(qrs_,1)),ny(s_set(qrs_,1)),nz(s_set(qrs_,1))
    !
    nsel,s,node,,t_nset
    !
    nsel,r,loc,x,-t2_,t2_
    nsel,r,loc,y,-t2_,t2_
    nsel,r,loc,z,-t2_,t2_
    !
    *get,ncnt_,node,,count              ! # of selected target nodes
    !
    *if,ncnt_,ge,1,then
        !
        dmin_=tol_
        t_node=0
        s_node=s_set(qrs_,1)
        !
        *do,ijk_,1,ncnt_
            t_node=ndnext(t_node)
            dist_=distnd(s_node,t_node)
            !
            *if,dist_,lt,dmin_,then
                dmin_=dist_
                nmin_=t_node
            *endif
        *enddo
        !
        nsel,s,node,,nmin_
        nsel,a,node,,s_node
        !
        cp,next,%dof_lab%,all
        !
        nsel,s,node,,t_nset
        nsel,u,node,,nmin_
        cm,t_nset,node
    *endif
*enddo
!
csdele,ctcs_
!
cmdele,s_nset
cmdele,t_nset
!
init_entity_num,1
!
*set,ctcs_,
*set,dist_,
*set,dmin_,
*set,dof_lab,
*set,ecount,
*set,ijk_,
*set,n_cs,
*set,nmin_,
*set,qrs_,
*set,s_aset,
*set,s_cnt,
*set,s_node,
*set,s_nset,
*set,s_set(1),
*set,t2_,
*set,tol_,
*set,t_aset,
*set,t_node,
*set,t_nset,
!
*if,prkey_,eq,1,then
    /go
*endif