CalculiX  2.13
A Free Software Three-Dimensional Structural Finite Element Program
springforc_n2f.f File Reference

Go to the source code of this file.

Functions/Subroutines

subroutine springforc_n2f (xl, konl, vl, imat, elcon, nelcon, elas, fnl, ncmat_, ntmat_, nope, lakonl, t1l, kode, elconloc, plicon, nplicon, npmat_, senergy, nener, cstr, mi, springarea, nmethod, ne0, nstate_, xstateini, xstate, reltime, ielas, venergy, ielorien, orab, norien, nelem)
 

Function/Subroutine Documentation

◆ springforc_n2f()

subroutine springforc_n2f ( real*8, dimension(3,10), intent(in)  xl,
integer, dimension(9), intent(in)  konl,
real*8, dimension(0:mi(2),10), intent(in)  vl,
integer, intent(in)  imat,
real*8, dimension(0:ncmat_,ntmat_,*), intent(in)  elcon,
integer, dimension(2,*), intent(in)  nelcon,
real*8, dimension(21), intent(inout)  elas,
real*8, dimension(3,10), intent(inout)  fnl,
integer, intent(in)  ncmat_,
integer, intent(in)  ntmat_,
integer, intent(in)  nope,
character*8, intent(in)  lakonl,
real*8, intent(in)  t1l,
integer, intent(in)  kode,
real*8, dimension(21), intent(in)  elconloc,
real*8, dimension(0:2*npmat_,ntmat_,*), intent(in)  plicon,
integer, dimension(0:ntmat_,*), intent(in)  nplicon,
integer, intent(in)  npmat_,
real*8, intent(inout)  senergy,
integer, intent(in)  nener,
real*8, dimension(6), intent(inout)  cstr,
integer, dimension(*), intent(in)  mi,
real*8, dimension(2), intent(inout)  springarea,
integer, intent(in)  nmethod,
integer, intent(in)  ne0,
integer, intent(in)  nstate_,
real*8, dimension(nstate_,mi(1),*), intent(in)  xstateini,
real*8, dimension(nstate_,mi(1),*), intent(inout)  xstate,
real*8, intent(in)  reltime,
integer, intent(in)  ielas,
real*8, intent(inout)  venergy,
integer, dimension(mi(3),*), intent(in)  ielorien,
real*8, dimension(7,*), intent(in)  orab,
integer, intent(in)  norien,
integer, intent(in)  nelem 
)
24 !
25 ! calculates the force of the spring (node-to-face penalty)
26 !
27  implicit none
28 !
29  character*8 lakonl
30 !
31  integer konl(9),i,j,imat,ncmat_,ntmat_,nope,nterms,iflag,mi(*),
32  & kode,niso,id,nplicon(0:ntmat_,*),npmat_,nelcon(2,*),nener,
33  & nmethod,ne0,nstate_,ielas,norien,nelem,ielorien(mi(3),*),
34  & iorien,idof,idof1,idof2
35 !
36  real*8 xl(3,10),elas(21),ratio(9),t1l,al(3),vl(0:mi(2),10),
37  & pl(3,10),xn(3),dm,alpha,beta,fnl(3,10),tp(3),te(3),ftrial(3),
38  & dist,t(3),dftrial,overclosure,venergy,orab(7,*),a(3,3),
39  & elcon(0:ncmat_,ntmat_,*),pproj(3),xsj2(3),xs2(3,7),clear,
40  & shp2(7,9),xi,et,elconloc(21),plconloc(802),xk,fk,dd,val,
41  & xiso(200),yiso(200),dd0,plicon(0:2*npmat_,ntmat_,*),
42  & um,eps,pi,senergy,cstr(6),dg,dfshear,dfnl,
43  & springarea(2),overlap,pres,xn1(3),xn2(3),
44  & xstate(nstate_,mi(1),*),xstateini(nstate_,mi(1),*),t1(3),t2(3),
45  & dt1,dte,alnew(3),reltime
46 !
47  intent(in) xl,konl,vl,imat,elcon,nelcon,
48  & ncmat_,ntmat_,nope,lakonl,t1l,kode,elconloc,
49  & plicon,nplicon,npmat_,nener,mi,
50  & nmethod,ne0,nstate_,xstateini,
51  & reltime,ielas,ielorien,orab,norien,nelem
52 !
53  intent(inout) venergy,senergy,fnl,cstr,springarea,elas,xstate
54 !
55  iflag=2
56 !
57  if(nener.eq.1) venergy=0.d0
58 !
59 ! actual positions of the nodes belonging to the contact spring
60 ! (otherwise no contact force)
61 !
62  if(nmethod.ne.2) then
63  do i=1,nope
64  do j=1,3
65  pl(j,i)=xl(j,i)+vl(j,i)
66  enddo
67  enddo
68  else
69 !
70 ! for frequency calculations the eigenmodes are freely
71 ! scalable, leading to problems with contact finding
72 !
73  do i=1,nope
74  do j=1,3
75  pl(j,i)=xl(j,i)
76  enddo
77  enddo
78  endif
79 !
80  if(lakonl(7:7).eq.'A') then
81  if(lakonl(4:6).eq.'RNG') then
82 !
83 ! SPRINGA-element
84 !
85  dd0=dsqrt((xl(1,2)-xl(1,1))**2
86  & +(xl(2,2)-xl(2,1))**2
87  & +(xl(3,2)-xl(3,1))**2)
88  dd=dsqrt((pl(1,2)-pl(1,1))**2
89  & +(pl(2,2)-pl(2,1))**2
90  & +(pl(3,2)-pl(3,1))**2)
91  if(dd.le.0.d0) then
92  write(*,*) '*ERROR in springforc_n2f: spring connects'
93  write(*,*) ' two nodes at the same location:'
94  write(*,*) ' spring length is zero'
95  call exit(201)
96  endif
97  do i=1,3
98  xn(i)=(pl(i,2)-pl(i,1))/dd
99  enddo
100  val=dd-dd0
101 !
102 ! calculating the spring force and the spring energy
103 !
104  call calcspringforc(imat,elcon,nelcon,ncmat_,ntmat_,t1l,
105  & kode,plicon,nplicon,npmat_,senergy,nener,fk,val)
106 !
107  else
108 !
109 ! GAP-element
110 ! interpolating the material data
111 !
112  call materialdata_sp(elcon,nelcon,imat,ntmat_,i,t1l,
113  & elconloc,kode,plicon,nplicon,npmat_,plconloc,ncmat_)
114 !
115  dd=elconloc(1)
116  xn(1)=elconloc(2)
117  xn(2)=elconloc(3)
118  xn(3)=elconloc(4)
119  xk=elconloc(5)
120  pi=4.d0*datan(1.d0)
121  eps=pi*elconloc(6)/xk
122  overclosure=-dd-xn(1)*(vl(1,2)-vl(1,1))
123  & -xn(2)*(vl(2,2)-vl(2,1))
124  & -xn(3)*(vl(3,2)-vl(3,1))
125  fk=-xk*overclosure*(0.5d0+datan(overclosure/eps)/pi)
126  endif
127 !
128  do i=1,3
129  fnl(i,1)=-fk*xn(i)
130  fnl(i,2)=fk*xn(i)
131  enddo
132  return
133  elseif(lakonl(7:7).eq.'1') then
134 !
135 ! spring1-element
136 ! determine the direction of action of the spring
137 !
138  idof=nint(elcon(3,1,imat))
139 !
140  if(norien.gt.0) then
141  iorien=ielorien(1,nelem)
142  else
143  iorien=0
144  endif
145 !
146  if(iorien.eq.0) then
147  do i=1,3
148  xn(i)=0.d0
149  enddo
150  xn(idof)=1.d0
151  else
152  call transformatrix(orab(1,iorien),xl(1,1),a)
153  do i=1,3
154  xn(i)=a(i,idof)
155  enddo
156  endif
157 !
158 ! change in spring length
159 !
160  val=vl(1,1)*xn(1)+vl(2,1)*xn(2)+vl(3,1)*xn(3)
161 !
162 ! calculating the spring force and the spring energy
163 !
164  call calcspringforc(imat,elcon,nelcon,ncmat_,ntmat_,t1l,
165  & kode,plicon,nplicon,npmat_,senergy,nener,fk,val)
166 !
167  do i=1,3
168  fnl(i,1)=fk*xn(i)
169  enddo
170  return
171  elseif(lakonl(7:7).eq.'2') then
172 !
173 ! spring2-element
174 ! determine the direction of action of the spring
175 !
176  idof1=nint(elcon(3,1,imat))
177  idof2=nint(elcon(4,1,imat))
178 !
179  if(norien.gt.0) then
180  iorien=ielorien(1,nelem)
181  else
182  iorien=0
183  endif
184 !
185  if(iorien.eq.0) then
186  do i=1,3
187  xn1(i)=0.d0
188  xn2(i)=0.d0
189  enddo
190  xn1(idof1)=1.d0
191  xn2(idof2)=1.d0
192  else
193  call transformatrix(orab(1,iorien),xl(1,1),a)
194  do i=1,3
195  xn1(i)=a(i,idof1)
196  enddo
197  call transformatrix(orab(1,iorien),xl(1,2),a)
198  do i=1,3
199  xn2(i)=a(i,idof2)
200  enddo
201  endif
202 !
203 ! change in spring length
204 !
205  val=(vl(1,1)*xn1(1)+vl(2,1)*xn1(2)+vl(3,1)*xn1(3))
206  & -(vl(1,2)*xn2(1)+vl(2,2)*xn2(2)+vl(3,2)*xn2(3))
207 !
208 ! calculating the spring force and the spring energy
209 !
210  call calcspringforc(imat,elcon,nelcon,ncmat_,ntmat_,t1l,
211  & kode,plicon,nplicon,npmat_,senergy,nener,fk,val)
212 !
213  do i=1,3
214  fnl(i,1)=fk*xn1(i)
215  fnl(i,2)=-fk*xn2(i)
216  enddo
217  return
218  endif
219 !
220  nterms=nope-1
221 !
222 ! vector vr connects the dependent node with its projection
223 ! on the independent face
224 !
225  do i=1,3
226  pproj(i)=pl(i,nope)
227  enddo
228  call attach(pl,pproj,nterms,ratio,dist,xi,et)
229  do i=1,3
230  al(i)=pl(i,nope)-pproj(i)
231  enddo
232 !
233 ! determining the jacobian vector on the surface
234 !
235  if(nterms.eq.9) then
236  call shape9q(xi,et,pl,xsj2,xs2,shp2,iflag)
237  elseif(nterms.eq.8) then
238  call shape8q(xi,et,pl,xsj2,xs2,shp2,iflag)
239  elseif(nterms.eq.4) then
240  call shape4q(xi,et,pl,xsj2,xs2,shp2,iflag)
241  elseif(nterms.eq.6) then
242  call shape6tri(xi,et,pl,xsj2,xs2,shp2,iflag)
243  elseif(nterms.eq.7) then
244  call shape7tri(xi,et,pl,xsj2,xs2,shp2,iflag)
245  else
246  call shape3tri(xi,et,pl,xsj2,xs2,shp2,iflag)
247  endif
248 !
249 ! normal on the surface
250 !
251  dm=dsqrt(xsj2(1)*xsj2(1)+xsj2(2)*xsj2(2)+xsj2(3)*xsj2(3))
252  do i=1,3
253  xn(i)=xsj2(i)/dm
254  enddo
255 !
256 ! distance from surface along normal (= clearance)
257 !
258  clear=al(1)*xn(1)+al(2)*xn(2)+al(3)*xn(3)
259 !
260 ! check for a reduction of the initial penetration, if any
261 !
262  if(nmethod.eq.1) then
263  clear=clear-springarea(2)*(1.d0-reltime)
264  endif
265  if(clear.le.0.d0) cstr(1)=clear
266 !
267 ! MPADD start
268 ! (keep also positive clearance in the frd file)
269 c if(nmethod.eq.4) then
270 c cstr(1)=clear
271 c else
272 c if(clear.le.0.d0) cstr(1)=clear
273 c endif
274 ! MPADD end
275 !
276 ! representative area: usually the slave surface stored in
277 ! springarea; however, if no area was assigned because the
278 ! node does not belong to any element, the master surface
279 ! is used
280 !
281  if(springarea(1).le.0.d0) then
282  if(nterms.eq.3) then
283  springarea(1)=dm/2.d0
284  else
285  springarea(1)=dm*4.d0
286  endif
287  endif
288 !
289  if(int(elcon(3,1,imat)).eq.1) then
290 !
291 ! exponential overclosure
292 !
293  if(dabs(elcon(2,1,imat)).lt.1.d-30) then
294  elas(1)=0.d0
295  beta=1.d0
296  else
297 !
298  alpha=elcon(2,1,imat)*springarea(1)
299  beta=elcon(1,1,imat)
300  if(-beta*clear.gt.23.d0-dlog(alpha)) then
301  beta=(dlog(alpha)-23.d0)/clear
302  endif
303  elas(1)=dexp(-beta*clear+dlog(alpha))
304  endif
305  if(nener.eq.1) then
306  senergy=elas(1)/beta
307  endif
308  elseif(int(elcon(3,1,imat)).eq.2) then
309 !
310 ! linear overclosure
311 !
312 ! MPADD start
313  if(nmethod.eq.4) then
314 !
315 ! Conputation of the force (only if negative clearance)
316 ! the energy is computed with the exact potential
317 !
318  if(clear.le.0.d0)then
319  pi=4.d0*datan(1.d0)
320  eps=elcon(1,1,imat)*pi/elcon(2,1,imat)
321  elas(1)=(-springarea(1)*elcon(2,1,imat)*clear*
322  & (0.5d0+datan(-clear/eps)/pi))
323  if(nener.eq.1)
324  & senergy=springarea(1)*elcon(2,1,imat)*(clear**2/4.d0+
325  & (0.5d0*datan(-clear/eps)*clear**2+
326  & 0.5d0*(eps*clear+datan(-clear/eps)*eps**2))/pi)
327  else
328  elas(1)=0.d0
329  if(nener.eq.1) senergy=0.d0
330  endif
331 !
332  else
333  pi=4.d0*datan(1.d0)
334  eps=elcon(1,1,imat)*pi/elcon(2,1,imat)
335  elas(1)=(-springarea(1)*elcon(2,1,imat)*clear*
336  & (0.5d0+datan(-clear/eps)/pi))
337  if(nener.eq.1) then
338  senergy=-elas(1)*clear/2.d0
339  endif
340  endif
341 ! MPADD end
342  elseif(int(elcon(3,1,imat)).eq.3) then
343 !
344 ! tabular overclosure
345 !
346 ! interpolating the material data
347 !
348  call materialdata_sp(elcon,nelcon,imat,ntmat_,i,t1l,
349  & elconloc,kode,plicon,nplicon,npmat_,plconloc,ncmat_)
350  overlap=-clear
351  niso=int(plconloc(801))
352  do i=1,niso
353  xiso(i)=plconloc(2*i-1)
354  yiso(i)=plconloc(2*i)
355  enddo
356  call ident(xiso,overlap,niso,id)
357  if(id.eq.0) then
358  pres=yiso(1)
359  if(nener.eq.1) then
360  senergy=yiso(1)*overlap
361  endif
362  elseif(id.eq.niso) then
363  pres=yiso(niso)
364  if(nener.eq.1) then
365  senergy=yiso(1)*xiso(1)
366  do i=2,niso
367  senergy=senergy+(xiso(i)-xiso(i-1))*
368  & (yiso(i)+yiso(i-1))/2.d0
369  enddo
370  senergy=senergy+(pres-xiso(niso))*yiso(niso)
371  endif
372  else
373  xk=(yiso(id+1)-yiso(id))/(xiso(id+1)-xiso(id))
374  pres=yiso(id)+xk*(overlap-xiso(id))
375  if(nener.eq.1) then
376  senergy=yiso(1)*xiso(1)
377  do i=2, id
378  senergy=senergy+(xiso(i)-xiso(i-1))*
379  & (yiso(i)+yiso(i-1))/2.d0
380  enddo
381  senergy=senergy+(overlap-xiso(id))*(pres+yiso(id))/2.d0
382  endif
383  endif
384  elas(1)=springarea(1)*pres
385  if(nener.eq.1) senergy=springarea(1)*senergy
386  else
387  write(*,*) '*ERROR in springforc: no overclosure model'
388  write(*,*) ' selected. This is mandatory in a penalty'
389  write(*,*) ' contact calculation. Please use the'
390  write(*,*) ' *SURFACE BEHAVIOR card.'
391  call exit(201)
392  endif
393 !
394 ! forces in the nodes of the contact element
395 !
396  do i=1,3
397  fnl(i,nope)=-elas(1)*xn(i)
398  enddo
399  cstr(4)=elas(1)/springarea(1)
400 !
401 ! Coulomb friction for static calculations
402 !
403  if(ncmat_.ge.7) then
404  um=elcon(6,1,imat)
405  if(um.gt.0.d0) then
406  if(1.d0 - dabs(xn(1)).lt.1.5231d-6) then
407 !
408 ! calculating the local directions on master surface
409 !
410  t1(1)=-xn(3)*xn(1)
411  t1(2)=-xn(3)*xn(2)
412  t1(3)=1.d0-xn(3)*xn(3)
413  else
414  t1(1)=1.d0-xn(1)*xn(1)
415  t1(2)=-xn(1)*xn(2)
416  t1(3)=-xn(1)*xn(3)
417  endif
418  dt1=dsqrt(t1(1)*t1(1)+t1(2)*t1(2)+t1(3)*t1(3))
419  do i=1,3
420  t1(i)=t1(i)/dt1
421  enddo
422  t2(1)=xn(2)*t1(3)-xn(3)*t1(2)
423  t2(2)=xn(3)*t1(1)-xn(1)*t1(3)
424  t2(3)=xn(1)*t1(2)-xn(2)*t1(1)
425 !
426 ! linear stiffness of the shear stress versus
427 ! slip curve
428 !
429  xk=elcon(7,1,imat)*springarea(1)
430 !
431 ! calculating the relative displacement between the slave node
432 ! and its projection on the master surface
433 !
434  do i=1,3
435  alnew(i)=vl(i,nope)
436  do j=1,nterms
437  alnew(i)=alnew(i)-ratio(j)*vl(i,j)
438  enddo
439  enddo
440 !
441 ! calculating the difference in relative displacement since
442 ! the start of the increment = lamda^*
443 !
444  do i=1,3
445  al(i)=alnew(i)-xstateini(3+i,1,ne0+konl(nope+1))
446  enddo
447 !
448 ! ||lambda^*||
449 !
450  val=al(1)*xn(1)+al(2)*xn(2)+al(3)*xn(3)
451 !
452 ! update the relative tangential displacement
453 !
454  do i=1,3
455  t(i)=xstateini(6+i,1,ne0+konl(nope+1))+al(i)-val*xn(i)
456  enddo
457 !
458 ! store the actual relative displacement and
459 ! the actual relative tangential displacement
460 !
461  do i=1,3
462  xstate(3+i,1,ne0+konl(nope+1))=alnew(i)
463  xstate(6+i,1,ne0+konl(nope+1))=t(i)
464  enddo
465 !
466 ! size of normal force
467 !
468  dfnl=dsqrt(fnl(1,nope)**2+fnl(2,nope)**2+fnl(3,nope)**2)
469 !
470 ! maximum size of shear force
471 !
472  dfshear=um*dfnl
473 !
474 ! plastic and elastic slip
475 !
476  do i=1,3
477  tp(i)=xstateini(i,1,ne0+konl(nope+1))
478  te(i)=t(i)-tp(i)
479  enddo
480  dte=dsqrt(te(1)*te(1)+te(2)*te(2)+te(3)*te(3))
481 !
482 ! trial force
483 !
484  do i=1,3
485  ftrial(i)=xk*te(i)
486  enddo
487  dftrial=xk*dte
488 c dftrial=dsqrt(ftrial(1)**2+ftrial(2)**2+ftrial(3)**2)
489 !
490 ! check whether stick or slip
491 !
492  if((dftrial.lt.dfshear).or.(dftrial.le.0.d0).or.
493  & (ielas.eq.1)) then
494 !
495 ! stick
496 !
497 c write(*,*)'STICK'
498  do i=1,3
499  fnl(i,nope)=fnl(i,nope)+ftrial(i)
500  xstate(i,1,ne0+konl(nope+1))=tp(i)
501  enddo
502  cstr(5)=(ftrial(1)*t1(1)+ftrial(2)*t1(2)+
503  & ftrial(3)*t1(3))/springarea(1)
504  cstr(6)=(ftrial(1)*t2(1)+ftrial(2)*t2(2)+
505  & ftrial(3)*t2(3))/springarea(1)
506 !
507 ! shear elastic energy
508 !
509  if(nener.eq.1) senergy=senergy+dftrial*dte
510  else
511 !
512 ! slip
513 !
514 c write(*,*)'SLIP'
515  dg=(dftrial-dfshear)/xk
516  do i=1,3
517  ftrial(i)=te(i)/dte
518  fnl(i,nope)=fnl(i,nope)+dfshear*ftrial(i)
519  xstate(i,1,ne0+konl(nope+1))=tp(i)+dg*ftrial(i)
520  enddo
521  cstr(5)=(dfshear*ftrial(1)*t1(1)+
522  & dfshear*ftrial(2)*t1(2)+
523  & dfshear*ftrial(3)*t1(3))/springarea(1)
524  cstr(6)=(dfshear*ftrial(1)*t2(1)+
525  & dfshear*ftrial(2)*t2(2)+
526  & dfshear*ftrial(3)*t2(3))/springarea(1)
527 !
528 ! shear elastic and viscous energy
529 !
530  if(nener.eq.1) then
531  senergy=senergy+dfshear*dfshear/xk
532  venergy=dg*dfshear
533  endif
534 !
535  endif
536  endif
537 !
538 ! storing the tangential displacements
539 !
540  cstr(2)=t(1)*t1(1)+t(2)*t1(2)+t(3)*t1(3)
541  cstr(3)=t(1)*t2(1)+t(2)*t2(2)+t(3)*t2(3)
542  endif
543 !
544 ! force in the master nodes
545 !
546  do i=1,3
547  do j=1,nterms
548  fnl(i,j)=-ratio(j)*fnl(i,nope)
549  enddo
550  enddo
551 !
552  return
subroutine ident(x, px, n, id)
Definition: ident.f:26
subroutine shape9q(xi, et, xl, xsj, xs, shp, iflag)
Definition: shape9q.f:20
subroutine shape8q(xi, et, xl, xsj, xs, shp, iflag)
Definition: shape8q.f:20
subroutine shape3tri(xi, et, xl, xsj, xs, shp, iflag)
Definition: shape3tri.f:20
subroutine shape7tri(xi, et, xl, xsj, xs, shp, iflag)
Definition: shape7tri.f:20
subroutine calcspringforc(imat, elcon, nelcon, ncmat_, ntmat_, t1l, kode, plicon, nplicon, npmat_, senergy, nener, fk, val)
Definition: calcspringforc.f:21
static double * dist
Definition: radflowload.c:42
subroutine transformatrix(xab, p, a)
Definition: transformatrix.f:20
subroutine shape4q(xi, et, xl, xsj, xs, shp, iflag)
Definition: shape4q.f:20
subroutine materialdata_sp(elcon, nelcon, imat, ntmat_, i, t1l, elconloc, kode, plicon, nplicon, npmat_, plconloc, ncmat_)
Definition: materialdata_sp.f:20
subroutine shape6tri(xi, et, xl, xsj, xs, shp, iflag)
Definition: shape6tri.f:20
subroutine attach(pneigh, pnode, nterms, ratio, dist, xil, etl)
Definition: attach.f:20
Hosted by OpenAircraft.com, (Michigan UAV, LLC)