ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/UseTheForce/DarkSide/simulation.F90
Revision: 2592
Committed: Thu Feb 16 21:40:20 2006 UTC (18 years, 6 months ago) by gezelter
File size: 23196 byte(s)
Log Message:
fixed a problem with cutoff radii being set larger than 1/2 the
length of the shortest box dimension.  added a few fortran utility
routines

File Contents

# User Rev Content
1 gezelter 1930 !!
2     !! Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3     !!
4     !! The University of Notre Dame grants you ("Licensee") a
5     !! non-exclusive, royalty free, license to use, modify and
6     !! redistribute this software in source and binary code form, provided
7     !! that the following conditions are met:
8     !!
9     !! 1. Acknowledgement of the program authors must be made in any
10     !! publication of scientific results based in part on use of the
11     !! program. An acceptable form of acknowledgement is citation of
12     !! the article in which the program was described (Matthew
13     !! A. Meineke, Charles F. Vardeman II, Teng Lin, Christopher
14     !! J. Fennell and J. Daniel Gezelter, "OOPSE: An Object-Oriented
15     !! Parallel Simulation Engine for Molecular Dynamics,"
16     !! J. Comput. Chem. 26, pp. 252-271 (2005))
17     !!
18     !! 2. Redistributions of source code must retain the above copyright
19     !! notice, this list of conditions and the following disclaimer.
20     !!
21     !! 3. Redistributions in binary form must reproduce the above copyright
22     !! notice, this list of conditions and the following disclaimer in the
23     !! documentation and/or other materials provided with the
24     !! distribution.
25     !!
26     !! This software is provided "AS IS," without a warranty of any
27     !! kind. All express or implied conditions, representations and
28     !! warranties, including any implied warranty of merchantability,
29     !! fitness for a particular purpose or non-infringement, are hereby
30     !! excluded. The University of Notre Dame and its licensors shall not
31     !! be liable for any damages suffered by licensee as a result of
32     !! using, modifying or distributing the software or its
33     !! derivatives. In no event will the University of Notre Dame or its
34     !! licensors be liable for any lost revenue, profit or data, or for
35     !! direct, indirect, special, consequential, incidental or punitive
36     !! damages, however caused and regardless of the theory of liability,
37     !! arising out of the use of or inability to use software, even if the
38     !! University of Notre Dame has been advised of the possibility of
39     !! such damages.
40     !!
41    
42 gezelter 1608 !! Fortran interface to C entry plug.
43    
44     module simulation
45     use definitions
46 gezelter 2592 use status
47     use linearAlgebra
48 gezelter 1608 use neighborLists
49     use force_globals
50     use vector_class
51     use atype_module
52     use switcheroo
53     #ifdef IS_MPI
54     use mpiSimulation
55     #endif
56    
57     implicit none
58     PRIVATE
59    
60     #define __FORTRAN90
61     #include "brains/fSimulation.h"
62     #include "UseTheForce/fSwitchingFunction.h"
63 chrisfen 2310 #include "UseTheForce/DarkSide/fElectrostaticSummationMethod.h"
64 gezelter 1608
65     type (simtype), public, save :: thisSim
66    
67     logical, save :: simulation_setup_complete = .false.
68    
69     integer, public, save :: nLocal, nGlobal
70     integer, public, save :: nGroups, nGroupGlobal
71     integer, public, save :: nExcludes_Global = 0
72     integer, public, save :: nExcludes_Local = 0
73     integer, allocatable, dimension(:,:), public :: excludesLocal
74     integer, allocatable, dimension(:), public :: excludesGlobal
75     integer, allocatable, dimension(:), public :: molMembershipList
76     integer, allocatable, dimension(:), public :: groupListRow
77     integer, allocatable, dimension(:), public :: groupStartRow
78     integer, allocatable, dimension(:), public :: groupListCol
79     integer, allocatable, dimension(:), public :: groupStartCol
80     integer, allocatable, dimension(:), public :: groupListLocal
81     integer, allocatable, dimension(:), public :: groupStartLocal
82     integer, allocatable, dimension(:), public :: nSkipsForAtom
83     integer, allocatable, dimension(:,:), public :: skipsForAtom
84     real(kind=dp), allocatable, dimension(:), public :: mfactRow
85     real(kind=dp), allocatable, dimension(:), public :: mfactCol
86     real(kind=dp), allocatable, dimension(:), public :: mfactLocal
87    
88 chuckv 2262 logical, allocatable, dimension(:) :: simHasAtypeMap
89 chuckv 2329 #ifdef IS_MPI
90     logical, allocatable, dimension(:) :: simHasAtypeMapTemp
91     #endif
92    
93 gezelter 1608 real(kind=dp), public, dimension(3,3), save :: Hmat, HmatInv
94 gezelter 2592 real(kind=dp), save :: DangerRcut
95 gezelter 1608 logical, public, save :: boxIsOrthorhombic
96 gezelter 2204
97 gezelter 1608 public :: SimulationSetup
98     public :: getNlocal
99     public :: setBox
100 gezelter 2592 public :: checkBox
101 gezelter 1608 public :: getDielect
102     public :: SimUsesPBC
103 gezelter 1633
104     public :: SimUsesDirectionalAtoms
105     public :: SimUsesLennardJones
106     public :: SimUsesElectrostatics
107 gezelter 1608 public :: SimUsesCharges
108     public :: SimUsesDipoles
109     public :: SimUsesSticky
110 chrisfen 2220 public :: SimUsesStickyPower
111 gezelter 1633 public :: SimUsesGayBerne
112     public :: SimUsesEAM
113     public :: SimUsesShapes
114     public :: SimUsesFLARB
115 gezelter 1608 public :: SimUsesRF
116 chrisfen 2418 public :: SimUsesSF
117 gezelter 1608 public :: SimRequiresPrepairCalc
118     public :: SimRequiresPostpairCalc
119 chuckv 2262 public :: SimHasAtype
120 chuckv 2432 public :: SimUsesSC
121     public :: SimUsesMEAM
122 gezelter 2592 public :: setHmatDangerousRcutValue
123 gezelter 1633
124 gezelter 1608 contains
125 gezelter 2204
126 gezelter 1608 subroutine SimulationSetup(setThisSim, CnGlobal, CnLocal, c_idents, &
127     CnLocalExcludes, CexcludesLocal, CnGlobalExcludes, CexcludesGlobal, &
128     CmolMembership, Cmfact, CnGroups, CglobalGroupMembership, &
129     status)
130    
131     type (simtype) :: setThisSim
132     integer, intent(inout) :: CnGlobal, CnLocal
133     integer, dimension(CnLocal),intent(inout) :: c_idents
134    
135     integer :: CnLocalExcludes
136     integer, dimension(2,CnLocalExcludes), intent(in) :: CexcludesLocal
137     integer :: CnGlobalExcludes
138     integer, dimension(CnGlobalExcludes), intent(in) :: CexcludesGlobal
139     integer, dimension(CnGlobal),intent(in) :: CmolMembership
140     !! Result status, success = 0, status = -1
141     integer, intent(out) :: status
142     integer :: i, j, me, thisStat, alloc_stat, myNode, id1, id2
143     integer :: ia
144    
145     !! mass factors used for molecular cutoffs
146     real ( kind = dp ), dimension(CnLocal) :: Cmfact
147     integer, intent(in):: CnGroups
148     integer, dimension(CnGlobal), intent(in):: CglobalGroupMembership
149     integer :: maxSkipsForAtom, glPointer
150    
151     #ifdef IS_MPI
152     integer, allocatable, dimension(:) :: c_idents_Row
153     integer, allocatable, dimension(:) :: c_idents_Col
154     integer :: nAtomsInRow, nGroupsInRow, aid
155     integer :: nAtomsInCol, nGroupsInCol, gid
156     #endif
157    
158     simulation_setup_complete = .false.
159     status = 0
160    
161     ! copy C struct into fortran type
162    
163     nLocal = CnLocal
164     nGlobal = CnGlobal
165     nGroups = CnGroups
166    
167     thisSim = setThisSim
168    
169     nExcludes_Global = CnGlobalExcludes
170     nExcludes_Local = CnLocalExcludes
171    
172     call InitializeForceGlobals(nLocal, thisStat)
173     if (thisStat /= 0) then
174     write(default_error,*) "SimSetup: InitializeForceGlobals error"
175     status = -1
176     return
177     endif
178    
179     call InitializeSimGlobals(thisStat)
180     if (thisStat /= 0) then
181     write(default_error,*) "SimSetup: InitializeSimGlobals error"
182     status = -1
183     return
184     endif
185    
186     #ifdef IS_MPI
187     ! We can only set up forces if mpiSimulation has been setup.
188     if (.not. isMPISimSet()) then
189     write(default_error,*) "MPI is not set"
190     status = -1
191     return
192     endif
193     nAtomsInRow = getNatomsInRow(plan_atom_row)
194     nAtomsInCol = getNatomsInCol(plan_atom_col)
195     nGroupsInRow = getNgroupsInRow(plan_group_row)
196     nGroupsInCol = getNgroupsInCol(plan_group_col)
197     mynode = getMyNode()
198 gezelter 2204
199 gezelter 1608 allocate(c_idents_Row(nAtomsInRow),stat=alloc_stat)
200     if (alloc_stat /= 0 ) then
201     status = -1
202     return
203     endif
204    
205     allocate(c_idents_Col(nAtomsInCol),stat=alloc_stat)
206     if (alloc_stat /= 0 ) then
207     status = -1
208     return
209     endif
210    
211     call gather(c_idents, c_idents_Row, plan_atom_row)
212     call gather(c_idents, c_idents_Col, plan_atom_col)
213    
214     do i = 1, nAtomsInRow
215     me = getFirstMatchingElement(atypes, "c_ident", c_idents_Row(i))
216     atid_Row(i) = me
217     enddo
218    
219     do i = 1, nAtomsInCol
220     me = getFirstMatchingElement(atypes, "c_ident", c_idents_Col(i))
221     atid_Col(i) = me
222     enddo
223    
224     !! free temporary ident arrays
225     if (allocated(c_idents_Col)) then
226     deallocate(c_idents_Col)
227     end if
228     if (allocated(c_idents_Row)) then
229     deallocate(c_idents_Row)
230     endif
231 gezelter 2204
232 gezelter 1608 #endif
233    
234     #ifdef IS_MPI
235     allocate(groupStartRow(nGroupsInRow+1),stat=alloc_stat)
236     if (alloc_stat /= 0 ) then
237     status = -1
238     return
239     endif
240     allocate(groupStartCol(nGroupsInCol+1),stat=alloc_stat)
241     if (alloc_stat /= 0 ) then
242     status = -1
243     return
244     endif
245     allocate(groupListRow(nAtomsInRow),stat=alloc_stat)
246     if (alloc_stat /= 0 ) then
247     status = -1
248     return
249     endif
250     allocate(groupListCol(nAtomsInCol),stat=alloc_stat)
251     if (alloc_stat /= 0 ) then
252     status = -1
253     return
254     endif
255     allocate(mfactRow(nAtomsInRow),stat=alloc_stat)
256     if (alloc_stat /= 0 ) then
257     status = -1
258     return
259     endif
260     allocate(mfactCol(nAtomsInCol),stat=alloc_stat)
261     if (alloc_stat /= 0 ) then
262     status = -1
263     return
264     endif
265     allocate(mfactLocal(nLocal),stat=alloc_stat)
266     if (alloc_stat /= 0 ) then
267     status = -1
268     return
269     endif
270 gezelter 2204
271 gezelter 1608 glPointer = 1
272    
273     do i = 1, nGroupsInRow
274    
275     gid = GroupRowToGlobal(i)
276     groupStartRow(i) = glPointer
277    
278     do j = 1, nAtomsInRow
279     aid = AtomRowToGlobal(j)
280     if (CglobalGroupMembership(aid) .eq. gid) then
281     groupListRow(glPointer) = j
282     glPointer = glPointer + 1
283     endif
284     enddo
285     enddo
286     groupStartRow(nGroupsInRow+1) = nAtomsInRow + 1
287    
288     glPointer = 1
289    
290     do i = 1, nGroupsInCol
291    
292     gid = GroupColToGlobal(i)
293     groupStartCol(i) = glPointer
294    
295     do j = 1, nAtomsInCol
296     aid = AtomColToGlobal(j)
297     if (CglobalGroupMembership(aid) .eq. gid) then
298     groupListCol(glPointer) = j
299     glPointer = glPointer + 1
300     endif
301     enddo
302     enddo
303     groupStartCol(nGroupsInCol+1) = nAtomsInCol + 1
304    
305     mfactLocal = Cmfact
306    
307     call gather(mfactLocal, mfactRow, plan_atom_row)
308     call gather(mfactLocal, mfactCol, plan_atom_col)
309 gezelter 2204
310 gezelter 1608 if (allocated(mfactLocal)) then
311     deallocate(mfactLocal)
312     end if
313     #else
314     allocate(groupStartRow(nGroups+1),stat=alloc_stat)
315     if (alloc_stat /= 0 ) then
316     status = -1
317     return
318     endif
319     allocate(groupStartCol(nGroups+1),stat=alloc_stat)
320     if (alloc_stat /= 0 ) then
321     status = -1
322     return
323     endif
324     allocate(groupListRow(nLocal),stat=alloc_stat)
325     if (alloc_stat /= 0 ) then
326     status = -1
327     return
328     endif
329     allocate(groupListCol(nLocal),stat=alloc_stat)
330     if (alloc_stat /= 0 ) then
331     status = -1
332     return
333     endif
334     allocate(mfactRow(nLocal),stat=alloc_stat)
335     if (alloc_stat /= 0 ) then
336     status = -1
337     return
338     endif
339     allocate(mfactCol(nLocal),stat=alloc_stat)
340     if (alloc_stat /= 0 ) then
341     status = -1
342     return
343     endif
344     allocate(mfactLocal(nLocal),stat=alloc_stat)
345     if (alloc_stat /= 0 ) then
346     status = -1
347     return
348     endif
349    
350     glPointer = 1
351     do i = 1, nGroups
352     groupStartRow(i) = glPointer
353     groupStartCol(i) = glPointer
354     do j = 1, nLocal
355     if (CglobalGroupMembership(j) .eq. i) then
356     groupListRow(glPointer) = j
357     groupListCol(glPointer) = j
358     glPointer = glPointer + 1
359     endif
360     enddo
361     enddo
362     groupStartRow(nGroups+1) = nLocal + 1
363     groupStartCol(nGroups+1) = nLocal + 1
364    
365     do i = 1, nLocal
366     mfactRow(i) = Cmfact(i)
367     mfactCol(i) = Cmfact(i)
368     end do
369 gezelter 2204
370 gezelter 1608 #endif
371    
372    
373 gezelter 2204 ! We build the local atid's for both mpi and nonmpi
374 gezelter 1608 do i = 1, nLocal
375 gezelter 2204
376 gezelter 1608 me = getFirstMatchingElement(atypes, "c_ident", c_idents(i))
377     atid(i) = me
378 gezelter 2204
379 gezelter 1608 enddo
380    
381     do i = 1, nExcludes_Local
382     excludesLocal(1,i) = CexcludesLocal(1,i)
383     excludesLocal(2,i) = CexcludesLocal(2,i)
384     enddo
385    
386     #ifdef IS_MPI
387     allocate(nSkipsForAtom(nAtomsInRow), stat=alloc_stat)
388     #else
389     allocate(nSkipsForAtom(nLocal), stat=alloc_stat)
390     #endif
391     if (alloc_stat /= 0 ) then
392     thisStat = -1
393     write(*,*) 'Could not allocate nSkipsForAtom array'
394     return
395     endif
396    
397     maxSkipsForAtom = 0
398     #ifdef IS_MPI
399     do j = 1, nAtomsInRow
400     #else
401 gezelter 2204 do j = 1, nLocal
402 gezelter 1608 #endif
403 gezelter 2204 nSkipsForAtom(j) = 0
404 gezelter 1608 #ifdef IS_MPI
405 gezelter 2204 id1 = AtomRowToGlobal(j)
406 gezelter 1608 #else
407 gezelter 2204 id1 = j
408 gezelter 1608 #endif
409 gezelter 2204 do i = 1, nExcludes_Local
410     if (excludesLocal(1,i) .eq. id1 ) then
411     nSkipsForAtom(j) = nSkipsForAtom(j) + 1
412 gezelter 1608
413 gezelter 2204 if (nSkipsForAtom(j) .gt. maxSkipsForAtom) then
414     maxSkipsForAtom = nSkipsForAtom(j)
415     endif
416 gezelter 1608 endif
417 gezelter 2204 if (excludesLocal(2,i) .eq. id1 ) then
418     nSkipsForAtom(j) = nSkipsForAtom(j) + 1
419 gezelter 1608
420 gezelter 2204 if (nSkipsForAtom(j) .gt. maxSkipsForAtom) then
421     maxSkipsForAtom = nSkipsForAtom(j)
422     endif
423 gezelter 1608 endif
424 gezelter 2204 end do
425     enddo
426 gezelter 1608
427     #ifdef IS_MPI
428 gezelter 2204 allocate(skipsForAtom(nAtomsInRow, maxSkipsForAtom), stat=alloc_stat)
429 gezelter 1608 #else
430 gezelter 2204 allocate(skipsForAtom(nLocal, maxSkipsForAtom), stat=alloc_stat)
431 gezelter 1608 #endif
432 gezelter 2204 if (alloc_stat /= 0 ) then
433     write(*,*) 'Could not allocate skipsForAtom array'
434     return
435     endif
436 gezelter 1608
437     #ifdef IS_MPI
438 gezelter 2204 do j = 1, nAtomsInRow
439 gezelter 1608 #else
440 gezelter 2204 do j = 1, nLocal
441 gezelter 1608 #endif
442 gezelter 2204 nSkipsForAtom(j) = 0
443 gezelter 1608 #ifdef IS_MPI
444 gezelter 2204 id1 = AtomRowToGlobal(j)
445 gezelter 1608 #else
446 gezelter 2204 id1 = j
447 gezelter 1608 #endif
448 gezelter 2204 do i = 1, nExcludes_Local
449     if (excludesLocal(1,i) .eq. id1 ) then
450     nSkipsForAtom(j) = nSkipsForAtom(j) + 1
451     ! exclude lists have global ID's so this line is
452     ! the same in MPI and non-MPI
453     id2 = excludesLocal(2,i)
454     skipsForAtom(j, nSkipsForAtom(j)) = id2
455     endif
456     if (excludesLocal(2, i) .eq. id1 ) then
457     nSkipsForAtom(j) = nSkipsForAtom(j) + 1
458     ! exclude lists have global ID's so this line is
459     ! the same in MPI and non-MPI
460     id2 = excludesLocal(1,i)
461     skipsForAtom(j, nSkipsForAtom(j)) = id2
462     endif
463     end do
464     enddo
465    
466     do i = 1, nExcludes_Global
467     excludesGlobal(i) = CexcludesGlobal(i)
468     enddo
469    
470     do i = 1, nGlobal
471     molMemberShipList(i) = CmolMembership(i)
472     enddo
473    
474 chuckv 2262 call createSimHasAtype(alloc_stat)
475     if (alloc_stat /= 0) then
476     status = -1
477     end if
478    
479     if (status == 0) simulation_setup_complete = .true.
480 gezelter 2204
481     end subroutine SimulationSetup
482    
483     subroutine setBox(cHmat, cHmatInv, cBoxIsOrthorhombic)
484     real(kind=dp), dimension(3,3) :: cHmat, cHmatInv
485     integer :: cBoxIsOrthorhombic
486 gezelter 2592 integer :: smallest, status
487 gezelter 2204
488     Hmat = cHmat
489     HmatInv = cHmatInv
490     if (cBoxIsOrthorhombic .eq. 0 ) then
491     boxIsOrthorhombic = .false.
492     else
493     boxIsOrthorhombic = .true.
494 gezelter 1608 endif
495    
496 gezelter 2592 call checkBox()
497     return
498 gezelter 2204 end subroutine setBox
499 gezelter 1608
500 gezelter 2592 subroutine checkBox()
501    
502     integer :: i
503     real(kind=dp), dimension(3) :: hx, hy, hz, ax, ay, az, piped
504     character(len = statusMsgSize) :: errMsg
505    
506     hx = Hmat(1,:)
507     hy = Hmat(2,:)
508     hz = Hmat(3,:)
509    
510     ax = cross_product(hy, hz)
511     ay = cross_product(hx, hz)
512     az = cross_product(hx, hy)
513    
514     ax = ax / length(ax)
515     ay = ay / length(ay)
516     az = az / length(az)
517    
518     piped(1) = abs(dot_product(ax, hx))
519     piped(2) = abs(dot_product(ay, hy))
520     piped(3) = abs(dot_product(az, hz))
521    
522     do i = 1, 3
523     if ((0.5_dp * piped(i)).lt.DangerRcut) then
524     write(errMsg, '(a94,f9.4,a1)') 'One of the dimensions of the Periodic ' &
525     // 'Box is smaller than ' // newline // tab // &
526     'the largest cutoff radius' // &
527     ' (rCut = ', DangerRcut, ')'
528     call handleError("checkBox", errMsg)
529     end if
530     enddo
531     return
532     end subroutine checkBox
533    
534 gezelter 2204 function getDielect() result(dielect)
535     real( kind = dp ) :: dielect
536     dielect = thisSim%dielect
537     end function getDielect
538 gezelter 1608
539 gezelter 2204 function SimUsesPBC() result(doesit)
540     logical :: doesit
541     doesit = thisSim%SIM_uses_PBC
542     end function SimUsesPBC
543 gezelter 1608
544 gezelter 2204 function SimUsesDirectionalAtoms() result(doesit)
545     logical :: doesit
546 chrisfen 2220 doesit = thisSim%SIM_uses_dipoles .or. thisSim%SIM_uses_Sticky .or. &
547     thisSim%SIM_uses_StickyPower .or. &
548 gezelter 2204 thisSim%SIM_uses_GayBerne .or. thisSim%SIM_uses_Shapes
549     end function SimUsesDirectionalAtoms
550 gezelter 1608
551 gezelter 2204 function SimUsesLennardJones() result(doesit)
552     logical :: doesit
553     doesit = thisSim%SIM_uses_LennardJones
554     end function SimUsesLennardJones
555 gezelter 1633
556 gezelter 2204 function SimUsesElectrostatics() result(doesit)
557     logical :: doesit
558     doesit = thisSim%SIM_uses_Electrostatics
559     end function SimUsesElectrostatics
560 gezelter 1608
561 gezelter 2204 function SimUsesCharges() result(doesit)
562     logical :: doesit
563     doesit = thisSim%SIM_uses_Charges
564     end function SimUsesCharges
565 gezelter 1608
566 gezelter 2204 function SimUsesDipoles() result(doesit)
567     logical :: doesit
568     doesit = thisSim%SIM_uses_Dipoles
569     end function SimUsesDipoles
570 gezelter 1608
571 gezelter 2204 function SimUsesSticky() result(doesit)
572     logical :: doesit
573     doesit = thisSim%SIM_uses_Sticky
574     end function SimUsesSticky
575 gezelter 1608
576 chrisfen 2220 function SimUsesStickyPower() result(doesit)
577     logical :: doesit
578     doesit = thisSim%SIM_uses_StickyPower
579     end function SimUsesStickyPower
580    
581 gezelter 2204 function SimUsesGayBerne() result(doesit)
582     logical :: doesit
583     doesit = thisSim%SIM_uses_GayBerne
584     end function SimUsesGayBerne
585 gezelter 1608
586 gezelter 2204 function SimUsesEAM() result(doesit)
587     logical :: doesit
588     doesit = thisSim%SIM_uses_EAM
589     end function SimUsesEAM
590 gezelter 1633
591 chuckv 2432
592     function SimUsesSC() result(doesit)
593     logical :: doesit
594     doesit = thisSim%SIM_uses_SC
595     end function SimUsesSC
596    
597     function SimUsesMEAM() result(doesit)
598     logical :: doesit
599     doesit = thisSim%SIM_uses_MEAM
600     end function SimUsesMEAM
601    
602    
603 gezelter 2204 function SimUsesShapes() result(doesit)
604     logical :: doesit
605     doesit = thisSim%SIM_uses_Shapes
606     end function SimUsesShapes
607 gezelter 1633
608 gezelter 2204 function SimUsesFLARB() result(doesit)
609     logical :: doesit
610     doesit = thisSim%SIM_uses_FLARB
611     end function SimUsesFLARB
612 gezelter 1608
613 gezelter 2204 function SimUsesRF() result(doesit)
614     logical :: doesit
615     doesit = thisSim%SIM_uses_RF
616     end function SimUsesRF
617 gezelter 1608
618 chrisfen 2418 function SimUsesSF() result(doesit)
619 chrisfen 2402 logical :: doesit
620 chrisfen 2418 doesit = thisSim%SIM_uses_SF
621     end function SimUsesSF
622 chrisfen 2402
623 gezelter 2204 function SimRequiresPrepairCalc() result(doesit)
624     logical :: doesit
625 chuckv 2432 doesit = thisSim%SIM_uses_EAM .or. thisSim%SIM_uses_SC &
626     .or. thisSim%SIM_uses_MEAM
627 gezelter 2204 end function SimRequiresPrepairCalc
628 chrisfen 2390
629 gezelter 2204 function SimRequiresPostpairCalc() result(doesit)
630     logical :: doesit
631 chrisfen 2418 doesit = thisSim%SIM_uses_RF .or. thisSim%SIM_uses_SF
632 gezelter 2204 end function SimRequiresPostpairCalc
633    
634 gezelter 2274 ! Function returns true if the simulation has this atype
635 chuckv 2262 function SimHasAtype(thisAtype) result(doesit)
636     logical :: doesit
637     integer :: thisAtype
638     doesit = .false.
639     if(.not.allocated(SimHasAtypeMap)) return
640    
641     doesit = SimHasAtypeMap(thisAtype)
642    
643     end function SimHasAtype
644    
645     subroutine createSimHasAtype(status)
646     integer, intent(out) :: status
647     integer :: alloc_stat
648     integer :: me_i
649     integer :: mpiErrors
650     integer :: nAtypes
651     status = 0
652    
653     nAtypes = getSize(atypes)
654     ! Setup logical map for atypes in simulation
655     if (.not.allocated(SimHasAtypeMap)) then
656     allocate(SimHasAtypeMap(nAtypes),stat=alloc_stat)
657     if (alloc_stat /= 0 ) then
658     status = -1
659     return
660     end if
661     SimHasAtypeMap = .false.
662     end if
663 chuckv 2329
664 gezelter 2274 ! Loop through the local atoms and grab the atypes present
665 chuckv 2262 do me_i = 1,nLocal
666     SimHasAtypeMap(atid(me_i)) = .true.
667     end do
668 gezelter 2274 ! For MPI, we need to know all possible atypes present in
669     ! simulation on all processors. Use LOR operation to set map.
670 chuckv 2262 #ifdef IS_MPI
671 chuckv 2329 if (.not.allocated(SimHasAtypeMapTemp)) then
672     allocate(SimHasAtypeMapTemp(nAtypes),stat=alloc_stat)
673     if (alloc_stat /= 0 ) then
674     status = -1
675     return
676     end if
677     end if
678     call mpi_allreduce(SimHasAtypeMap, SimHasAtypeMaptemp, nAtypes, &
679 gezelter 2274 mpi_logical, MPI_LOR, mpi_comm_world, mpiErrors)
680 chuckv 2329 simHasAtypeMap = simHasAtypeMapTemp
681     deallocate(simHasAtypeMapTemp)
682 gezelter 2274 #endif
683 chuckv 2262 end subroutine createSimHasAtype
684 gezelter 2274
685 chuckv 2262 subroutine InitializeSimGlobals(thisStat)
686 gezelter 2204 integer, intent(out) :: thisStat
687     integer :: alloc_stat
688    
689     thisStat = 0
690    
691     call FreeSimGlobals()
692    
693     allocate(excludesLocal(2,nExcludes_Local), stat=alloc_stat)
694     if (alloc_stat /= 0 ) then
695     thisStat = -1
696     return
697     endif
698    
699     allocate(excludesGlobal(nExcludes_Global), stat=alloc_stat)
700     if (alloc_stat /= 0 ) then
701     thisStat = -1
702     return
703     endif
704    
705     allocate(molMembershipList(nGlobal), stat=alloc_stat)
706     if (alloc_stat /= 0 ) then
707     thisStat = -1
708     return
709     endif
710    
711     end subroutine InitializeSimGlobals
712    
713     subroutine FreeSimGlobals()
714    
715     !We free in the opposite order in which we allocate in.
716    
717     if (allocated(skipsForAtom)) deallocate(skipsForAtom)
718     if (allocated(nSkipsForAtom)) deallocate(nSkipsForAtom)
719     if (allocated(mfactLocal)) deallocate(mfactLocal)
720     if (allocated(mfactCol)) deallocate(mfactCol)
721     if (allocated(mfactRow)) deallocate(mfactRow)
722     if (allocated(groupListCol)) deallocate(groupListCol)
723     if (allocated(groupListRow)) deallocate(groupListRow)
724     if (allocated(groupStartCol)) deallocate(groupStartCol)
725     if (allocated(groupStartRow)) deallocate(groupStartRow)
726     if (allocated(molMembershipList)) deallocate(molMembershipList)
727     if (allocated(excludesGlobal)) deallocate(excludesGlobal)
728     if (allocated(excludesLocal)) deallocate(excludesLocal)
729    
730     end subroutine FreeSimGlobals
731    
732     pure function getNlocal() result(n)
733     integer :: n
734     n = nLocal
735     end function getNlocal
736    
737 gezelter 2592 subroutine setHmatDangerousRcutValue(dangerWillRobinson)
738     real(kind=dp), intent(in) :: dangerWillRobinson
739     DangerRcut = dangerWillRobinson
740 chuckv 2262
741 gezelter 2592 call checkBox()
742 chuckv 2262
743 gezelter 2592 return
744     end subroutine setHmatDangerousRcutValue
745 chuckv 2262
746    
747 gezelter 2592
748 gezelter 2204 end module simulation