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

Go to the source code of this file.

Functions/Subroutines

subroutine usermpc (ipompc, nodempc, coefmpc, labmpc, nmpc, nmpc_, mpcfree, ikmpc, ilmpc, nk, nk_, nodeboun, ndirboun, ikboun, ilboun, nboun, nboun_, nnodes, node, co, label, typeboun, iperturb, noderef, idirref, xboun)
 

Function/Subroutine Documentation

◆ usermpc()

subroutine usermpc ( integer, dimension(*)  ipompc,
integer, dimension(3,*)  nodempc,
real*8, dimension(*)  coefmpc,
character*20, dimension(*)  labmpc,
integer  nmpc,
integer  nmpc_,
integer  mpcfree,
integer, dimension(*)  ikmpc,
integer, dimension(*)  ilmpc,
integer  nk,
integer  nk_,
integer, dimension(*)  nodeboun,
integer, dimension(*)  ndirboun,
integer, dimension(*)  ikboun,
integer, dimension(*)  ilboun,
integer  nboun,
integer  nboun_,
integer  nnodes,
integer  node,
real*8, dimension(3,*)  co,
character*20  label,
character*1, dimension(*)  typeboun,
integer, dimension(2)  iperturb,
integer  noderef,
integer  idirref,
real*8, dimension(*)  xboun 
)
23 !
24 ! initializes mpc fields for a user MPC
25 !
26  implicit none
27 !
28  character*1 typeboun(*)
29  character*20 labmpc(*),label
30 !
31  integer ipompc(*),nodempc(3,*),nmpc,nmpc_,mpcfree,nk,nk_,
32  & ikmpc(*),idir,indexmax,indexold(3),indexnew(3),nodeold,nodemax,
33  & ilmpc(*),node,id,mpcfreeold,idof,l,nodeboun(*),iperturb(2),
34  & ndirboun(*),ikboun(*),ilboun(*),nboun,nboun_,nnodes,nodevector,
35  & index,index1,node1,i,j,nkn,idirold,idirmax,noderef,idirref,
36  & nendnode
37 !
38  real*8 coefmpc(*),co(3,*),aa(3),dd,cgx(3),pi(3),c1,c4,c9,
39  & c10,amax,xcoef,transcoef(3),xboun(*)
40 !
41  save nodevector
42 !
43  if(node.ne.0) then
44  if(nnodes.eq.1) then
45  if((label(1:7).ne.'MEANROT').and.
46  & (label(1:1).ne.'1')) then
47 !
48 ! define a new MPC
49 ! default for the dependent DOF direction is 1
50 !
51  idof=8*(node-1)+1
52 !
53  call nident(ikmpc,idof,nmpc,id)
54  if(id.gt.0) then
55  if(ikmpc(id).eq.idof) then
56  write(*,*)'*WARNING in usermpc: DOF for node ',node
57  write(*,*) ' in direction 1 has been used'
58  write(*,*)
59  & ' on the dependent side of another'
60  write(*,*) ' MPC. ',label
61  write(*,*) ' constraint cannot be applied'
62  return
63  endif
64  endif
65  endif
66 !
67  nmpc=nmpc+1
68  if(nmpc.gt.nmpc_) then
69  write(*,*) '*ERROR in usermpc: increase nmpc_'
70  call exit(201)
71  endif
72 !
73  ipompc(nmpc)=mpcfree
74  labmpc(nmpc)=label
75 !
76 ! for a mean rotation MPC the dependent degree of freedom
77 ! is determined at the end of this routine
78 !
79  if((label(1:7).ne.'MEANROT').and.
80  & (label(1:1).ne.'1')) then
81  do l=nmpc,id+2,-1
82  ikmpc(l)=ikmpc(l-1)
83  ilmpc(l)=ilmpc(l-1)
84  enddo
85  ikmpc(id+1)=idof
86  ilmpc(id+1)=nmpc
87  endif
88  endif
89 !
90 ! general case: add a term to the MPC
91 !
92  nodempc(1,mpcfree)=node
93 !
94 ! nodevector: additional node such that:
95 ! - the coordinates of this node are the axis direction
96 ! - the 1st DOF is reserved for the mean rotation value
97 !
98  if((labmpc(nmpc)(1:7).eq.'MEANROT').or.
99  & (labmpc(nmpc)(1:1).eq.'1')) then
100  nodevector=node
101  labmpc(nmpc)(1:7)='MEANROT'
102  endif
103 !
104  if(nnodes.eq.1) then
105  nodempc(2,mpcfree)=1
106  else
107  nodempc(2,mpcfree)=0
108  endif
109  coefmpc(mpcfree)=0.d0
110  mpcfree=nodempc(3,mpcfree)
111  else
112 !
113 ! MPC definition finished: add a nonhomogeneous term
114 ! (the 2nd degree of freedom of an extra node is taken;
115 ! the 1st degree of freedom can be taken by the user
116 ! for the angle dof)
117 !
118  nk=nk+1
119  if(nk.gt.nk_) then
120  write(*,*) '*ERROR in usermpc: increase nk_'
121  call exit(201)
122  endif
123 !
124  nodempc(1,mpcfree)=nk
125  nodempc(2,mpcfree)=2
126 !
127  coefmpc(mpcfree)=1.d0
128 !
129  mpcfreeold=mpcfree
130  mpcfree=nodempc(3,mpcfree)
131  nodempc(3,mpcfreeold)=0
132  idof=8*(nk-1)+2
133  call nident(ikboun,idof,nboun,id)
134  nboun=nboun+1
135  if(nboun.gt.nboun_) then
136  write(*,*) '*ERROR in usermpc: increase nboun_'
137  call exit(201)
138  endif
139  nodeboun(nboun)=nk
140  ndirboun(nboun)=2
141  xboun(nboun)=0.d0
142  typeboun(nboun)='U'
143  do l=nboun,id+2,-1
144  ikboun(l)=ikboun(l-1)
145  ilboun(l)=ilboun(l-1)
146  enddo
147  ikboun(id+1)=idof
148  ilboun(id+1)=nboun
149 !
150 ! calculating the MPC coefficients for linear applications
151 !
152  if((labmpc(nmpc)(1:7).eq.'MEANROT').or.
153  & (labmpc(nmpc)(1:1).eq.'1')) then
154  nkn=(nnodes-1)/3
155  if(3*nkn.ne.nnodes-1) then
156  write(*,*)
157  & '*ERROR in usermpc: MPC has wrong number of terms'
158  call exit(201)
159  endif
160 !
161 ! normal along the rotation axis
162 !
163  dd=0.d0
164  do i=1,3
165  aa(i)=co(i,nodevector)
166  dd=dd+aa(i)**2
167  enddo
168  dd=dsqrt(dd)
169  if(dd.lt.1.d-10) then
170  write(*,*)
171  & '*ERROR in usermpc: rotation vector has zero length'
172  call exit(201)
173  endif
174  do i=1,3
175  aa(i)=aa(i)/dd
176  enddo
177 !
178 ! finding the center of gravity of the position and the
179 ! displacements of the nodes involved in the MPC
180 !
181  do i=1,3
182  cgx(i)=0.d0
183  enddo
184 !
185  index=ipompc(nmpc)
186  do
187  node=nodempc(1,index)
188  if(node.eq.nodevector) exit
189  do j=1,3
190  cgx(j)=cgx(j)+co(j,node)
191  enddo
192  index=nodempc(3,nodempc(3,nodempc(3,index)))
193  enddo
194 !
195  do i=1,3
196  cgx(i)=cgx(i)/nkn
197  enddo
198 !
199 ! calculating the derivatives
200 !
201 ! loop over all nodes belonging to the mean rotation MPC
202 !
203  index=ipompc(nmpc)
204  do
205  node=nodempc(1,index)
206  if(node.eq.nodevector) exit
207 !
208 ! relative positions
209 !
210  do j=1,3
211  pi(j)=co(j,node)-cgx(j)
212  enddo
213 !
214 ! projection on a plane orthogonal to the rotation vector
215 !
216  c1=pi(1)*aa(1)+pi(2)*aa(2)+pi(3)*aa(3)
217  do j=1,3
218  pi(j)=pi(j)-c1*aa(j)
219  enddo
220 !
221  c1=pi(1)*pi(1)+pi(2)*pi(2)+pi(3)*pi(3)
222  if(c1.lt.1.d-20) then
223  if(label(8:9).ne.'BS') then
224  write(*,*) '*WARNING in usermpc: node ',node
225  write(*,*) ' is very close to the '
226  write(*,*) ' rotation axis through the'
227  write(*,*) ' center of gravity of'
228  write(*,*) ' the nodal cloud in a'
229  write(*,*) ' mean rotation MPC.'
230  write(*,*) ' This node is not taken'
231  write(*,*) ' into account in the MPC'
232  endif
233  index=nodempc(3,nodempc(3,nodempc(3,index)))
234  cycle
235  endif
236 !
237  do j=1,3
238  if(j.eq.1) then
239  c4=aa(2)*pi(3)-aa(3)*pi(2)
240  elseif(j.eq.2) then
241  c4=aa(3)*pi(1)-aa(1)*pi(3)
242  else
243  c4=aa(1)*pi(2)-aa(2)*pi(1)
244  endif
245  c9=c4/c1
246 !
247  index1=ipompc(nmpc)
248  do
249  node1=nodempc(1,index1)
250  if(node1.eq.nodevector) exit
251  if(node1.eq.node) then
252  c10=c9*(1.d0-1.d0/real(nkn))
253  else
254  c10=-c9/real(nkn)
255  endif
256  if(j.eq.1) then
257  coefmpc(index1)=coefmpc(index1)+c10
258  elseif(j.eq.2) then
259  coefmpc(nodempc(3,index1))=
260  & coefmpc(nodempc(3,index1))+c10
261  else
262  coefmpc(nodempc(3,nodempc(3,index1)))=
263  & coefmpc(nodempc(3,nodempc(3,index1)))+c10
264  endif
265  index1=nodempc(3,nodempc(3,nodempc(3,index1)))
266  enddo
267  enddo
268  index=nodempc(3,nodempc(3,nodempc(3,index)))
269  enddo
270  coefmpc(index)=-nkn
271 !
272 ! assigning the degrees of freedom
273 !
274  j=0
275  index=ipompc(nmpc)
276  do
277  j=j+1
278  if(j.gt.3) j=1
279  nodempc(2,index)=j
280  index=nodempc(3,index)
281  if(nodempc(3,index).eq.0) exit
282  enddo
283 !
284 ! look for biggest coefficient of all but the last
285 ! regular node. The general form of the MPC is:
286 ! regular nodes, angle dof and inhomogeneous dof
287 ! The last regular node is exempted so that it can
288 ! be used for translational dofs in the application of
289 ! moments/rotations to beams/shells.
290 !
291 ! check for the coefficients of the last regular node
292 ! this node is used for translational dofs in shell
293 ! and beam applications
294 !
295  if(label(8:9).eq.'BS') then
296  index=ipompc(nmpc)
297  do i=1,nnodes-4
298  index=nodempc(3,index)
299  enddo
300  do i=1,3
301  transcoef(i)=coefmpc(index)
302  index=nodempc(3,index)
303  enddo
304  endif
305 !
306  indexmax=0
307  index=ipompc(nmpc)
308  amax=1.d-5
309 !
310 ! loop over all nodes - angle node - last regular node
311 !
312  if(label(8:9).eq.'BS') then
313  nendnode=nnodes-4
314  else
315  nendnode=nnodes-1
316  endif
317  do i=1,nendnode
318  if(dabs(coefmpc(index)).gt.amax) then
319  idir=nodempc(2,index)
320 !
321 ! dependent node of MPC should not have the same
322 ! sign as the corresponding dof of the translational
323 ! degrees of freedom: avoids the occurence of a
324 ! zero coefficient of the dependent term if both
325 ! rotational and translational dofs are suppressed
326 !
327  if(label(8:9).eq.'BS') then
328  if(coefmpc(index)*transcoef(idir).gt.0) then
329  index=nodempc(3,index)
330  cycle
331  endif
332  endif
333 !
334  node=nodempc(1,index)
335  idof=8*(node-1)+idir
336 !
337 ! check whether the node was used in another MPC
338 !
339  call nident(ikmpc,idof,nmpc-1,id)
340  if(id.gt.0) then
341  if(ikmpc(id).eq.idof) then
342  index=nodempc(3,index)
343  cycle
344  endif
345  endif
346 !
347 ! check whether the node was used in a SPC
348 !
349  call nident(ikboun,idof,nboun,id)
350  if(id.gt.0) then
351  if(ikboun(id).eq.idof) then
352  index=nodempc(3,index)
353  cycle
354  endif
355  endif
356 !
357  amax=dabs(coefmpc(index))
358  indexmax=index
359  endif
360 !
361 ! after each node has been treated, a check is performed
362 ! whether indexmax is already nonzero. Taking too many
363 ! nodes into account may lead to dependent equations if
364 ! all rotational dofs are constrained.
365 !
366  if((i/3)*3.eq.i) then
367  if(indexmax.ne.0) exit
368  endif
369 !
370  index=nodempc(3,index)
371  enddo
372 !
373  if(indexmax.eq.0) then
374  if(idirref.ne.0) then
375  write(*,*) '*WARNING in usermpc: no MPC is '
376  write(*,*) ' generated for the mean'
377  write(*,*) ' rotation in node ',noderef
378  write(*,*) ' and direction ',idirref+3
379  else
380  write(*,*) '*WARNING in usermpc: no MPC is '
381  write(*,*) ' generated for the mean'
382  write(*,*) ' rotation definition starting '
383  write(*,*) ' with node ',noderef
384  endif
385 !
386 ! removing the MPC
387 !
388  mpcfreeold=mpcfree
389  index=ipompc(nmpc)
390  ipompc(nmpc)=0
391  mpcfree=index
392 !
393 ! removing the MPC from fields nodempc and coefmpc
394 !
395  do
396  nodempc(1,index)=0
397  nodempc(2,index)=0
398  coefmpc(index)=0
399  if(nodempc(3,index).ne.0) then
400  index=nodempc(3,index)
401  else
402  nodempc(3,index)=mpcfreeold
403  exit
404  endif
405  enddo
406 !
407 ! decrementing nmpc
408 !
409  nmpc=nmpc-1
410 !
411 ! token to signify that no MPC was generated
412 ! (needed in gen3dboun.f)
413 !
414  node=-1
415  return
416  endif
417 !
418  nodemax=nodempc(1,indexmax)
419  idirmax=nodempc(2,indexmax)
420  index=ipompc(nmpc)
421 !
422  nodeold=nodempc(1,index)
423  idirold=nodempc(2,index)
424 !
425 ! exchange the node information in the MPC
426 !
427  if(nodemax.ne.nodeold) then
428 !
429  indexold(1)=index
430  indexold(2)=nodempc(3,index)
431  indexold(3)=nodempc(3,indexold(2))
432 !
433  index=nodempc(3,indexold(3))
434  do
435  if(nodempc(1,index).eq.nodevector) exit
436  if(nodempc(1,index).eq.nodemax) then
437  if(nodempc(2,index).eq.1) then
438  indexnew(1)=index
439  elseif(nodempc(2,index).eq.2) then
440  indexnew(2)=index
441  else
442  indexnew(3)=index
443  endif
444  endif
445  index=nodempc(3,index)
446  enddo
447 !
448  do j=1,3
449  node=nodempc(1,indexold(j))
450  idir=nodempc(2,indexold(j))
451  xcoef=coefmpc(indexold(j))
452  nodempc(1,indexold(j))=nodempc(1,indexnew(j))
453  nodempc(2,indexold(j))=nodempc(2,indexnew(j))
454  coefmpc(indexold(j))=coefmpc(indexnew(j))
455  nodempc(1,indexnew(j))=node
456  nodempc(2,indexnew(j))=idir
457  coefmpc(indexnew(j))=xcoef
458  enddo
459  endif
460 !
461 ! exchange the direction information in the MPC
462 !
463  index=ipompc(nmpc)
464  if(idirmax.ne.1) then
465  indexold(1)=index
466  if(idirmax.eq.2) then
467  indexnew(1)=nodempc(3,index)
468  else
469  indexnew(1)=nodempc(3,nodempc(3,index))
470  endif
471 !
472  do j=1,1
473  idir=nodempc(2,indexold(j))
474  xcoef=coefmpc(indexold(j))
475  nodempc(2,indexold(j))=nodempc(2,indexnew(j))
476  coefmpc(indexold(j))=coefmpc(indexnew(j))
477  nodempc(2,indexnew(j))=idir
478  coefmpc(indexnew(j))=xcoef
479  enddo
480  endif
481 !
482 ! determining the dependent dof of the MPC
483 !
484  idof=8*(nodemax-1)+idirmax
485  call nident(ikmpc,idof,nmpc-1,id)
486  do l=nmpc,id+2,-1
487  ikmpc(l)=ikmpc(l-1)
488  ilmpc(l)=ilmpc(l-1)
489  enddo
490  ikmpc(id+1)=idof
491  ilmpc(id+1)=nmpc
492 !
493  elseif(labmpc(nmpc)(1:4).eq.'DIST') then
494  iperturb(2)=1
495  write(*,*) '*INFO in usermpc: nonlinear geometric'
496  write(*,*) ' effects are turned on'
497  write(*,*)
498  if(iperturb(1).eq.0) iperturb(1)=2
499 c elseif(labmpc(nmpc)(1:3).eq.'GAP') then
500 c iperturb(2)=1
501 c write(*,*) '*INFO in usermpc: nonlinear geometric'
502 c write(*,*) ' effects are turned on'
503 c write(*,*)
504 c if(iperturb(1).eq.0) iperturb(1)=2
505  elseif(labmpc(nmpc)(1:4).eq.'USER') then
506  iperturb(2)=1
507  write(*,*) '*INFO in usermpc: nonlinear geometric'
508  write(*,*) ' effects are turned on'
509  write(*,*)
510  if(iperturb(1).eq.0) iperturb(1)=2
511  else
512  write(*,*) '*ERROR in usermpc: mpc of type',labmpc(nmpc)
513  write(*,*) ' is unknown'
514  call exit(201)
515  endif
516  endif
517 !
518  return
static double * c1
Definition: mafillvcompmain.c:30
subroutine nident(x, px, n, id)
Definition: nident.f:26
Hosted by OpenAircraft.com, (Michigan UAV, LLC)