atomes 1.1.14
atomes: an atomic scale modeling tool box
Loading...
Searching...
No Matches
utils.F90
Go to the documentation of this file.
1! This file is part of the 'atomes' software.
2!
3! 'atomes' is free software: you can redistribute it and/or modify it under the terms
4! of the GNU Affero General Public License as published by the Free Software Foundation,
5! either version 3 of the License, or (at your option) any later version.
6!
7! 'atomes' is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
8! without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9! See the GNU General Public License for more details.
10!
11! You should have received a copy of the GNU Affero General Public License along with 'atomes'.
12! If not, see <https://www.gnu.org/licenses/>
13!
14! Copyright (C) 2022-2024 by CNRS and University of Strasbourg
15!
20
21!
22! This file contains various tools
23!
24
25!********************************************************************
26!
27! Transformer un entier en chaine de charactères
28! Transform an integer into character
29!
30
31SUBROUTINE charint(Word, Num)
32
33IMPLICIT NONE
34
35INTEGER :: lc
36
37INTEGER, INTENT(IN) :: Num
38
39CHARACTER (LEN=16) :: Pseudo
40
41CHARACTER (LEN=15), INTENT(INOUT) :: Word
42
43
44word=' '
45write (word, *) num
46lc=1
47do while (word(1:lc) .eq. ' ')
48
49 lc= lc+1
50
51enddo
52
53pseudo=word
54word=' '
55
56write (word, *) pseudo(lc:len_trim(pseudo))
57
58END SUBROUTINE
59
60SUBROUTINE creat_ring (RING_INIT, ELEM_CR)
61
62USE parameters
63
64IMPLICIT NONE
65
66TYPE (RING), INTENT(INOUT) :: RING_INIT
67INTEGER, INTENT(IN) :: ELEM_CR
68
69ring_init%SPEC = 0
70ring_init%ATOM = elem_cr
71nullify(ring_init%PAST)
72nullify(ring_init%NEXT)
73
74END SUBROUTINE
75
76SUBROUTINE do_ring (THE_RING, ELEM_DO)
77
78USE parameters
79
80IMPLICIT NONE
81
82TYPE (RING), POINTER, INTENT(INOUT) :: THE_RING
83!INTEGER, DIMENSION(NA), INTENT(INOUT) :: RPT
84INTEGER, INTENT(IN) :: ELEM_DO
85TYPE (RING), POINTER :: NEW
86allocate(new, stat=err)
87if (err .ne. 0) then
88 call show_error ("Impossible to allocate memory"//char(0), &
89 "Subroutine: DO_RING"//char(0), "Pointer: NEW"//char(0))
90 alc=.true.
91 goto 001
92endif
93nullify(new%NEXT)
94nullify(new%PAST)
95the_ring%NEXT => new
96new%PAST => the_ring
97new%ATOM = elem_do
98new%SPEC = the_ring%SPEC+1
99the_ring => new
100!if (RPT(THE_RING%ATOM) .eq. 0) then
101! RPT(THE_RING%ATOM) = 1
102!endif
103
104001 continue
105
106END SUBROUTINE
107
108!********************************************************************
109!
110! Calculer une distance
111! Compute a distance including PBC
112!
113
114SUBROUTINE calcrij(AT1, AT2, STEP_1, STEP_2, SID)
115
116USE parameters
117
118IMPLICIT NONE
119
120INTEGER, INTENT(IN) :: AT1, AT2, STEP_1, STEP_2, SID
121INTEGER :: R1
122DOUBLE PRECISION, DIMENSION(3) :: COORDA, COORDB
123DOUBLE PRECISION, DIMENSION(3) :: Aij, Bij, Nij
124
125if (step_1 .eq. -2) then
126
127 do r1=1, 3
128 coorda(r1) = nfullpos(at1,r1,step_2)
129 coordb(r1) = nfullpos(at2,r1,step_2)
130 enddo
131
132elseif (step_1 .eq. -1) then
133
134! Prepos for MSD
135 do r1=1, 3
136 coorda(r1) = pob(at2,r1)
137 coordb(r1) = poa(at1,r1)
138 enddo
139
140else
141! Standard inter-atomic distance
142 do r1=1, 3
143 coorda(r1) = fullpos(at1,r1,step_1)
144 coordb(r1) = fullpos(at2,r1,step_2)
145 enddo
146
147endif
148
149do r1=1, 3
150 rij(r1) = coorda(r1) - coordb(r1)
151enddo
152
153if (.not.pbc) goto 001
154
155! Test if the simulation box is cubic-like symmetric
156! For that we check the lattice angles
157if (the_box(sid)%GLASS) then
158
159 do r1=1, 3
160 rij(r1)=rij(r1) - anint(rij(r1)/(the_box(sid)%modv(r1)))*(the_box(sid)%modv(r1))
161 enddo
162
163else
164
165 aij = matmul(coorda,the_box(sid)%carttofrac)
166 bij = matmul(coordb,the_box(sid)%carttofrac)
167 do r1=1,3
168 nij(r1) = aij(r1) - bij(r1)
169 nij(r1) = nij(r1) - anint(nij(r1))
170 enddo
171 rij = matmul(nij,the_box(sid)%fractocart)
172
173endif
174
175001 continue
176
177dij=0.0d0
178do r1=1, 3
179 dij=dij+rij(r1)**2
180enddo
181
182END SUBROUTINE
183
184DOUBLE PRECISION FUNCTION calcdij(R12, AT1, AT2, STEP_1, STEP_2, SID)
185
186USE parameters
187
188IMPLICIT NONE
189
190DOUBLE PRECISION, DIMENSION(3), INTENT(INOUT) :: r12
191INTEGER, INTENT(IN) :: at1, at2, step_1, step_2, sid
192INTEGER :: r1
193DOUBLE PRECISION, DIMENSION(3) :: coorda, coordb
194DOUBLE PRECISION, DIMENSION(3) :: aij, bij, nij
195
196if (step_1 .eq. -2) then
197
198 do r1=1, 3
199 coorda(r1) = nfullpos(at1,r1,step_2)
200 coordb(r1) = nfullpos(at2,r1,step_2)
201 enddo
202
203elseif (step_1 .eq. -1) then
204
205! Prepos for MSD
206 do r1=1, 3
207 coorda(r1) = pob(at2,r1)
208 coordb(r1) = poa(at1,r1)
209 enddo
210
211else
212! Standard inter-atomic distance
213 do r1=1, 3
214 coorda(r1) = fullpos(at1,r1,step_1)
215 coordb(r1) = fullpos(at2,r1,step_2)
216 enddo
217
218endif
219
220do r1=1, 3
221 r12(r1) = coorda(r1) - coordb(r1)
222enddo
223
224if (.not.pbc) goto 001
225
226! Test if the simulation box is cubic-like symetric
227! For that we check the lattice angles
228if (the_box(sid)%GLASS) then
229
230 do r1=1, 3
231 r12(r1)=r12(r1) - anint(r12(r1)/(the_box(sid)%modv(r1)))*(the_box(sid)%modv(r1))
232 enddo
233
234else
235
236 aij = matmul(coorda,the_box(sid)%carttofrac)
237 bij = matmul(coordb,the_box(sid)%carttofrac)
238 do r1=1,3
239 nij(r1) = aij(r1) - bij(r1)
240 nij(r1) = nij(r1) - anint(nij(r1))
241 enddo
242 r12 = matmul(nij,the_box(sid)%fractocart)
243
244endif
245
246001 continue
247
248calcdij = 0.0d0
249do r1=1, 3
250 calcdij = calcdij + r12(r1)**2
251enddo
252
253END FUNCTION
254
255!********************************************************************
256!
257! Home made arcosine calculation
258!
259
260DOUBLE PRECISION FUNCTION sacos (ANG)
261
262USE parameters
263
264DOUBLE PRECISION, INTENT(IN) :: ang
265DOUBLE PRECISION :: scos
266
267if (ang .lt. -1.0d0) then
268 scos = -2.0d0 - ang
269else if (ang .gt. 1.0d0) then
270 scos = 2.0d0 - ang
271else
272 scos = ang
273endif
274sacos = dacos(scos)*180.d0/pi
275
276END FUNCTION
277
278!********************************************************************
279!
280! Calculer un angle direct
281! Compute a direct angle
282!
283
284DOUBLE PRECISION FUNCTION angijk(ATG1, ATG2, ATG3, ASTEP)
285
286USE parameters
287
288IMPLICIT NONE
289
290INTEGER, INTENT(IN) :: atg1, atg2, atg3, astep
291INTEGER :: ag1, ag2
292DOUBLE PRECISION :: daa, dbb, vang
293DOUBLE PRECISION, DIMENSION(3) :: raa, rbb
294
295INTERFACE
296 DOUBLE PRECISION FUNCTION calcdij(R12, AT1, AT2, STEP_1, STEP_2, SID)
297 DOUBLE PRECISION, DIMENSION(3), INTENT(INOUT) :: r12
298 INTEGER, INTENT(IN) :: at1, at2, step_1, step_2, sid
299 END FUNCTION
300 DOUBLE PRECISION FUNCTION sacos (ANG)
301 DOUBLE PRECISION, INTENT(IN) :: ang
302 END FUNCTION
303END INTERFACE
304
305if (ncells .gt. 1) then
306 ag2 = astep
307else
308 ag2 = 1
309endif
310
311daa = calcdij(raa, atg2,atg1,astep,astep,ag2)
312daa=sqrt(daa)
313dbb = calcdij(rbb, atg2,atg3,astep,astep,ag2)
314vang=0.0d0
315do ag1=1, 3
316 vang=vang+raa(ag1)*rbb(ag1)
317enddo
318dbb=sqrt(dbb)
319
320angijk = sacos(vang/(daa*dbb))
321
322END FUNCTION
323
324!********************************************************************
325!
326! Calculer un angle dièdre
327! Compute a dihedral angle
328!
329
330DOUBLE PRECISION FUNCTION diedre(DG1, DG2, DG3, DG4, DSTEP)
331
332USE parameters
333
334IMPLICIT NONE
335
336INTEGER, INTENT(IN) :: dg1, dg2, dg3, dg4, dstep
337INTEGER :: ag, ah
338DOUBLE PRECISION :: dh1, dh2, dh3, vdi
339DOUBLE PRECISION, DIMENSION(3) :: d12, d23, d34
340DOUBLE PRECISION, DIMENSION(3) :: vh1, vh2
341
342INTERFACE
343 DOUBLE PRECISION FUNCTION calcdij(R12, AT1, AT2, STEP_1, STEP_2, SID)
344 DOUBLE PRECISION, DIMENSION(3), INTENT(INOUT) :: r12
345 INTEGER, INTENT(IN) :: at1, at2, step_1, step_2, sid
346 END FUNCTION
347 DOUBLE PRECISION FUNCTION sacos (ANG)
348 DOUBLE PRECISION, INTENT(IN) :: ang
349 END FUNCTION
350END INTERFACE
351
352if (ncells .gt. 1) then
353 ah = dstep
354else
355 ah = 1
356endif
357
358dh1 = calcdij(d12,dg1,dg2,dstep,dstep,ah)
359dh2 = calcdij(d23,dg2,dg3,dstep,dstep,ah)
360dh3 = calcdij(d34,dg3,dg4,dstep,dstep,ah)
361
362vh1(1) = d12(2)*d23(3) - d12(3)*d23(2)
363vh1(2) = d12(3)*d23(1) - d12(1)*d23(3)
364vh1(3) = d12(1)*d23(2) - d12(2)*d23(1)
365
366vh2(1) = d23(2)*d34(3) - d23(3)*d34(2)
367vh2(2) = d23(3)*d34(1) - d23(1)*d34(3)
368vh2(3) = d23(1)*d34(2) - d23(2)*d34(1)
369
370dh1=0.0d0
371dh2=0.0d0
372do ag=1, 3
373 dh1 = dh1 + vh1(ag)*vh1(ag)
374 dh2 = dh2 + vh2(ag)*vh2(ag)
375enddo
376dh1=sqrt(dh1)
377dh2=sqrt(dh2)
378if (dh1.eq.0.0d0 .or. dh2.eq.0.0d0) then
379 diedre = 0.0d0
380else
381 vdi = 0.0d0
382 do ag=1, 3
383 vdi=vdi+vh1(ag)*vh2(ag)
384 enddo
385 vdi = vdi/(dh1*dh2)
386 diedre = sacos(vdi)
387endif
388
389END FUNCTION
390
391! Cas particulier lors des statistiques d'anneaux
392
393SUBROUTINE ect_type_rings(MOYENNE, TABLEAU, LONGTE, LREPRES, EC_TYPE)
394
395INTEGER :: pose
396INTEGER, INTENT(IN) :: LONGTE, LREPRES
397
398DOUBLE PRECISION, INTENT(IN) :: MOYENNE
399DOUBLE PRECISION, INTENT(IN), DIMENSION(LONGTE) :: TABLEAU
400DOUBLE PRECISION, INTENT(INOUT) :: EC_TYPE
401
402ec_type=0.0d0
403
404do pose=1, longte
405
406 if (tableau(pose) .ne. 0.0) ec_type= ec_type + (tableau(pose) - moyenne)**2
407
408enddo
409
410ec_type=sqrt(ec_type/dble(lrepres-1))
411
412END SUBROUTINE
413
414!********************************************************************
415!
416! Générateur de nombre aléatoire
417! Numerical recipes random number generator 3
418!
419
420DOUBLE PRECISION FUNCTION ran3 (idnum)
421
422INTEGER, INTENT(IN) :: idnum
423INTEGER :: idum
424INTEGER :: mbig,mseed,mz
425INTEGER :: iii,iff,ii,inext,inextp,k
426INTEGER :: mj,mk,ma(55)
427
428DOUBLE PRECISION :: fac
429
430parameter(mbig=1000000000,mseed=161803398,mz=0,fac=1./mbig)
431SAVE iff,inext,inextp,ma
432DATA iff /0/
433
434idum = idnum
435if(idum.lt.0 .or. iff.eq.0)then
436
437 iff=1
438 mj=mseed-iabs(idum)
439 mj=mod(mj,mbig)
440 ma(55)=mj
441 mk=1
442 do 11 iii=1,54
443
444 ii=mod(21*iii,55)
445 ma(ii)=mk
446 mk=mj-mk
447 if(mk.lt.mz)mk=mk+mbig
448 mj=ma(ii)
449
45011 continue
451
452 do 13 k=1,4
453
454 do 12 iii=1,55
455
456 ma(iii)=ma(iii)-ma(1+mod(iii+30,55))
457 if(ma(iii).lt.mz)ma(iii)=ma(iii)+mbig
458
45912 continue
460
46113 continue
462 inext=0
463 inextp=31
464 idum=1
465
466endif
467
468inext=inext+1
469if(inext.eq.56)inext=1
470inextp=inextp+1
471if(inextp.eq.56)inextp=1
472mj=ma(inext)-ma(inextp)
473if(mj.lt.mz)mj=mj+mbig
474ma(inext)=mj
475ran3=mj*fac
476
477END FUNCTION
478
479REAL (KIND=c_double) FUNCTION random3(seed) bind (C,NAME='random3_')
480
481use, INTRINSIC :: iso_c_binding
482
483INTEGER (KIND=c_int), INTENT(IN) :: seed
484
485INTERFACE
486 DOUBLE PRECISION FUNCTION ran3 (idnum)
487 INTEGER, INTENT(IN) :: idnum
488 END FUNCTION
489END INTERFACE
490
491random3 = ran3(seed)
492
493END FUNCTION
494
495!********************************************************************
496!
497! Calculer la somme d'une série de valeurs
498! Compute sum of a list of values
499!
500
501SUBROUTINE somme(TABS, LONGTS, SOMTAB)
502
503INTEGER :: posm
504INTEGER, INTENT(IN) :: LONGTS
505
506DOUBLE PRECISION, INTENT(INOUT) :: SOMTAB
507DOUBLE PRECISION, INTENT(IN), DIMENSION(LONGTS) :: TABS
508
509somtab=0.0d0
510
511do posm=1, longts
512
513somtab=somtab+tabs(posm)
514
515enddo
516
517END SUBROUTINE
518
519!********************************************************************
520!
521! Calculer la moyenne d'une série de valeurs
522! Compute the average of list of values
523!
524
525SUBROUTINE moyenne(TABLEAU, LONGTM, MOYTAB)
526
527INTEGER :: posm
528INTEGER, INTENT(IN) :: LONGTM
529
530DOUBLE PRECISION, INTENT(INOUT) :: MOYTAB
531DOUBLE PRECISION, INTENT(IN), DIMENSION(LONGTM) :: TABLEAU
532
533moytab=0.0d0
534
535do posm=1, longtm
536
537moytab=moytab+tableau(posm)
538
539enddo
540
541moytab=moytab/dble(longtm)
542
543END SUBROUTINE
544
545!********************************************************************
546!
547! Calculer l'écart type sur une série de valeurs
548! Compute the standard error on a list of values
549!
550
551SUBROUTINE ect_type(MOYENNE, TABLEAU, LONGTE, EC_TYPE)
552
553INTEGER :: pose
554INTEGER, INTENT(IN) :: LONGTE
555
556DOUBLE PRECISION, INTENT(IN) :: MOYENNE
557DOUBLE PRECISION, INTENT(IN), DIMENSION(LONGTE) :: TABLEAU
558DOUBLE PRECISION, INTENT(INOUT) :: EC_TYPE
559
560ec_type=0.0d0
561
562do pose=1, longte
563
564ec_type= ec_type + (tableau(pose) - moyenne)**2
565
566enddo
567
568ec_type=sqrt(ec_type/dble(longte-1))
569
570END SUBROUTINE
571
572!********************************************************************
573!
574! Trier une liste d'entiers
575! Sort a list of integers
576! This is the most simple sort
577! For an improved routine (huge data to sort) see SORT3 in this file
578!
579
580SUBROUTINE tri(TAB, DIMTAB)
581
582IMPLICIT NONE
583
584INTEGER, INTENT(IN) :: DIMTAB
585INTEGER, DIMENSION(DIMTAB), INTENT(INOUT) :: TAB
586INTEGER :: SORTX, SORTY, VALUE
587
588do sortx=2, dimtab
589
590 VALUE=tab(sortx)
591
592 do sorty=sortx-1, 1, -1
593
594 if (tab(sorty) .le. VALUE) exit
595
596 tab(sorty+1)=tab(sorty)
597
598 enddo
599
600 tab(sorty+1)=VALUE
601
602enddo
603
604END SUBROUTINE
605
606!********************************************************************
607!
608! Lisser une courbe / To smooth a curve
609!
610
611LOGICAL FUNCTION smooth (TABTOLISS, GTOLISS, DIMTOLISS, SIGMALISS)
612
613! Lissage selon une gaussienne
614! Gaussian smoothing - zero based curve
615
616IMPLICIT NONE
617
618INTEGER, INTENT(IN) :: dimtoliss
619DOUBLE PRECISION, INTENT(IN) :: sigmaliss
620DOUBLE PRECISION, INTENT(IN), DIMENSION(DIMTOLISS) :: gtoliss
621DOUBLE PRECISION, INTENT(INOUT), DIMENSION(DIMTOLISS) :: tabtoliss
622
623INTEGER :: inda, indb, err
624DOUBLE PRECISION, PARAMETER :: pi=acos(-1.0)
625DOUBLE PRECISION :: dq, dq2
626DOUBLE PRECISION :: factliss
627
628DOUBLE PRECISION, DIMENSION(:), ALLOCATABLE :: newtab
629
630allocate(newtab(dimtoliss), stat=err)
631if (err .ne. 0) then
632 call show_error ("Impossible to allocate memory"//char(0), &
633 "Function: SMOOTH"//char(0), "Table: NEWTAB"//char(0))
634 smooth=.false.
635 goto 001
636endif
637
638do inda=1, dimtoliss
639 newtab(inda)=0.0d0
640enddo
641
642factliss=1.0d0/(sigmaliss*sqrt(2.0d0*pi))
643
644do inda=1, dimtoliss
645 do indb=1, dimtoliss
646
647 if(indb .eq. 1)then
648 dq= gtoliss(2)-gtoliss(1)
649 elseif (indb .eq. dimtoliss) then
650 dq = gtoliss(dimtoliss)- gtoliss(dimtoliss-1)
651 else
652 dq = (gtoliss(indb+1)- gtoliss(indb-1))*0.5
653 endif
654
655 dq2=(gtoliss(inda)-gtoliss(indb))*(gtoliss(inda)-gtoliss(indb))
656 newtab(inda) = newtab(inda) + exp(-dq2/(2.0d0*sigmaliss*sigmaliss))*tabtoliss(indb)*dq
657
658 enddo
659 newtab(inda)=factliss*newtab(inda)
660enddo
661
662do inda=1, dimtoliss
663 tabtoliss(inda)=newtab(inda)
664enddo
665
666smooth=.true.
667
668001 continue
669
670if (allocated(newtab)) deallocate(newtab)
671
672END FUNCTION
673
674!********************************************************************
675!
676! Sort routine adapted from:
677! Numerical sort array 3 - Quicksort INTEGER
678!
679
680SUBROUTINE sort3(arr, ndum)
681
682INTEGER, INTENT(IN) :: ndum
683INTEGER, DIMENSION(ndum) :: index
684
685INTEGER, DIMENSION(ndum), INTENT(INOUT) :: arr
686
687call indexx_i(arr, index, ndum)
688
689arr=arr(index)
690
691END SUBROUTINE
692
693SUBROUTINE indexx_i(arr, index, n)
694
695 IMPLICIT NONE
696 INTEGER, PARAMETER :: NPAR_ARTH=16,npar2_arth=8
697 INTEGER, DIMENSION(n), INTENT(INOUT) :: index
698 INTEGER, PARAMETER :: NN=15, nstack=50
699 INTEGER, INTENT(IN) :: n
700 INTEGER :: k,i,j,indext,jstack,l,r
701 INTEGER, DIMENSION(NSTACK) :: istack
702 INTEGER :: a
703 INTEGER, DIMENSION(n), INTENT(IN) :: arr
704
705 call arth(1,1,n,index)
706 jstack=0
707 l=1
708 r=n
709 do
710 if (r-l < nn) then
711 do j=l+1,r
712 indext=index(j)
713 a=arr(indext)
714 do i=j-1,l,-1
715 if (arr(index(i)) <= a) exit
716 index(i+1)=index(i)
717 end do
718 index(i+1)=indext
719 end do
720 if (jstack .eq. 0) RETURN
721 r=istack(jstack)
722 l=istack(jstack-1)
723 jstack=jstack-2
724 else
725 k=(l+r)/2
726 call swap(index(k),index(l+1))
727 call icomp_xchg(index(l),index(r))
728 call icomp_xchg(index(l+1),index(r))
729 call icomp_xchg(index(l),index(l+1))
730 i=l+1
731 j=r
732 indext=index(l+1)
733 a=arr(indext)
734 do
735 do
736 i=i+1
737 if (arr(index(i)) >= a) exit
738 end do
739 do
740 j=j-1
741 if (arr(index(j)) <= a) exit
742 end do
743 if (j < i) exit
744 call swap(index(i),index(j))
745 end do
746 index(l+1)=index(j)
747 index(j)=indext
748 jstack=jstack+2
749 if (jstack > nstack) write (6, *) 'Sort3 error: indexx: NSTACK too small'
750 if (r-i+1 >= j-l) then
751 istack(jstack)=r
752 istack(jstack-1)=i
753 r=j-1
754 else
755 istack(jstack)=j-1
756 istack(jstack-1)=l
757 l=i
758 end if
759 end if
760 end do
761 CONTAINS
762!BL
763 SUBROUTINE icomp_xchg(i, j)
764 INTEGER, INTENT(INOUT) :: i,j
765 INTEGER :: swp
766 if (arr(j) < arr(i)) then
767 swp=i
768 i=j
769 j=swp
770 end if
771 END SUBROUTINE icomp_xchg
772
773 SUBROUTINE arth(first, increment, m, arth_i)
774 INTEGER, INTENT(IN) :: first,increment,m
775 INTEGER, DIMENSION(m) :: arth_i
776 INTEGER :: k,k2,temp
777
778 if (m > 0) arth_i(1)=first
779 if (m <= npar_arth) then
780 do k=2,m
781 arth_i(k)=arth_i(k-1)+increment
782 end do
783 else
784 do k=2,npar2_arth
785 arth_i(k)=arth_i(k-1)+increment
786 end do
787 temp=increment*npar2_arth
788 k=npar2_arth
789 do
790 if (k >= m) exit
791 k2=k+k
792 arth_i(k+1:min(k2,m))=temp+arth_i(1:min(k,m-k))
793 temp=temp+temp
794 k=k2
795 end do
796 end if
797 END SUBROUTINE
798
799 SUBROUTINE swap(a,b)
800 INTEGER, INTENT(INOUT) :: a,b
801 INTEGER :: dum
802 dum=a
803 a=b
804 b=dum
805 END SUBROUTINE swap
806
807END SUBROUTINE indexx_i
808!********************************************************************
809
810!********************************************************************
811!
812! Sort routine adapted from:
813! Numerical sort array 3 - Quicksort DOUBLE PRECISION
814!
815
816SUBROUTINE sort3_dp (arr, ndum)
817
818INTEGER, INTENT(IN) :: ndum
819INTEGER, DIMENSION(ndum) :: index
820
821DOUBLE PRECISION, DIMENSION(ndum), INTENT(INOUT) :: arr
822
823call indexx_dp (arr, index, ndum)
824
825arr=arr(index)
826
827END SUBROUTINE
828
829SUBROUTINE indexx_dp (arr, index, n)
830
831 IMPLICIT NONE
832 INTEGER, PARAMETER :: NPAR_ARTH=16,npar2_arth=8
833 INTEGER, DIMENSION(n), INTENT(INOUT) :: index
834 INTEGER, PARAMETER :: NN=15, nstack=50
835 INTEGER, INTENT(IN) :: n
836 INTEGER :: k,i,j,indext,jstack,l,r
837 INTEGER, DIMENSION(NSTACK) :: istack
838 DOUBLE PRECISION :: a
839 DOUBLE PRECISION, DIMENSION(n), INTENT(IN) :: arr
840
841 call arth(1,1,n,index)
842 jstack=0
843 l=1
844 r=n
845 do
846 if (r-l < nn) then
847 do j=l+1,r
848 indext=index(j)
849 a=arr(indext)
850 do i=j-1,l,-1
851 if (arr(index(i)) <= a) exit
852 index(i+1)=index(i)
853 end do
854 index(i+1)=indext
855 end do
856 if (jstack .eq. 0) RETURN
857 r=istack(jstack)
858 l=istack(jstack-1)
859 jstack=jstack-2
860 else
861 k=(l+r)/2
862 call swap(index(k),index(l+1))
863 call icomp_xchg(index(l),index(r))
864 call icomp_xchg(index(l+1),index(r))
865 call icomp_xchg(index(l),index(l+1))
866 i=l+1
867 j=r
868 indext=index(l+1)
869 a=arr(indext)
870 do
871 do
872 i=i+1
873 if (arr(index(i)) >= a) exit
874 end do
875 do
876 j=j-1
877 if (arr(index(j)) <= a) exit
878 end do
879 if (j < i) exit
880 call swap(index(i),index(j))
881 end do
882 index(l+1)=index(j)
883 index(j)=indext
884 jstack=jstack+2
885 if (jstack > nstack) write (6, *) 'Sort3 error: indexx: NSTACK too small'
886 if (r-i+1 >= j-l) then
887 istack(jstack)=r
888 istack(jstack-1)=i
889 r=j-1
890 else
891 istack(jstack)=j-1
892 istack(jstack-1)=l
893 l=i
894 end if
895 end if
896 end do
897 CONTAINS
898!BL
899 SUBROUTINE icomp_xchg(i, j)
900 INTEGER, INTENT(INOUT) :: i,j
901 INTEGER :: swp
902 if (arr(j) < arr(i)) then
903 swp=i
904 i=j
905 j=swp
906 end if
907 END SUBROUTINE icomp_xchg
908
909 SUBROUTINE arth(first, increment, m, arth_i)
910 INTEGER, INTENT(IN) :: first,increment,m
911 INTEGER, DIMENSION(m) :: arth_i
912 INTEGER :: k,k2,temp
913
914 if (m > 0) arth_i(1)=first
915 if (m <= npar_arth) then
916 do k=2,m
917 arth_i(k)=arth_i(k-1)+increment
918 end do
919 else
920 do k=2,npar2_arth
921 arth_i(k)=arth_i(k-1)+increment
922 end do
923 temp=increment*npar2_arth
924 k=npar2_arth
925 do
926 if (k >= m) exit
927 k2=k+k
928 arth_i(k+1:min(k2,m))=temp+arth_i(1:min(k,m-k))
929 temp=temp+temp
930 k=k2
931 end do
932 end if
933 END SUBROUTINE
934
935 SUBROUTINE swap(a,b)
936 INTEGER, INTENT(INOUT) :: a,b
937 INTEGER :: dum
938 dum=a
939 a=b
940 b=dum
941 END SUBROUTINE swap
942
943END SUBROUTINE indexx_dp
944!********************************************************************
#define min(a, b)
Definition global.h:75
void show_error(char *error, int val, GtkWidget *win)
show error message
Definition interface.c:293
double precision, dimension(:,:,:), allocatable fullpos
integer ncells
double precision, dimension(:,:,:), allocatable nfullpos
double precision, dimension(:,:), allocatable pob
double precision, dimension(:,:), allocatable poa
integer err
double precision, dimension(3) rij
type(lattice), dimension(:), allocatable, target the_box
double precision dij
logical alc
logical pbc
double precision, parameter pi
real(kind=c_double) function random3(seed)
Definition utils.F90:480
subroutine moyenne(tableau, longtm, moytab)
Definition utils.F90:526
subroutine somme(tabs, longts, somtab)
Definition utils.F90:502
subroutine sort3(arr, ndum)
Definition utils.F90:681
subroutine do_ring(the_ring, elem_do)
Definition utils.F90:77
subroutine sort3_dp(arr, ndum)
Definition utils.F90:817
double precision function sacos(ang)
Definition utils.F90:261
logical function smooth(tabtoliss, gtoliss, dimtoliss, sigmaliss)
Definition utils.F90:612
subroutine creat_ring(ring_init, elem_cr)
Definition utils.F90:61
subroutine ect_type(moyenne, tableau, longte, ec_type)
Definition utils.F90:552
subroutine ect_type_rings(moyenne, tableau, longte, lrepres, ec_type)
Definition utils.F90:394
subroutine tri(tab, dimtab)
Definition utils.F90:581
subroutine indexx_i(arr, index, n)
Definition utils.F90:694
subroutine charint(word, num)
Definition utils.F90:32
double precision function calcdij(r12, at1, at2, step_1, step_2, sid)
Definition utils.F90:185
double precision function angijk(atg1, atg2, atg3, astep)
Definition utils.F90:285
subroutine calcrij(at1, at2, step_1, step_2, sid)
Definition utils.F90:115
double precision function ran3(idnum)
Definition utils.F90:421
double precision function diedre(dg1, dg2, dg3, dg4, dstep)
Definition utils.F90:331
subroutine indexx_dp(arr, index, n)
Definition utils.F90:830