ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-2.0/src/UseTheForce/DarkSide/simulation.F90
Revision: 2432
Committed: Tue Nov 15 16:01:06 2005 UTC (18 years, 9 months ago) by chuckv
File size: 21673 byte(s)
Log Message:
Added Sutton-Chen to force loop...

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     use neighborLists
47     use force_globals
48     use vector_class
49     use atype_module
50     use switcheroo
51     #ifdef IS_MPI
52     use mpiSimulation
53     #endif
54    
55     implicit none
56     PRIVATE
57    
58     #define __FORTRAN90
59     #include "brains/fSimulation.h"
60     #include "UseTheForce/fSwitchingFunction.h"
61 chrisfen 2310 #include "UseTheForce/DarkSide/fElectrostaticSummationMethod.h"
62 gezelter 1608
63     type (simtype), public, save :: thisSim
64    
65     logical, save :: simulation_setup_complete = .false.
66    
67     integer, public, save :: nLocal, nGlobal
68     integer, public, save :: nGroups, nGroupGlobal
69     integer, public, save :: nExcludes_Global = 0
70     integer, public, save :: nExcludes_Local = 0
71     integer, allocatable, dimension(:,:), public :: excludesLocal
72     integer, allocatable, dimension(:), public :: excludesGlobal
73     integer, allocatable, dimension(:), public :: molMembershipList
74     integer, allocatable, dimension(:), public :: groupListRow
75     integer, allocatable, dimension(:), public :: groupStartRow
76     integer, allocatable, dimension(:), public :: groupListCol
77     integer, allocatable, dimension(:), public :: groupStartCol
78     integer, allocatable, dimension(:), public :: groupListLocal
79     integer, allocatable, dimension(:), public :: groupStartLocal
80     integer, allocatable, dimension(:), public :: nSkipsForAtom
81     integer, allocatable, dimension(:,:), public :: skipsForAtom
82     real(kind=dp), allocatable, dimension(:), public :: mfactRow
83     real(kind=dp), allocatable, dimension(:), public :: mfactCol
84     real(kind=dp), allocatable, dimension(:), public :: mfactLocal
85    
86 chuckv 2262 logical, allocatable, dimension(:) :: simHasAtypeMap
87 chuckv 2329 #ifdef IS_MPI
88     logical, allocatable, dimension(:) :: simHasAtypeMapTemp
89     #endif
90    
91 gezelter 1608 real(kind=dp), public, dimension(3,3), save :: Hmat, HmatInv
92     logical, public, save :: boxIsOrthorhombic
93 gezelter 2204
94 gezelter 1608 public :: SimulationSetup
95     public :: getNlocal
96     public :: setBox
97     public :: getDielect
98     public :: SimUsesPBC
99 gezelter 1633
100     public :: SimUsesDirectionalAtoms
101     public :: SimUsesLennardJones
102     public :: SimUsesElectrostatics
103 gezelter 1608 public :: SimUsesCharges
104     public :: SimUsesDipoles
105     public :: SimUsesSticky
106 chrisfen 2220 public :: SimUsesStickyPower
107 gezelter 1633 public :: SimUsesGayBerne
108     public :: SimUsesEAM
109     public :: SimUsesShapes
110     public :: SimUsesFLARB
111 gezelter 1608 public :: SimUsesRF
112 chrisfen 2418 public :: SimUsesSF
113 gezelter 1608 public :: SimRequiresPrepairCalc
114     public :: SimRequiresPostpairCalc
115 chuckv 2262 public :: SimHasAtype
116 chuckv 2432 public :: SimUsesSC
117     public :: SimUsesMEAM
118 gezelter 1633
119 gezelter 1608 contains
120 gezelter 2204
121 gezelter 1608 subroutine SimulationSetup(setThisSim, CnGlobal, CnLocal, c_idents, &
122     CnLocalExcludes, CexcludesLocal, CnGlobalExcludes, CexcludesGlobal, &
123     CmolMembership, Cmfact, CnGroups, CglobalGroupMembership, &
124     status)
125    
126     type (simtype) :: setThisSim
127     integer, intent(inout) :: CnGlobal, CnLocal
128     integer, dimension(CnLocal),intent(inout) :: c_idents
129    
130     integer :: CnLocalExcludes
131     integer, dimension(2,CnLocalExcludes), intent(in) :: CexcludesLocal
132     integer :: CnGlobalExcludes
133     integer, dimension(CnGlobalExcludes), intent(in) :: CexcludesGlobal
134     integer, dimension(CnGlobal),intent(in) :: CmolMembership
135     !! Result status, success = 0, status = -1
136     integer, intent(out) :: status
137     integer :: i, j, me, thisStat, alloc_stat, myNode, id1, id2
138     integer :: ia
139    
140     !! mass factors used for molecular cutoffs
141     real ( kind = dp ), dimension(CnLocal) :: Cmfact
142     integer, intent(in):: CnGroups
143     integer, dimension(CnGlobal), intent(in):: CglobalGroupMembership
144     integer :: maxSkipsForAtom, glPointer
145    
146     #ifdef IS_MPI
147     integer, allocatable, dimension(:) :: c_idents_Row
148     integer, allocatable, dimension(:) :: c_idents_Col
149     integer :: nAtomsInRow, nGroupsInRow, aid
150     integer :: nAtomsInCol, nGroupsInCol, gid
151     #endif
152    
153     simulation_setup_complete = .false.
154     status = 0
155    
156     ! copy C struct into fortran type
157    
158     nLocal = CnLocal
159     nGlobal = CnGlobal
160     nGroups = CnGroups
161    
162     thisSim = setThisSim
163    
164     nExcludes_Global = CnGlobalExcludes
165     nExcludes_Local = CnLocalExcludes
166    
167     call InitializeForceGlobals(nLocal, thisStat)
168     if (thisStat /= 0) then
169     write(default_error,*) "SimSetup: InitializeForceGlobals error"
170     status = -1
171     return
172     endif
173    
174     call InitializeSimGlobals(thisStat)
175     if (thisStat /= 0) then
176     write(default_error,*) "SimSetup: InitializeSimGlobals error"
177     status = -1
178     return
179     endif
180    
181     #ifdef IS_MPI
182     ! We can only set up forces if mpiSimulation has been setup.
183     if (.not. isMPISimSet()) then
184     write(default_error,*) "MPI is not set"
185     status = -1
186     return
187     endif
188     nAtomsInRow = getNatomsInRow(plan_atom_row)
189     nAtomsInCol = getNatomsInCol(plan_atom_col)
190     nGroupsInRow = getNgroupsInRow(plan_group_row)
191     nGroupsInCol = getNgroupsInCol(plan_group_col)
192     mynode = getMyNode()
193 gezelter 2204
194 gezelter 1608 allocate(c_idents_Row(nAtomsInRow),stat=alloc_stat)
195     if (alloc_stat /= 0 ) then
196     status = -1
197     return
198     endif
199    
200     allocate(c_idents_Col(nAtomsInCol),stat=alloc_stat)
201     if (alloc_stat /= 0 ) then
202     status = -1
203     return
204     endif
205    
206     call gather(c_idents, c_idents_Row, plan_atom_row)
207     call gather(c_idents, c_idents_Col, plan_atom_col)
208    
209     do i = 1, nAtomsInRow
210     me = getFirstMatchingElement(atypes, "c_ident", c_idents_Row(i))
211     atid_Row(i) = me
212     enddo
213    
214     do i = 1, nAtomsInCol
215     me = getFirstMatchingElement(atypes, "c_ident", c_idents_Col(i))
216     atid_Col(i) = me
217     enddo
218    
219     !! free temporary ident arrays
220     if (allocated(c_idents_Col)) then
221     deallocate(c_idents_Col)
222     end if
223     if (allocated(c_idents_Row)) then
224     deallocate(c_idents_Row)
225     endif
226 gezelter 2204
227 gezelter 1608 #endif
228    
229     #ifdef IS_MPI
230     allocate(groupStartRow(nGroupsInRow+1),stat=alloc_stat)
231     if (alloc_stat /= 0 ) then
232     status = -1
233     return
234     endif
235     allocate(groupStartCol(nGroupsInCol+1),stat=alloc_stat)
236     if (alloc_stat /= 0 ) then
237     status = -1
238     return
239     endif
240     allocate(groupListRow(nAtomsInRow),stat=alloc_stat)
241     if (alloc_stat /= 0 ) then
242     status = -1
243     return
244     endif
245     allocate(groupListCol(nAtomsInCol),stat=alloc_stat)
246     if (alloc_stat /= 0 ) then
247     status = -1
248     return
249     endif
250     allocate(mfactRow(nAtomsInRow),stat=alloc_stat)
251     if (alloc_stat /= 0 ) then
252     status = -1
253     return
254     endif
255     allocate(mfactCol(nAtomsInCol),stat=alloc_stat)
256     if (alloc_stat /= 0 ) then
257     status = -1
258     return
259     endif
260     allocate(mfactLocal(nLocal),stat=alloc_stat)
261     if (alloc_stat /= 0 ) then
262     status = -1
263     return
264     endif
265 gezelter 2204
266 gezelter 1608 glPointer = 1
267    
268     do i = 1, nGroupsInRow
269    
270     gid = GroupRowToGlobal(i)
271     groupStartRow(i) = glPointer
272    
273     do j = 1, nAtomsInRow
274     aid = AtomRowToGlobal(j)
275     if (CglobalGroupMembership(aid) .eq. gid) then
276     groupListRow(glPointer) = j
277     glPointer = glPointer + 1
278     endif
279     enddo
280     enddo
281     groupStartRow(nGroupsInRow+1) = nAtomsInRow + 1
282    
283     glPointer = 1
284    
285     do i = 1, nGroupsInCol
286    
287     gid = GroupColToGlobal(i)
288     groupStartCol(i) = glPointer
289    
290     do j = 1, nAtomsInCol
291     aid = AtomColToGlobal(j)
292     if (CglobalGroupMembership(aid) .eq. gid) then
293     groupListCol(glPointer) = j
294     glPointer = glPointer + 1
295     endif
296     enddo
297     enddo
298     groupStartCol(nGroupsInCol+1) = nAtomsInCol + 1
299    
300     mfactLocal = Cmfact
301    
302     call gather(mfactLocal, mfactRow, plan_atom_row)
303     call gather(mfactLocal, mfactCol, plan_atom_col)
304 gezelter 2204
305 gezelter 1608 if (allocated(mfactLocal)) then
306     deallocate(mfactLocal)
307     end if
308     #else
309     allocate(groupStartRow(nGroups+1),stat=alloc_stat)
310     if (alloc_stat /= 0 ) then
311     status = -1
312     return
313     endif
314     allocate(groupStartCol(nGroups+1),stat=alloc_stat)
315     if (alloc_stat /= 0 ) then
316     status = -1
317     return
318     endif
319     allocate(groupListRow(nLocal),stat=alloc_stat)
320     if (alloc_stat /= 0 ) then
321     status = -1
322     return
323     endif
324     allocate(groupListCol(nLocal),stat=alloc_stat)
325     if (alloc_stat /= 0 ) then
326     status = -1
327     return
328     endif
329     allocate(mfactRow(nLocal),stat=alloc_stat)
330     if (alloc_stat /= 0 ) then
331     status = -1
332     return
333     endif
334     allocate(mfactCol(nLocal),stat=alloc_stat)
335     if (alloc_stat /= 0 ) then
336     status = -1
337     return
338     endif
339     allocate(mfactLocal(nLocal),stat=alloc_stat)
340     if (alloc_stat /= 0 ) then
341     status = -1
342     return
343     endif
344    
345     glPointer = 1
346     do i = 1, nGroups
347     groupStartRow(i) = glPointer
348     groupStartCol(i) = glPointer
349     do j = 1, nLocal
350     if (CglobalGroupMembership(j) .eq. i) then
351     groupListRow(glPointer) = j
352     groupListCol(glPointer) = j
353     glPointer = glPointer + 1
354     endif
355     enddo
356     enddo
357     groupStartRow(nGroups+1) = nLocal + 1
358     groupStartCol(nGroups+1) = nLocal + 1
359    
360     do i = 1, nLocal
361     mfactRow(i) = Cmfact(i)
362     mfactCol(i) = Cmfact(i)
363     end do
364 gezelter 2204
365 gezelter 1608 #endif
366    
367    
368 gezelter 2204 ! We build the local atid's for both mpi and nonmpi
369 gezelter 1608 do i = 1, nLocal
370 gezelter 2204
371 gezelter 1608 me = getFirstMatchingElement(atypes, "c_ident", c_idents(i))
372     atid(i) = me
373 gezelter 2204
374 gezelter 1608 enddo
375    
376     do i = 1, nExcludes_Local
377     excludesLocal(1,i) = CexcludesLocal(1,i)
378     excludesLocal(2,i) = CexcludesLocal(2,i)
379     enddo
380    
381     #ifdef IS_MPI
382     allocate(nSkipsForAtom(nAtomsInRow), stat=alloc_stat)
383     #else
384     allocate(nSkipsForAtom(nLocal), stat=alloc_stat)
385     #endif
386     if (alloc_stat /= 0 ) then
387     thisStat = -1
388     write(*,*) 'Could not allocate nSkipsForAtom array'
389     return
390     endif
391    
392     maxSkipsForAtom = 0
393     #ifdef IS_MPI
394     do j = 1, nAtomsInRow
395     #else
396 gezelter 2204 do j = 1, nLocal
397 gezelter 1608 #endif
398 gezelter 2204 nSkipsForAtom(j) = 0
399 gezelter 1608 #ifdef IS_MPI
400 gezelter 2204 id1 = AtomRowToGlobal(j)
401 gezelter 1608 #else
402 gezelter 2204 id1 = j
403 gezelter 1608 #endif
404 gezelter 2204 do i = 1, nExcludes_Local
405     if (excludesLocal(1,i) .eq. id1 ) then
406     nSkipsForAtom(j) = nSkipsForAtom(j) + 1
407 gezelter 1608
408 gezelter 2204 if (nSkipsForAtom(j) .gt. maxSkipsForAtom) then
409     maxSkipsForAtom = nSkipsForAtom(j)
410     endif
411 gezelter 1608 endif
412 gezelter 2204 if (excludesLocal(2,i) .eq. id1 ) then
413     nSkipsForAtom(j) = nSkipsForAtom(j) + 1
414 gezelter 1608
415 gezelter 2204 if (nSkipsForAtom(j) .gt. maxSkipsForAtom) then
416     maxSkipsForAtom = nSkipsForAtom(j)
417     endif
418 gezelter 1608 endif
419 gezelter 2204 end do
420     enddo
421 gezelter 1608
422     #ifdef IS_MPI
423 gezelter 2204 allocate(skipsForAtom(nAtomsInRow, maxSkipsForAtom), stat=alloc_stat)
424 gezelter 1608 #else
425 gezelter 2204 allocate(skipsForAtom(nLocal, maxSkipsForAtom), stat=alloc_stat)
426 gezelter 1608 #endif
427 gezelter 2204 if (alloc_stat /= 0 ) then
428     write(*,*) 'Could not allocate skipsForAtom array'
429     return
430     endif
431 gezelter 1608
432     #ifdef IS_MPI
433 gezelter 2204 do j = 1, nAtomsInRow
434 gezelter 1608 #else
435 gezelter 2204 do j = 1, nLocal
436 gezelter 1608 #endif
437 gezelter 2204 nSkipsForAtom(j) = 0
438 gezelter 1608 #ifdef IS_MPI
439 gezelter 2204 id1 = AtomRowToGlobal(j)
440 gezelter 1608 #else
441 gezelter 2204 id1 = j
442 gezelter 1608 #endif
443 gezelter 2204 do i = 1, nExcludes_Local
444     if (excludesLocal(1,i) .eq. id1 ) then
445     nSkipsForAtom(j) = nSkipsForAtom(j) + 1
446     ! exclude lists have global ID's so this line is
447     ! the same in MPI and non-MPI
448     id2 = excludesLocal(2,i)
449     skipsForAtom(j, nSkipsForAtom(j)) = id2
450     endif
451     if (excludesLocal(2, i) .eq. id1 ) then
452     nSkipsForAtom(j) = nSkipsForAtom(j) + 1
453     ! exclude lists have global ID's so this line is
454     ! the same in MPI and non-MPI
455     id2 = excludesLocal(1,i)
456     skipsForAtom(j, nSkipsForAtom(j)) = id2
457     endif
458     end do
459     enddo
460    
461     do i = 1, nExcludes_Global
462     excludesGlobal(i) = CexcludesGlobal(i)
463     enddo
464    
465     do i = 1, nGlobal
466     molMemberShipList(i) = CmolMembership(i)
467     enddo
468    
469 chuckv 2262 call createSimHasAtype(alloc_stat)
470     if (alloc_stat /= 0) then
471     status = -1
472     end if
473    
474     if (status == 0) simulation_setup_complete = .true.
475 gezelter 2204
476     end subroutine SimulationSetup
477    
478     subroutine setBox(cHmat, cHmatInv, cBoxIsOrthorhombic)
479     real(kind=dp), dimension(3,3) :: cHmat, cHmatInv
480     integer :: cBoxIsOrthorhombic
481     integer :: smallest, status, i
482    
483     Hmat = cHmat
484     HmatInv = cHmatInv
485     if (cBoxIsOrthorhombic .eq. 0 ) then
486     boxIsOrthorhombic = .false.
487     else
488     boxIsOrthorhombic = .true.
489 gezelter 1608 endif
490    
491 gezelter 2204 return
492     end subroutine setBox
493 gezelter 1608
494 gezelter 2204 function getDielect() result(dielect)
495     real( kind = dp ) :: dielect
496     dielect = thisSim%dielect
497     end function getDielect
498 gezelter 1608
499 gezelter 2204 function SimUsesPBC() result(doesit)
500     logical :: doesit
501     doesit = thisSim%SIM_uses_PBC
502     end function SimUsesPBC
503 gezelter 1608
504 gezelter 2204 function SimUsesDirectionalAtoms() result(doesit)
505     logical :: doesit
506 chrisfen 2220 doesit = thisSim%SIM_uses_dipoles .or. thisSim%SIM_uses_Sticky .or. &
507     thisSim%SIM_uses_StickyPower .or. &
508 gezelter 2204 thisSim%SIM_uses_GayBerne .or. thisSim%SIM_uses_Shapes
509     end function SimUsesDirectionalAtoms
510 gezelter 1608
511 gezelter 2204 function SimUsesLennardJones() result(doesit)
512     logical :: doesit
513     doesit = thisSim%SIM_uses_LennardJones
514     end function SimUsesLennardJones
515 gezelter 1633
516 gezelter 2204 function SimUsesElectrostatics() result(doesit)
517     logical :: doesit
518     doesit = thisSim%SIM_uses_Electrostatics
519     end function SimUsesElectrostatics
520 gezelter 1608
521 gezelter 2204 function SimUsesCharges() result(doesit)
522     logical :: doesit
523     doesit = thisSim%SIM_uses_Charges
524     end function SimUsesCharges
525 gezelter 1608
526 gezelter 2204 function SimUsesDipoles() result(doesit)
527     logical :: doesit
528     doesit = thisSim%SIM_uses_Dipoles
529     end function SimUsesDipoles
530 gezelter 1608
531 gezelter 2204 function SimUsesSticky() result(doesit)
532     logical :: doesit
533     doesit = thisSim%SIM_uses_Sticky
534     end function SimUsesSticky
535 gezelter 1608
536 chrisfen 2220 function SimUsesStickyPower() result(doesit)
537     logical :: doesit
538     doesit = thisSim%SIM_uses_StickyPower
539     end function SimUsesStickyPower
540    
541 gezelter 2204 function SimUsesGayBerne() result(doesit)
542     logical :: doesit
543     doesit = thisSim%SIM_uses_GayBerne
544     end function SimUsesGayBerne
545 gezelter 1608
546 gezelter 2204 function SimUsesEAM() result(doesit)
547     logical :: doesit
548     doesit = thisSim%SIM_uses_EAM
549     end function SimUsesEAM
550 gezelter 1633
551 chuckv 2432
552     function SimUsesSC() result(doesit)
553     logical :: doesit
554     doesit = thisSim%SIM_uses_SC
555     end function SimUsesSC
556    
557     function SimUsesMEAM() result(doesit)
558     logical :: doesit
559     doesit = thisSim%SIM_uses_MEAM
560     end function SimUsesMEAM
561    
562    
563 gezelter 2204 function SimUsesShapes() result(doesit)
564     logical :: doesit
565     doesit = thisSim%SIM_uses_Shapes
566     end function SimUsesShapes
567 gezelter 1633
568 gezelter 2204 function SimUsesFLARB() result(doesit)
569     logical :: doesit
570     doesit = thisSim%SIM_uses_FLARB
571     end function SimUsesFLARB
572 gezelter 1608
573 gezelter 2204 function SimUsesRF() result(doesit)
574     logical :: doesit
575     doesit = thisSim%SIM_uses_RF
576     end function SimUsesRF
577 gezelter 1608
578 chrisfen 2418 function SimUsesSF() result(doesit)
579 chrisfen 2402 logical :: doesit
580 chrisfen 2418 doesit = thisSim%SIM_uses_SF
581     end function SimUsesSF
582 chrisfen 2402
583 gezelter 2204 function SimRequiresPrepairCalc() result(doesit)
584     logical :: doesit
585 chuckv 2432 doesit = thisSim%SIM_uses_EAM .or. thisSim%SIM_uses_SC &
586     .or. thisSim%SIM_uses_MEAM
587 gezelter 2204 end function SimRequiresPrepairCalc
588 chrisfen 2390
589 gezelter 2204 function SimRequiresPostpairCalc() result(doesit)
590     logical :: doesit
591 chrisfen 2418 doesit = thisSim%SIM_uses_RF .or. thisSim%SIM_uses_SF
592 gezelter 2204 end function SimRequiresPostpairCalc
593    
594 gezelter 2274 ! Function returns true if the simulation has this atype
595 chuckv 2262 function SimHasAtype(thisAtype) result(doesit)
596     logical :: doesit
597     integer :: thisAtype
598     doesit = .false.
599     if(.not.allocated(SimHasAtypeMap)) return
600    
601     doesit = SimHasAtypeMap(thisAtype)
602    
603     end function SimHasAtype
604    
605     subroutine createSimHasAtype(status)
606     integer, intent(out) :: status
607     integer :: alloc_stat
608     integer :: me_i
609     integer :: mpiErrors
610     integer :: nAtypes
611     status = 0
612    
613     nAtypes = getSize(atypes)
614     ! Setup logical map for atypes in simulation
615     if (.not.allocated(SimHasAtypeMap)) then
616     allocate(SimHasAtypeMap(nAtypes),stat=alloc_stat)
617     if (alloc_stat /= 0 ) then
618     status = -1
619     return
620     end if
621     SimHasAtypeMap = .false.
622     end if
623 chuckv 2329
624 gezelter 2274 ! Loop through the local atoms and grab the atypes present
625 chuckv 2262 do me_i = 1,nLocal
626     SimHasAtypeMap(atid(me_i)) = .true.
627     end do
628 gezelter 2274 ! For MPI, we need to know all possible atypes present in
629     ! simulation on all processors. Use LOR operation to set map.
630 chuckv 2262 #ifdef IS_MPI
631 chuckv 2329 if (.not.allocated(SimHasAtypeMapTemp)) then
632     allocate(SimHasAtypeMapTemp(nAtypes),stat=alloc_stat)
633     if (alloc_stat /= 0 ) then
634     status = -1
635     return
636     end if
637     end if
638     call mpi_allreduce(SimHasAtypeMap, SimHasAtypeMaptemp, nAtypes, &
639 gezelter 2274 mpi_logical, MPI_LOR, mpi_comm_world, mpiErrors)
640 chuckv 2329 simHasAtypeMap = simHasAtypeMapTemp
641     deallocate(simHasAtypeMapTemp)
642 gezelter 2274 #endif
643 chuckv 2262 end subroutine createSimHasAtype
644 gezelter 2274
645 chuckv 2262 subroutine InitializeSimGlobals(thisStat)
646 gezelter 2204 integer, intent(out) :: thisStat
647     integer :: alloc_stat
648    
649     thisStat = 0
650    
651     call FreeSimGlobals()
652    
653     allocate(excludesLocal(2,nExcludes_Local), stat=alloc_stat)
654     if (alloc_stat /= 0 ) then
655     thisStat = -1
656     return
657     endif
658    
659     allocate(excludesGlobal(nExcludes_Global), stat=alloc_stat)
660     if (alloc_stat /= 0 ) then
661     thisStat = -1
662     return
663     endif
664    
665     allocate(molMembershipList(nGlobal), stat=alloc_stat)
666     if (alloc_stat /= 0 ) then
667     thisStat = -1
668     return
669     endif
670    
671     end subroutine InitializeSimGlobals
672    
673     subroutine FreeSimGlobals()
674    
675     !We free in the opposite order in which we allocate in.
676    
677     if (allocated(skipsForAtom)) deallocate(skipsForAtom)
678     if (allocated(nSkipsForAtom)) deallocate(nSkipsForAtom)
679     if (allocated(mfactLocal)) deallocate(mfactLocal)
680     if (allocated(mfactCol)) deallocate(mfactCol)
681     if (allocated(mfactRow)) deallocate(mfactRow)
682     if (allocated(groupListCol)) deallocate(groupListCol)
683     if (allocated(groupListRow)) deallocate(groupListRow)
684     if (allocated(groupStartCol)) deallocate(groupStartCol)
685     if (allocated(groupStartRow)) deallocate(groupStartRow)
686     if (allocated(molMembershipList)) deallocate(molMembershipList)
687     if (allocated(excludesGlobal)) deallocate(excludesGlobal)
688     if (allocated(excludesLocal)) deallocate(excludesLocal)
689    
690     end subroutine FreeSimGlobals
691    
692     pure function getNlocal() result(n)
693     integer :: n
694     n = nLocal
695     end function getNlocal
696    
697 chuckv 2262
698    
699    
700    
701 gezelter 2204 end module simulation