atomes 1.1.14
atomes: an atomic scale modeling tool box
Loading...
Searching...
No Matches
molecules.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
21LOGICAL FUNCTION add_mol(this_mol, MOL_ID, STEP_ID)
22
23USE parameters
24
25IMPLICIT NONE
26
27TYPE (mol), POINTER, INTENT(INOUT) :: this_mol
28INTEGER, INTENT(IN) :: mol_id, step_id
29INTEGER :: aaa
30
31TYPE (mol), POINTER :: new
32
33allocate(new, stat=err)
34if (err .ne. 0) then
35 !call show_error ("Impossible to allocate memory"//CHAR(0), &
36 ! "Function: ADD_MOL"//CHAR(0), "Pointer: NEW"//CHAR(0))
37 add_mol = .false.
38 goto 001
39endif
40new%MID = mol_id
41new%STEP = step_id
42new%ATOMES = 0
43allocate(new%BSP(nsp), stat=err)
44if (err .ne. 0) then
45 !call show_error ("Impossible to allocate memory"//CHAR(0), &
46 ! "Function: ADD_MOL"//CHAR(0), "TABLE: NEW%BSP"//CHAR(0))
47 add_mol = .false.
48 goto 001
49endif
50nullify(new%FIRST_AT)
51do aaa=1, nsp
52 new%BSP(aaa) = 0
53enddo
54nullify(new%NEXT)
55new%PREV => this_mol
56this_mol%NEXT => new
57this_mol => new
58add_mol = .true.
59
60001 continue
61
62END FUNCTION
63
64LOGICAL FUNCTION add_ato(this_mol, ATOM_ID)
65
66USE parameters
67
68IMPLICIT NONE
69
70TYPE (mol), POINTER, INTENT(INOUT) :: this_mol
71INTEGER, INTENT(IN) :: atom_id
72
73TYPE (at), POINTER :: new
74
75allocate(new, stat=err)
76if (err .ne. 0) then
77 !call show_error ("Impossible to allocate memory"//CHAR(0), &
78 ! "Function: ADD_ATO"//CHAR(0), "POINTER: NEW"//CHAR(0))
79 add_ato = .false.
80 goto 001
81endif
82new%IND = atom_id
83new%PREV => this_mol%ATOM
84this_mol%ATOM%NEXT => new
85this_mol%ATOM => new
86add_ato=.true.
87
88001 continue
89
90END FUNCTION
91
92RECURSIVE SUBROUTINE setmol (this_mol, toglin, stmb, molcount, the_step, the_atom, the_id)
93
94USE parameters
95
96IMPLICIT NONE
97
98TYPE (mol), POINTER, INTENT(INOUT) :: this_mol
99INTEGER, INTENT(INOUT) :: molcount, stmb
100INTEGER, INTENT(IN) :: the_step, the_atom, the_id
101INTEGER, DIMENSION(NA), INTENT(INOUT) :: toglin
102INTEGER :: mc, md
103INTERFACE
104 LOGICAL FUNCTION add_ato(this_mol, ATOM_ID)
105 USE parameters
106 TYPE (mol), POINTER, INTENT(INOUT) :: this_mol
107 INTEGER, INTENT(IN) :: atom_id
108 END FUNCTION
109END INTERFACE
110
111molcount=molcount+1
112toglin(the_atom) = the_id
113this_mol%ATOMES = this_mol%ATOMES + 1
114this_mol%BSP(lot(the_atom)) = this_mol%BSP(lot(the_atom)) + 1
115stmb = stmb + 1
116if (this_mol%ATOMES > 1) then
117 if (.not. add_ato(this_mol, the_atom)) then
118 molcount=-1
119 goto 001
120 endif
121else
122 allocate(this_mol%FIRST_AT, stat=err)
123 if (err .ne. 0) then
124 !call show_error ("Impossible to allocate memory"//CHAR(0), &
125 ! "Function: SETMOL"//CHAR(0), "POINTER: this_mol%FIRST_AT"//CHAR(0))
126 molcount=-1
127 goto 001
128 endif
129 !write (6, '("Adding first atom:: Mol= ",i4,", At= ",i4)') this_mol%MID, the_atom
130 this_mol%FIRST_AT%IND = the_atom
131 this_mol%ATOM => this_mol%FIRST_AT
132endif
133if (stmb .eq. na) goto 002
134if (molcount.eq.10000) goto 001
135if (molcount.eq.-1) goto 001
136do mc=1, contj(the_atom, the_step)
137 md = voisj(mc,the_atom,the_step)
138 if (toglin(md).eq.0 .and. molcount.lt.10000) then
139 call setmol (this_mol, toglin, stmb, molcount, the_step, voisj(mc,the_atom,the_step), the_id)
140 endif
141 if (stmb .eq. na) goto 002
142 if (molcount.eq.10000) goto 001
143 if (molcount.eq.-1) goto 001
144enddo
145
146002 continue
147
148molcount=molcount-1
149
150001 continue
151
152END SUBROUTINE setmol
153
154INTEGER (KIND=c_int) FUNCTION molecules (frag_and_mol, allbonds) bind (C,NAME='molecules_')
155
156USE parameters
157
158#ifdef OPENMP
159!$ USE OMP_LIB
160#endif
161IMPLICIT NONE
162
163INTEGER (KIND=c_int), INTENT(IN) :: frag_and_mol, allbonds
164INTEGER :: totmol, molps, maxmol
165INTEGER, DIMENSION(:), ALLOCATABLE :: atmol
166INTEGER, DIMENSION(:), ALLOCATABLE :: atvs, mtmbs
167#ifdef OPENMP
168INTEGER :: numth
169#endif
170INTERFACE
171 LOGICAL FUNCTION add_mol(this_mol, MOL_ID, STEP_ID)
172 USE parameters
173 TYPE (mol), POINTER, INTENT(INOUT) :: this_mol
174 INTEGER, INTENT(IN) :: mol_id, step_id
175 END FUNCTION
176 RECURSIVE SUBROUTINE setmol (this_mol, toglin, stmb, molcount, the_step, the_atom, the_id)
177 USE parameters
178 TYPE (mol), POINTER, INTENT(INOUT) :: this_mol
179 INTEGER, INTENT(INOUT) :: molcount, stmb
180 INTEGER, INTENT(IN) :: the_step, the_atom, the_id
181 INTEGER, DIMENSION(NA), INTENT(INOUT) :: toglin
182 END SUBROUTINE
183END INTERFACE
184
185TYPE (at), POINTER :: tmpat
186TYPE (mol), ALLOCATABLE, TARGET :: themol
187TYPE (mol), POINTER :: tmpmol
188
189if (allocated(fullpos)) deallocate(fullpos)
190
191k = 0
192do i=1, ns
193 do j=1, na
194 if (contj(j,i) .eq. 0) k = k + 1
195 enddo
196enddo
197maxmol = k + allbonds/2;
198
199if (allocated(themol)) deallocate(themol)
200allocate(themol, stat=err)
201if (err .ne. 0) then
202 alc_tab="THEMOL"
203 alc=.true.
204 molecules = 0
205 goto 001
206endif
207if (allocated(mtmbs)) deallocate(mtmbs)
208allocate(mtmbs(ns), stat=err)
209if (err .ne. 0) then
210 alc_tab="MTMBS"
211 alc=.true.
212 molecules = 0
213 goto 001
214endif
215
216if (frag_and_mol .eq. 1) then
217 call allocate_mol_data ()
218endif
219
220molecules = 1
221#ifdef OPENMP
222numth = omp_get_max_threads()
223if (ns.lt.numth) numth=ns
224!$OMP PARALLEL NUM_THREADS(NUMTH) DEFAULT (NONE) &
225!$OMP& PRIVATE(i, j, k, l, m, n, o, ERR, TOGL, THEMOL, TMPMOL, &
226!$OMP& TOTMOL, MOLCOUNTER, TMBS, ATMOL, TMPAT, ATVS) &
227!$OMP& SHARED(NUMTH, frag_and_mol, NS, NA, NSP, LOT, MTMBS, CONTJ, VOISJ, ALC, ALC_TAB)
228#endif
229if (allocated(togl)) deallocate(togl)
230allocate(togl(na), stat=err)
231if (err .ne. 0) then
232 alc_tab="TOGL"
233 alc=.true.
234 molecules = 0
235#ifdef OPENMP
236 goto 005
237#else
238 goto 001
239#endif
240endif
241nullify(tmpat)
242#ifdef OPENMP
243 !$OMP DO SCHEDULE(STATIC,NS/NUMTH)
244#endif
245do i=1, ns
246
247#ifdef OPENMP
248 if (molecules .eq.0) goto 004
249#endif
250 togl(:)=0
251 themol%MID = 1
252 themol%STEP = i
253 themol%ATOMES = 0
254 nullify(themol%FIRST_AT)
255 allocate(themol%BSP(nsp), stat=err)
256 if (err .ne. 0) then
257 alc_tab="THEMOL%BSP"
258 alc=.true.
259 molecules = 0
260#ifdef OPENMP
261 goto 004
262#else
263 goto 001
264#endif
265 endif
266 do j=1, nsp
267 themol%BSP(j) = 0
268 enddo
269 nullify(themol%NEXT)
270 nullify(themol%PREV)
271 tmbs=0
272 totmol = 0
273 mtmbs(i)=0
274 molcounter=0
275 tmpmol => themol
276 n = 1
277 002 continue
278 do j=n, na
279 if (molcounter.eq.0 .and. togl(j).eq.0) then
280 totmol = totmol + 1
281 if (totmol > 1) then
282 if (.not.add_mol(tmpmol, mtmbs(i)+1, i)) then
283 alc_tab="ADD_MOL"
284 alc=.true.
285 molecules = 0
286#ifdef OPENMP
287 goto 004
288#else
289 goto 001
290#endif
291 endif
292 endif
293 mtmbs(i) = mtmbs(i) + 1
294 call setmol (tmpmol, togl, tmbs, molcounter, i, j, totmol)
295 if (molcounter .lt. 0) then
296 alc_tab="SETMOL"
297 alc=.true.
298#ifdef OPENMP
299 goto 004
300#else
301 goto 001
302#endif
303 endif
304 if (tmbs.eq.na) goto 003
305 ! The 10000 iterations break required because of F90 limitations
306 if (molcounter.eq.10000) goto 002
307 molcounter = 0
308 n = j
309 goto 002
310 else if (molcounter.gt.0 .and.togl(j).eq.totmol) then
311 do l=1, contj(j,i)
312 m = voisj(l,j,i)
313 if (togl(m).eq.0) then
314 molcounter = 0
315 call setmol (tmpmol, togl, tmbs, molcounter, i, voisj(l,j,i), totmol)
316 if (molcounter .lt. 0) then
317 alc_tab="SETMOL"
318 alc=.true.
319#ifdef OPENMP
320 goto 004
321#else
322 goto 001
323#endif
324 endif
325 if (tmbs.eq.na) goto 003
326 if (molcounter.eq.10000) goto 002
327 molcounter = 1
328 endif
329 enddo
330 endif
331 enddo
332
333 if (tmbs .lt. na) then
334 molcounter = 0
335 goto 002
336 endif
337
338 003 continue
339
340 if (frag_and_mol .eq. 1) then
341
342 tmpmol => themol
343 call allocate_mol_for_step (i, mtmbs(i))
344 do j=1, mtmbs(i)
345 if (allocated(atmol)) deallocate(atmol)
346 allocate(atmol(tmpmol%ATOMES), stat=err)
347 if (err .ne. 0) then
348 alc_tab="ATMOL"
349 alc=.true.
350 molecules = 0
351#ifdef OPENMP
352 goto 004
353#else
354 goto 001
355#endif
356 endif
357 if (associated(tmpat)) deallocate (tmpat)
358 allocate(tmpat, stat=err)
359 if (err .ne. 0) then
360 alc_tab="TMPAT"
361 alc=.true.
362 molecules = 0
363#ifdef OPENMP
364 goto 004
365#else
366 goto 001
367#endif
368 endif
369 tmpat = tmpmol%FIRST_AT
370 do k=1, tmpmol%ATOMES
371 atmol(k) = tmpat%IND
372 if (k < tmpmol%ATOMES) then
373 tmpat => tmpat%NEXT
374 deallocate (tmpat%PREV)
375 else
376 deallocate (tmpat)
377 endif
378 enddo
379
380 call send_mol_details (tmpmol%STEP, tmpmol%MID, tmpmol%ATOMES, nsp, tmpmol%BSP, atmol)
381 if (tmpmol%ATOMES .gt. 1) then
382 do l=1, tmpmol%ATOMES
383 m = atmol(l)
384 n = contj(m,tmpmol%STEP)
385 if (allocated(atvs)) deallocate(atvs)
386 allocate(atvs(n), stat=err)
387 if (err .ne. 0) then
388 alc_tab="ATVS"
389 alc=.true.
390 molecules = 0
391#ifdef OPENMP
392 goto 004
393#else
394 goto 001
395#endif
396 endif
397 do o=1, n
398 atvs(o)= voisj(o,m,tmpmol%STEP)
399 enddo
400 call send_mol_neighbors (tmpmol%STEP, tmpmol%MID, m, n, atvs)
401 enddo
402 endif
403 if (allocated(atvs)) deallocate(atvs)
404 if (allocated(atmol)) deallocate(atmol)
405 if (allocated(tmpmol%BSP)) deallocate (tmpmol%BSP)
406
407 if (j .lt. mtmbs(i)) tmpmol => tmpmol%NEXT
408
409 enddo
410 call setup_molecules (i)
411 endif
412 call setup_fragments (i, togl)
413 do while (tmpmol%MID .gt. 1)
414 tmpmol => tmpmol%PREV
415 deallocate (tmpmol%NEXT)
416 enddo
417#ifdef OPENMP
418 004 continue
419#endif
420enddo
421#ifdef OPENMP
422!$OMP END DO NOWAIT
423005 continue
424if (allocated(togl)) deallocate (togl)
425if (allocated(themol)) deallocate(themol)
426if (allocated(atmol)) deallocate(atmol)
427if (allocated(atvs)) deallocate(atvs)
428!$OMP END PARALLEL
429#else
430if (allocated(togl)) deallocate (togl)
431if (allocated(themol)) deallocate(themol)
432if (allocated(atvs)) deallocate(atvs)
433if (allocated(atmol)) deallocate(atmol)
434#endif
435
436molps = 0
437j = 0
438do i=1, ns
439 molps = molps + mtmbs(i)
440 j = max(mtmbs(i), j)
441enddo
442call send_coord_opengl (2, 1, 0, 0, j, 1)
443call init_menu_fragmol (2)
444
445if (frag_and_mol .eq. 1) then
446 call setup_menu_molecules ()
447endif
448
449molecules=1
450
451001 continue
452
453if (alc) then
454 call show_error ("Impossible to allocate memory !"//char(0), &
455 "Function: molecules"//char(0), char(9)//"Table: "//alc_tab(1:len_trim(alc_tab))//char(0))
456endif
457
458if (allocated(mtmbs)) deallocate(mtmbs)
459
460END FUNCTION molecules
#define max(a, b)
Definition global.h:74
void setup_molecules()
void show_error(char *error, int val, GtkWidget *win)
show error message
Definition interface.c:293
recursive subroutine setmol(this_mol, toglin, stmb, molcount, the_step, the_atom, the_id)
Definition molecules.F90:93
logical function add_ato(this_mol, atom_id)
Definition molecules.F90:65
integer(kind=c_int) function molecules(frag_and_mol, allbonds)
logical function add_mol(this_mol, mol_id, step_id)
Definition molecules.F90:22
integer err
integer nsp