1 /*     CalculiX - A 3-dimensional finite element program                 */
2 /*              Copyright (C) 1998-2021 Guido Dhondt                     */
3 
4 /*     This program is free software; you can redistribute it and/or     */
5 /*     modify it under the terms of the GNU General Public License as    */
6 /*     published by the Free Software Foundation(version 2);    */
7 /*                    */
8 
9 /*     This program is distributed in the hope that it will be useful,   */
10 /*     but WITHOUT ANY WARRANTY; without even the implied warranty of    */
11 /*     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the      */
12 /*     GNU General Public License for more details.                      */
13 
14 /*     You should have received a copy of the GNU General Public License */
15 /*     along with this program; if not, write to the Free Software       */
16 /*     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.         */
17 
18 #include <stdio.h>
19 #include <math.h>
20 #include <stdlib.h>
21 #include <time.h>
22 #include "CalculiX.h"
23 #include "mortar.h"
24 
25 #define min(a,b) ((a) <= (b) ? (a) : (b))
26 #define max(a,b) ((a) >= (b) ? (a) : (b))
27 
28 /**  modify n and t  due to SPC's/MPC's
29  * needed for 2D calculations
30  * author: Saskia Sitzmann
31  *  [in,out] n		slave normal
32  *  [in,out] t		slave tangent
33  *  [out] n2		transformed slave normal
34  *  [out] that		transformed slave tangent
35  *  [in] islavnodeentry	current slave node entry
36  *  [in] nslavspc		(2*i) pointer to islavspc...
37  *  [in] islavspc         ... which stores SPCs for slave node i
38  *  [in] nsspc            number of SPC for slave nodes
39  *  [in] nslavmpc		(2*i) pointer to islavmpc...
40  *  [in] islavmpc		... which stores MPCs for slave node i
41  *  [in] nsmpc		number of MPC for slave nodes
42  *  [in] nmastspc		(2*i) pointer to imastspc...
43  *  [in] imastspc         ... which stores SPCs for master node i
44  *  [in] nmspc            number of SPC for master nodes
45  *  [in] nmastmpc		(2*i) pointer to imastmpc...
46  *  [in] imastmpc		... which stores MPCs for master node i
47  *  [in] nmmpc		number of MPC for master nodes
48  *  [in] debug 		debug output flag
49  *  [in] node 	 	current slave node
50  */
51 
trafontspcmpc(double * n,double * t,double * n2,double * that,ITG * islavnodeentry,ITG * nboun,ITG * ndirboun,ITG * nodeboun,double * xboun,ITG * nmpc,ITG * ipompc,ITG * nodempc,double * coefmpc,ITG * ikboun,ITG * ilboun,ITG * ikmpc,ITG * ilmpc,ITG * nslavspc,ITG * islavspc,ITG * nsspc,ITG * nslavmpc,ITG * islavmpc,ITG * nsmpc,ITG * nmastspc,ITG * imastspc,ITG * nmspc,ITG * nmastmpc,ITG * imastmpc,ITG * nmmpc,ITG * debug,ITG * node)52 void trafontspcmpc( double *n,double *t,double *n2,double *that,
53 		    ITG *islavnodeentry,ITG *nboun,ITG *ndirboun,ITG *nodeboun,
54 		    double *xboun,ITG *nmpc,ITG *ipompc,ITG *nodempc,
55 		    double *coefmpc,ITG *ikboun,ITG *ilboun,ITG *ikmpc,
56 		    ITG *ilmpc,ITG *nslavspc,ITG *islavspc,ITG *nsspc,
57 		    ITG *nslavmpc,ITG *islavmpc,ITG *nsmpc,ITG *nmastspc,
58 		    ITG *imastspc,ITG *nmspc,ITG *nmastmpc,ITG *imastmpc,
59 		    ITG *nmmpc,ITG *debug,ITG *node){
60 
61   ITG jj,kk,ist,dir,node1,index,dirind,dirdep,nt1;
62 
63   double dist,nn,coefdep;
64 
65   /** handle SPCs and MPCs -> modify tangentials and normal **/
66 
67   for(jj=nslavspc[2*(*islavnodeentry-1)];jj<nslavspc[2*(*islavnodeentry-1)+1];
68       jj++){
69     t[0]=0;t[1]=0;t[2]=0;
70     ist=islavspc[2*jj];
71     dir=ndirboun[ist-1];
72     node1=nodeboun[ist-1];
73     if(*debug==1){printf("jj %" ITGFORMAT " ist %" ITGFORMAT " dir %"
74 			 ITGFORMAT " node %" ITGFORMAT "\n",jj,ist,dir,node1);}
75     t[dir-1]=1.0;
76     dist=t[0]*n[0]+t[1]*n[1]+t[2]*n[2];
77     n[0]=n[0]-dist*t[0];
78     n[1]=n[1]-dist*t[1];
79     n[2]=n[2]-dist*t[2];
80     nn=sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);
81     n[0]=n[0]/nn;n[1]=n[1]/nn;n[2]=n[2]/nn;
82   }
83   for(jj=nslavmpc[2*(*islavnodeentry-1)];jj<nslavmpc[2*(*islavnodeentry-1)+1];
84       jj++){
85     t[0]=0;t[1]=0;t[2]=0;
86     ist=islavmpc[2*jj];
87     dirdep=nodempc[3*(ist-1)+1];
88     coefdep=coefmpc[ist-1];
89     index=nodempc[3*(ist-1)+2];
90     node1=nodempc[3*(ist-1)];
91     t[dirdep-1]=coefdep;
92     if(*debug==1){printf("jj %" ITGFORMAT " ist %" ITGFORMAT " dir %"
93 			 ITGFORMAT " node %" ITGFORMAT " coef %e\n",jj,ist,
94 			 dirdep,node1,coefdep);}
95     while(index!=0){
96       dirind=nodempc[3*(index-1)+1];
97       node1=nodempc[3*(index-1)];
98       if(node1==*node)t[dirind-1]=coefmpc[index-1];
99       index=nodempc[3*(index-1)+2];
100       if(*debug==1){printf("index %" ITGFORMAT " \n",index);}
101     }
102     nt1=sqrt(t[0]*t[0]+t[1]*t[1]+t[2]*t[2]);
103     t[0]=t[0]/nt1;t[1]=t[1]/nt1;t[2]=t[2]/nt1;
104     dist=t[0]*n[0]+t[1]*n[1]+t[2]*n[2];
105     n[0]=n[0]-dist*t[0];
106     n[1]=n[1]-dist*t[1];
107     n[2]=n[2]-dist*t[2];
108     nn=sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);
109     n[0]=n[0]/nn;n[1]=n[1]/nn;n[2]=n[2]/nn;
110   }
111 
112   /** get second tangential and modify it due to SPC's/MPC's**/
113 
114   if(nslavspc[2*(*islavnodeentry-1)+1]-nslavspc[2*(*islavnodeentry-1)]>0 ||
115      nslavmpc[2*(*islavnodeentry-1)+1]-nslavmpc[2*(*islavnodeentry-1)]>0){
116 
117     /** caution: t[3-5]= hat(t2)=n x hat(t1) **/
118 
119     t[3]=n[1]*t[2]-n[2]*t[1];
120     t[4]=n[2]*t[0]-n[0]*t[2];
121     t[5]=n[0]*t[1]-n[1]*t[0];
122     for(kk=0;kk<6;kk++){that[kk]=t[kk];}
123     for(jj=nslavmpc[2*(*islavnodeentry-1)];
124 	jj<nslavmpc[2*(*islavnodeentry-1)+1];jj++){
125       ist=islavmpc[2*jj];
126       dirdep=nodempc[3*(ist-1)+1];
127       coefdep=coefmpc[ist-1];
128       index=nodempc[3*(ist-1)+2];
129       node1=nodempc[3*(ist-1)];
130       while(index!=0){
131 	dirind=nodempc[3*(index-1)+1];
132 	node1=nodempc[3*(index-1)];
133 	if(node1==*node){
134 	  t[dirind-1+3]=t[dirind-1+3]-coefmpc[index-1]*t[dirdep-1+3]/coefdep;
135 	  n[dirind-1]=n[dirind-1]-coefmpc[index-1]*n[dirdep-1]/coefdep;
136 	}
137 	index=nodempc[3*(index-1)+2];
138       }
139       t[dirdep-1+3]=0.0;
140       n[dirdep-1]=0.0;
141     }
142     nn=sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);
143     nt1=sqrt(t[0]*t[0]+t[1]*t[1]+t[2]*t[2]);
144     if(*debug==1){
145       printf("n= %e %e %e \n",n[0],n[1],n[2]);
146       printf("t1= %e %e %e \n",t[0],t[1],t[2]);
147       printf("t2= %e %e %e \n",t[3],t[4],t[5]);
148     }
149 
150     /** caution: t[3-5]= tilde(t2),hat(t2) with modifications due to SPC/MPCs
151      *        that[0-5] =hat(t1) ,hat(t2)
152      *	n[0-2]= n*hat(D)/D in case of directinal blocking
153      *       n[0-2]= n otherwise
154      *       n2[0-2]= original n
155      **/
156 
157   }
158   if(*debug==1){
159     printf("n= %e %e %e \n",n[0],n[1],n[2]);
160     printf("t1= %e %e %e \n",t[0],t[1],t[2]);
161     printf("t2= %e %e %e \n",t[3],t[4],t[5]);
162   }
163   return;
164 
165 }
166