ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/UseTheForce/DarkSide/simulation.F90
Revision: 1290
Committed: Wed Sep 10 19:51:45 2008 UTC (16 years, 9 months ago) by cli2
Original Path: trunk/src/UseTheForce/DarkSide/simulation.F90
File size: 27380 byte(s)
Log Message:
Inversion fixes and amber mostly working

File Contents

# User Rev Content
1 gezelter 246 !!
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 115 !! Fortran interface to C entry plug.
43    
44     module simulation
45     use definitions
46 gezelter 889 use status
47     use linearAlgebra
48 gezelter 115 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 611 #include "UseTheForce/DarkSide/fElectrostaticSummationMethod.h"
64 gezelter 115
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 gezelter 1286 integer, public, save :: nExcludes = 0
72     integer, public, save :: nOneTwo = 0
73     integer, public, save :: nOneThree = 0
74     integer, public, save :: nOneFour = 0
75    
76     integer, allocatable, dimension(:,:), public :: excludes
77 gezelter 115 integer, allocatable, dimension(:), public :: molMembershipList
78     integer, allocatable, dimension(:), public :: groupListRow
79     integer, allocatable, dimension(:), public :: groupStartRow
80     integer, allocatable, dimension(:), public :: groupListCol
81     integer, allocatable, dimension(:), public :: groupStartCol
82     integer, allocatable, dimension(:), public :: groupListLocal
83     integer, allocatable, dimension(:), public :: groupStartLocal
84     integer, allocatable, dimension(:), public :: nSkipsForAtom
85     integer, allocatable, dimension(:,:), public :: skipsForAtom
86 gezelter 1286 integer, allocatable, dimension(:), public :: nTopoPairsForAtom
87     integer, allocatable, dimension(:,:), public :: toposForAtom
88     integer, allocatable, dimension(:,:), public :: topoDistance
89 gezelter 115 real(kind=dp), allocatable, dimension(:), public :: mfactRow
90     real(kind=dp), allocatable, dimension(:), public :: mfactCol
91     real(kind=dp), allocatable, dimension(:), public :: mfactLocal
92    
93 chuckv 563 logical, allocatable, dimension(:) :: simHasAtypeMap
94 chuckv 630 #ifdef IS_MPI
95     logical, allocatable, dimension(:) :: simHasAtypeMapTemp
96     #endif
97    
98 gezelter 115 real(kind=dp), public, dimension(3,3), save :: Hmat, HmatInv
99 gezelter 889 real(kind=dp), save :: DangerRcut
100 gezelter 115 logical, public, save :: boxIsOrthorhombic
101 gezelter 507
102 gezelter 115 public :: SimulationSetup
103     public :: getNlocal
104     public :: setBox
105 gezelter 889 public :: checkBox
106 gezelter 115 public :: SimUsesPBC
107 gezelter 1126 public :: SimUsesAtomicVirial
108 gezelter 140
109     public :: SimUsesDirectionalAtoms
110     public :: SimUsesLennardJones
111     public :: SimUsesElectrostatics
112 gezelter 115 public :: SimUsesCharges
113     public :: SimUsesDipoles
114     public :: SimUsesSticky
115 chrisfen 523 public :: SimUsesStickyPower
116 gezelter 140 public :: SimUsesGayBerne
117     public :: SimUsesEAM
118     public :: SimUsesShapes
119     public :: SimUsesFLARB
120 gezelter 115 public :: SimUsesRF
121 chrisfen 719 public :: SimUsesSF
122 chrisfen 998 public :: SimUsesSP
123     public :: SimUsesBoxDipole
124 gezelter 115 public :: SimRequiresPrepairCalc
125     public :: SimRequiresPostpairCalc
126 chuckv 563 public :: SimHasAtype
127 chuckv 733 public :: SimUsesSC
128 chuckv 1162 public :: SimUsesMNM
129 gezelter 889 public :: setHmatDangerousRcutValue
130 gezelter 140
131 gezelter 115 contains
132 gezelter 507
133 gezelter 115 subroutine SimulationSetup(setThisSim, CnGlobal, CnLocal, c_idents, &
134 gezelter 1286 CnExcludes, Cexcludes, CnOneTwo, ConeTwo, CnOneThree, ConeThree, &
135     CnOneFour, ConeFour, CmolMembership, Cmfact, CnGroups, &
136     CglobalGroupMembership, status)
137 gezelter 115
138     type (simtype) :: setThisSim
139     integer, intent(inout) :: CnGlobal, CnLocal
140     integer, dimension(CnLocal),intent(inout) :: c_idents
141    
142 gezelter 1286 integer :: CnExcludes
143     integer, dimension(2,CnExcludes), intent(in) :: Cexcludes
144     integer :: CnOneTwo
145     integer, dimension(2,CnOneTwo), intent(in) :: ConeTwo
146     integer :: CnOneThree
147     integer, dimension(2,CnOneThree), intent(in) :: ConeThree
148     integer :: CnOneFour
149     integer, dimension(2,CnOneFour), intent(in) :: ConeFour
150    
151 gezelter 115 integer, dimension(CnGlobal),intent(in) :: CmolMembership
152     !! Result status, success = 0, status = -1
153     integer, intent(out) :: status
154     integer :: i, j, me, thisStat, alloc_stat, myNode, id1, id2
155 gezelter 1286 integer :: ia, jend
156 gezelter 115
157     !! mass factors used for molecular cutoffs
158     real ( kind = dp ), dimension(CnLocal) :: Cmfact
159     integer, intent(in):: CnGroups
160     integer, dimension(CnGlobal), intent(in):: CglobalGroupMembership
161 gezelter 1286 integer :: maxSkipsForAtom, maxToposForAtom, glPointer
162 gezelter 115
163     #ifdef IS_MPI
164     integer, allocatable, dimension(:) :: c_idents_Row
165     integer, allocatable, dimension(:) :: c_idents_Col
166     integer :: nAtomsInRow, nGroupsInRow, aid
167     integer :: nAtomsInCol, nGroupsInCol, gid
168     #endif
169    
170     simulation_setup_complete = .false.
171     status = 0
172    
173     ! copy C struct into fortran type
174    
175     nLocal = CnLocal
176     nGlobal = CnGlobal
177     nGroups = CnGroups
178    
179     thisSim = setThisSim
180    
181 gezelter 1286 nExcludes = CnExcludes
182 gezelter 115
183     call InitializeForceGlobals(nLocal, thisStat)
184     if (thisStat /= 0) then
185     write(default_error,*) "SimSetup: InitializeForceGlobals error"
186     status = -1
187     return
188     endif
189    
190     call InitializeSimGlobals(thisStat)
191     if (thisStat /= 0) then
192     write(default_error,*) "SimSetup: InitializeSimGlobals error"
193     status = -1
194     return
195     endif
196    
197     #ifdef IS_MPI
198     ! We can only set up forces if mpiSimulation has been setup.
199     if (.not. isMPISimSet()) then
200     write(default_error,*) "MPI is not set"
201     status = -1
202     return
203     endif
204     nAtomsInRow = getNatomsInRow(plan_atom_row)
205     nAtomsInCol = getNatomsInCol(plan_atom_col)
206     nGroupsInRow = getNgroupsInRow(plan_group_row)
207     nGroupsInCol = getNgroupsInCol(plan_group_col)
208     mynode = getMyNode()
209 gezelter 507
210 gezelter 115 allocate(c_idents_Row(nAtomsInRow),stat=alloc_stat)
211     if (alloc_stat /= 0 ) then
212     status = -1
213     return
214     endif
215    
216     allocate(c_idents_Col(nAtomsInCol),stat=alloc_stat)
217     if (alloc_stat /= 0 ) then
218     status = -1
219     return
220     endif
221    
222     call gather(c_idents, c_idents_Row, plan_atom_row)
223     call gather(c_idents, c_idents_Col, plan_atom_col)
224    
225     do i = 1, nAtomsInRow
226     me = getFirstMatchingElement(atypes, "c_ident", c_idents_Row(i))
227     atid_Row(i) = me
228     enddo
229    
230     do i = 1, nAtomsInCol
231     me = getFirstMatchingElement(atypes, "c_ident", c_idents_Col(i))
232     atid_Col(i) = me
233     enddo
234    
235     !! free temporary ident arrays
236     if (allocated(c_idents_Col)) then
237     deallocate(c_idents_Col)
238     end if
239     if (allocated(c_idents_Row)) then
240     deallocate(c_idents_Row)
241     endif
242 gezelter 507
243 gezelter 115 #endif
244    
245     #ifdef IS_MPI
246     allocate(groupStartRow(nGroupsInRow+1),stat=alloc_stat)
247     if (alloc_stat /= 0 ) then
248     status = -1
249     return
250     endif
251     allocate(groupStartCol(nGroupsInCol+1),stat=alloc_stat)
252     if (alloc_stat /= 0 ) then
253     status = -1
254     return
255     endif
256     allocate(groupListRow(nAtomsInRow),stat=alloc_stat)
257     if (alloc_stat /= 0 ) then
258     status = -1
259     return
260     endif
261     allocate(groupListCol(nAtomsInCol),stat=alloc_stat)
262     if (alloc_stat /= 0 ) then
263     status = -1
264     return
265     endif
266     allocate(mfactRow(nAtomsInRow),stat=alloc_stat)
267     if (alloc_stat /= 0 ) then
268     status = -1
269     return
270     endif
271     allocate(mfactCol(nAtomsInCol),stat=alloc_stat)
272     if (alloc_stat /= 0 ) then
273     status = -1
274     return
275     endif
276     allocate(mfactLocal(nLocal),stat=alloc_stat)
277     if (alloc_stat /= 0 ) then
278     status = -1
279     return
280     endif
281 gezelter 1286
282 gezelter 115 glPointer = 1
283 gezelter 1286
284 gezelter 115 do i = 1, nGroupsInRow
285 gezelter 1286
286 gezelter 115 gid = GroupRowToGlobal(i)
287     groupStartRow(i) = glPointer
288 gezelter 1286
289 gezelter 115 do j = 1, nAtomsInRow
290     aid = AtomRowToGlobal(j)
291     if (CglobalGroupMembership(aid) .eq. gid) then
292     groupListRow(glPointer) = j
293     glPointer = glPointer + 1
294     endif
295     enddo
296     enddo
297     groupStartRow(nGroupsInRow+1) = nAtomsInRow + 1
298 gezelter 1286
299 gezelter 115 glPointer = 1
300 gezelter 1286
301 gezelter 115 do i = 1, nGroupsInCol
302 gezelter 1286
303 gezelter 115 gid = GroupColToGlobal(i)
304     groupStartCol(i) = glPointer
305 gezelter 1286
306 gezelter 115 do j = 1, nAtomsInCol
307     aid = AtomColToGlobal(j)
308     if (CglobalGroupMembership(aid) .eq. gid) then
309     groupListCol(glPointer) = j
310     glPointer = glPointer + 1
311     endif
312     enddo
313     enddo
314     groupStartCol(nGroupsInCol+1) = nAtomsInCol + 1
315    
316     mfactLocal = Cmfact
317    
318     call gather(mfactLocal, mfactRow, plan_atom_row)
319     call gather(mfactLocal, mfactCol, plan_atom_col)
320 gezelter 507
321 gezelter 115 if (allocated(mfactLocal)) then
322     deallocate(mfactLocal)
323     end if
324     #else
325     allocate(groupStartRow(nGroups+1),stat=alloc_stat)
326     if (alloc_stat /= 0 ) then
327     status = -1
328     return
329     endif
330     allocate(groupStartCol(nGroups+1),stat=alloc_stat)
331     if (alloc_stat /= 0 ) then
332     status = -1
333     return
334     endif
335     allocate(groupListRow(nLocal),stat=alloc_stat)
336     if (alloc_stat /= 0 ) then
337     status = -1
338     return
339     endif
340     allocate(groupListCol(nLocal),stat=alloc_stat)
341     if (alloc_stat /= 0 ) then
342     status = -1
343     return
344     endif
345     allocate(mfactRow(nLocal),stat=alloc_stat)
346     if (alloc_stat /= 0 ) then
347     status = -1
348     return
349     endif
350     allocate(mfactCol(nLocal),stat=alloc_stat)
351     if (alloc_stat /= 0 ) then
352     status = -1
353     return
354     endif
355     allocate(mfactLocal(nLocal),stat=alloc_stat)
356     if (alloc_stat /= 0 ) then
357     status = -1
358     return
359     endif
360    
361     glPointer = 1
362     do i = 1, nGroups
363     groupStartRow(i) = glPointer
364     groupStartCol(i) = glPointer
365     do j = 1, nLocal
366     if (CglobalGroupMembership(j) .eq. i) then
367     groupListRow(glPointer) = j
368     groupListCol(glPointer) = j
369     glPointer = glPointer + 1
370     endif
371     enddo
372     enddo
373     groupStartRow(nGroups+1) = nLocal + 1
374     groupStartCol(nGroups+1) = nLocal + 1
375    
376     do i = 1, nLocal
377     mfactRow(i) = Cmfact(i)
378     mfactCol(i) = Cmfact(i)
379     end do
380 gezelter 507
381 gezelter 115 #endif
382    
383 gezelter 507 ! We build the local atid's for both mpi and nonmpi
384 gezelter 115 do i = 1, nLocal
385     me = getFirstMatchingElement(atypes, "c_ident", c_idents(i))
386     atid(i) = me
387     enddo
388    
389 gezelter 1286 do i = 1, nExcludes
390     excludes(1,i) = Cexcludes(1,i)
391     excludes(2,i) = Cexcludes(2,i)
392 gezelter 115 enddo
393    
394     #ifdef IS_MPI
395     allocate(nSkipsForAtom(nAtomsInRow), stat=alloc_stat)
396     #else
397     allocate(nSkipsForAtom(nLocal), stat=alloc_stat)
398     #endif
399     if (alloc_stat /= 0 ) then
400     thisStat = -1
401     write(*,*) 'Could not allocate nSkipsForAtom array'
402     return
403     endif
404    
405     maxSkipsForAtom = 0
406 gezelter 1286
407 gezelter 115 #ifdef IS_MPI
408 gezelter 1286 jend = nAtomsInRow
409 gezelter 115 #else
410 gezelter 1286 jend = nLocal
411 gezelter 115 #endif
412 gezelter 1286
413     do j = 1, jend
414     nSkipsForAtom(j) = 0
415 gezelter 115 #ifdef IS_MPI
416 gezelter 1286 id1 = AtomRowToGlobal(j)
417 gezelter 115 #else
418 gezelter 1286 id1 = j
419 gezelter 115 #endif
420 gezelter 1286 do i = 1, nExcludes
421     if (excludes(1,i) .eq. id1 ) then
422     nSkipsForAtom(j) = nSkipsForAtom(j) + 1
423    
424     if (nSkipsForAtom(j) .gt. maxSkipsForAtom) then
425     maxSkipsForAtom = nSkipsForAtom(j)
426 gezelter 115 endif
427 gezelter 1286 endif
428     if (excludes(2,i) .eq. id1 ) then
429     nSkipsForAtom(j) = nSkipsForAtom(j) + 1
430    
431     if (nSkipsForAtom(j) .gt. maxSkipsForAtom) then
432     maxSkipsForAtom = nSkipsForAtom(j)
433 gezelter 115 endif
434 gezelter 1286 endif
435     end do
436     enddo
437    
438     #ifdef IS_MPI
439     allocate(skipsForAtom(nAtomsInRow, maxSkipsForAtom), stat=alloc_stat)
440     #else
441     allocate(skipsForAtom(nLocal, maxSkipsForAtom), stat=alloc_stat)
442     #endif
443     if (alloc_stat /= 0 ) then
444     write(*,*) 'Could not allocate skipsForAtom array'
445     return
446     endif
447    
448     #ifdef IS_MPI
449     jend = nAtomsInRow
450     #else
451     jend = nLocal
452     #endif
453     do j = 1, jend
454     nSkipsForAtom(j) = 0
455     #ifdef IS_MPI
456     id1 = AtomRowToGlobal(j)
457     #else
458     id1 = j
459     #endif
460     do i = 1, nExcludes
461     if (excludes(1,i) .eq. id1 ) then
462     nSkipsForAtom(j) = nSkipsForAtom(j) + 1
463     ! exclude lists have global ID's so this line is
464     ! the same in MPI and non-MPI
465     id2 = excludes(2,i)
466     skipsForAtom(j, nSkipsForAtom(j)) = id2
467     endif
468     if (excludes(2, i) .eq. id1 ) then
469     nSkipsForAtom(j) = nSkipsForAtom(j) + 1
470     ! exclude lists have global ID's so this line is
471     ! the same in MPI and non-MPI
472     id2 = excludes(1,i)
473     skipsForAtom(j, nSkipsForAtom(j)) = id2
474     endif
475     end do
476     enddo
477    
478     do i = 1, nGlobal
479     molMemberShipList(i) = CmolMembership(i)
480     enddo
481 gezelter 115
482     #ifdef IS_MPI
483 gezelter 1286 allocate(nTopoPairsForAtom(nAtomsInRow), stat=alloc_stat)
484 gezelter 115 #else
485 gezelter 1286 allocate(nTopoPairsForAtom(nLocal), stat=alloc_stat)
486 gezelter 115 #endif
487 gezelter 1286 if (alloc_stat /= 0 ) then
488     thisStat = -1
489     write(*,*) 'Could not allocate nTopoPairsForAtom array'
490     return
491     endif
492 gezelter 115
493     #ifdef IS_MPI
494 gezelter 1286 jend = nAtomsInRow
495 gezelter 115 #else
496 gezelter 1286 jend = nLocal
497 gezelter 115 #endif
498 gezelter 1286
499     do j = 1, jend
500     nTopoPairsForAtom(j) = 0
501 gezelter 115 #ifdef IS_MPI
502 gezelter 1286 id1 = AtomRowToGlobal(j)
503 gezelter 115 #else
504 gezelter 1286 id1 = j
505 gezelter 115 #endif
506 gezelter 1286 do i = 1, CnOneTwo
507     if (ConeTwo(1,i) .eq. id1 ) then
508     nTopoPairsForAtom(j) = nTopoPairsForAtom(j) + 1
509     endif
510     if (ConeTwo(2,i) .eq. id1 ) then
511     nTopoPairsForAtom(j) = nTopoPairsForAtom(j) + 1
512     endif
513     end do
514 gezelter 507
515 gezelter 1286 do i = 1, CnOneThree
516     if (ConeThree(1,i) .eq. id1 ) then
517     nTopoPairsForAtom(j) = nTopoPairsForAtom(j) + 1
518     endif
519     if (ConeThree(2,i) .eq. id1 ) then
520     nTopoPairsForAtom(j) = nTopoPairsForAtom(j) + 1
521     endif
522     end do
523 gezelter 507
524 gezelter 1286 do i = 1, CnOneFour
525     if (ConeFour(1,i) .eq. id1 ) then
526     nTopoPairsForAtom(j) = nTopoPairsForAtom(j) + 1
527     endif
528     if (ConeFour(2,i) .eq. id1 ) then
529     nTopoPairsForAtom(j) = nTopoPairsForAtom(j) + 1
530     endif
531     end do
532     enddo
533    
534     maxToposForAtom = maxval(nTopoPairsForAtom)
535     #ifdef IS_MPI
536     allocate(toposForAtom(nAtomsInRow, maxToposForAtom), stat=alloc_stat)
537     allocate(topoDistance(nAtomsInRow, maxToposForAtom), stat=alloc_stat)
538     #else
539     allocate(toposForAtom(nLocal, maxToposForAtom), stat=alloc_stat)
540     allocate(topoDistance(nLocal, maxToposForAtom), stat=alloc_stat)
541     #endif
542     if (alloc_stat /= 0 ) then
543     write(*,*) 'Could not allocate topoDistance array'
544     return
545     endif
546    
547     #ifdef IS_MPI
548     jend = nAtomsInRow
549     #else
550     jend = nLocal
551     #endif
552     do j = 1, jend
553     nTopoPairsForAtom(j) = 0
554     #ifdef IS_MPI
555     id1 = AtomRowToGlobal(j)
556     #else
557     id1 = j
558     #endif
559     do i = 1, CnOneTwo
560     if (ConeTwo(1,i) .eq. id1 ) then
561     nTopoPairsForAtom(j) = nTopoPairsForAtom(j) + 1
562     id2 = ConeTwo(2,i)
563     toposForAtom(j, nTopoPairsForAtom(j)) = id2
564     topoDistance(j, nTopoPairsForAtom(j)) = 1
565     endif
566     if (ConeTwo(2, i) .eq. id1 ) then
567     nTopoPairsForAtom(j) = nTopoPairsForAtom(j) + 1
568     id2 = ConeTwo(1,i)
569     toposForAtom(j, nTopoPairsForAtom(j)) = id2
570     topoDistance(j, nTopoPairsForAtom(j)) = 1
571     endif
572     end do
573 gezelter 507
574 gezelter 1286 do i = 1, CnOneThree
575     if (ConeThree(1,i) .eq. id1 ) then
576     nTopoPairsForAtom(j) = nTopoPairsForAtom(j) + 1
577     id2 = ConeThree(2,i)
578     toposForAtom(j, nTopoPairsForAtom(j)) = id2
579     topoDistance(j, nTopoPairsForAtom(j)) = 2
580     endif
581     if (ConeThree(2, i) .eq. id1 ) then
582     nTopoPairsForAtom(j) = nTopoPairsForAtom(j) + 1
583     id2 = ConeThree(1,i)
584     toposForAtom(j, nTopoPairsForAtom(j)) = id2
585     topoDistance(j, nTopoPairsForAtom(j)) = 2
586     endif
587     end do
588 gezelter 507
589 gezelter 1286 do i = 1, CnOneFour
590     if (ConeFour(1,i) .eq. id1 ) then
591     nTopoPairsForAtom(j) = nTopoPairsForAtom(j) + 1
592     id2 = ConeFour(2,i)
593     toposForAtom(j, nTopoPairsForAtom(j)) = id2
594     topoDistance(j, nTopoPairsForAtom(j)) = 3
595     endif
596     if (ConeFour(2, i) .eq. id1 ) then
597     nTopoPairsForAtom(j) = nTopoPairsForAtom(j) + 1
598     id2 = ConeFour(1,i)
599     toposForAtom(j, nTopoPairsForAtom(j)) = id2
600     topoDistance(j, nTopoPairsForAtom(j)) = 3
601     endif
602     end do
603     enddo
604 gezelter 507
605 gezelter 1286 call createSimHasAtype(alloc_stat)
606     if (alloc_stat /= 0) then
607     status = -1
608     end if
609    
610     if (status == 0) simulation_setup_complete = .true.
611    
612     end subroutine SimulationSetup
613 gezelter 115
614 gezelter 1286 subroutine setBox(cHmat, cHmatInv, cBoxIsOrthorhombic)
615     real(kind=dp), dimension(3,3) :: cHmat, cHmatInv
616     integer :: cBoxIsOrthorhombic
617     integer :: smallest, status
618    
619     Hmat = cHmat
620     HmatInv = cHmatInv
621     if (cBoxIsOrthorhombic .eq. 0 ) then
622     boxIsOrthorhombic = .false.
623     else
624     boxIsOrthorhombic = .true.
625     endif
626    
627     call checkBox()
628     return
629     end subroutine setBox
630    
631 gezelter 889 subroutine checkBox()
632    
633     integer :: i
634     real(kind=dp), dimension(3) :: hx, hy, hz, ax, ay, az, piped
635     character(len = statusMsgSize) :: errMsg
636    
637     hx = Hmat(1,:)
638     hy = Hmat(2,:)
639     hz = Hmat(3,:)
640    
641     ax = cross_product(hy, hz)
642     ay = cross_product(hx, hz)
643     az = cross_product(hx, hy)
644    
645     ax = ax / length(ax)
646     ay = ay / length(ay)
647     az = az / length(az)
648    
649     piped(1) = abs(dot_product(ax, hx))
650     piped(2) = abs(dot_product(ay, hy))
651     piped(3) = abs(dot_product(az, hz))
652    
653     do i = 1, 3
654     if ((0.5_dp * piped(i)).lt.DangerRcut) then
655     write(errMsg, '(a94,f9.4,a1)') 'One of the dimensions of the Periodic ' &
656     // 'Box is smaller than ' // newline // tab // &
657     'the largest cutoff radius' // &
658     ' (rCut = ', DangerRcut, ')'
659     call handleError("checkBox", errMsg)
660 chuckv 1135
661 gezelter 889 end if
662     enddo
663     return
664     end subroutine checkBox
665    
666 gezelter 507 function SimUsesPBC() result(doesit)
667     logical :: doesit
668     doesit = thisSim%SIM_uses_PBC
669     end function SimUsesPBC
670 gezelter 115
671 gezelter 1126 function SimUsesAtomicVirial() result(doesit)
672     logical :: doesit
673     doesit = thisSim%SIM_uses_AtomicVirial
674     end function SimUsesAtomicVirial
675    
676 gezelter 507 function SimUsesDirectionalAtoms() result(doesit)
677     logical :: doesit
678 chrisfen 523 doesit = thisSim%SIM_uses_dipoles .or. thisSim%SIM_uses_Sticky .or. &
679     thisSim%SIM_uses_StickyPower .or. &
680 gezelter 507 thisSim%SIM_uses_GayBerne .or. thisSim%SIM_uses_Shapes
681     end function SimUsesDirectionalAtoms
682 gezelter 115
683 gezelter 507 function SimUsesLennardJones() result(doesit)
684     logical :: doesit
685     doesit = thisSim%SIM_uses_LennardJones
686     end function SimUsesLennardJones
687 gezelter 140
688 gezelter 507 function SimUsesElectrostatics() result(doesit)
689     logical :: doesit
690     doesit = thisSim%SIM_uses_Electrostatics
691     end function SimUsesElectrostatics
692 gezelter 115
693 gezelter 507 function SimUsesCharges() result(doesit)
694     logical :: doesit
695     doesit = thisSim%SIM_uses_Charges
696     end function SimUsesCharges
697 gezelter 115
698 gezelter 507 function SimUsesDipoles() result(doesit)
699     logical :: doesit
700     doesit = thisSim%SIM_uses_Dipoles
701     end function SimUsesDipoles
702 gezelter 115
703 gezelter 507 function SimUsesSticky() result(doesit)
704     logical :: doesit
705     doesit = thisSim%SIM_uses_Sticky
706     end function SimUsesSticky
707 gezelter 115
708 chrisfen 523 function SimUsesStickyPower() result(doesit)
709     logical :: doesit
710     doesit = thisSim%SIM_uses_StickyPower
711     end function SimUsesStickyPower
712    
713 gezelter 507 function SimUsesGayBerne() result(doesit)
714     logical :: doesit
715     doesit = thisSim%SIM_uses_GayBerne
716     end function SimUsesGayBerne
717 gezelter 115
718 gezelter 507 function SimUsesEAM() result(doesit)
719     logical :: doesit
720     doesit = thisSim%SIM_uses_EAM
721     end function SimUsesEAM
722 gezelter 140
723 chuckv 733
724     function SimUsesSC() result(doesit)
725     logical :: doesit
726     doesit = thisSim%SIM_uses_SC
727     end function SimUsesSC
728    
729 chuckv 1162 function SimUsesMNM() result(doesit)
730 chuckv 733 logical :: doesit
731 chuckv 1162 doesit = thisSim%SIM_uses_MNM
732     end function SimUsesMNM
733 chuckv 733
734    
735 gezelter 507 function SimUsesShapes() result(doesit)
736     logical :: doesit
737     doesit = thisSim%SIM_uses_Shapes
738     end function SimUsesShapes
739 gezelter 140
740 gezelter 507 function SimUsesFLARB() result(doesit)
741     logical :: doesit
742     doesit = thisSim%SIM_uses_FLARB
743     end function SimUsesFLARB
744 gezelter 115
745 gezelter 507 function SimUsesRF() result(doesit)
746     logical :: doesit
747     doesit = thisSim%SIM_uses_RF
748     end function SimUsesRF
749 gezelter 115
750 chrisfen 719 function SimUsesSF() result(doesit)
751 chrisfen 703 logical :: doesit
752 chrisfen 719 doesit = thisSim%SIM_uses_SF
753     end function SimUsesSF
754 chrisfen 703
755 chrisfen 998 function SimUsesSP() result(doesit)
756     logical :: doesit
757     doesit = thisSim%SIM_uses_SP
758     end function SimUsesSP
759    
760     function SimUsesBoxDipole() result(doesit)
761     logical :: doesit
762     doesit = thisSim%SIM_uses_BoxDipole
763     end function SimUsesBoxDipole
764    
765 gezelter 507 function SimRequiresPrepairCalc() result(doesit)
766     logical :: doesit
767 chuckv 1162 doesit = thisSim%SIM_uses_EAM .or. thisSim%SIM_uses_SC
768 gezelter 507 end function SimRequiresPrepairCalc
769 chrisfen 691
770 gezelter 507 function SimRequiresPostpairCalc() result(doesit)
771     logical :: doesit
772 chrisfen 998 doesit = thisSim%SIM_uses_RF .or. thisSim%SIM_uses_SF &
773     .or. thisSim%SIM_uses_SP .or. thisSim%SIM_uses_BoxDipole
774 gezelter 507 end function SimRequiresPostpairCalc
775    
776 gezelter 575 ! Function returns true if the simulation has this atype
777 chuckv 563 function SimHasAtype(thisAtype) result(doesit)
778     logical :: doesit
779     integer :: thisAtype
780     doesit = .false.
781     if(.not.allocated(SimHasAtypeMap)) return
782    
783     doesit = SimHasAtypeMap(thisAtype)
784    
785     end function SimHasAtype
786    
787     subroutine createSimHasAtype(status)
788     integer, intent(out) :: status
789     integer :: alloc_stat
790     integer :: me_i
791     integer :: mpiErrors
792     integer :: nAtypes
793     status = 0
794    
795     nAtypes = getSize(atypes)
796     ! Setup logical map for atypes in simulation
797     if (.not.allocated(SimHasAtypeMap)) then
798     allocate(SimHasAtypeMap(nAtypes),stat=alloc_stat)
799     if (alloc_stat /= 0 ) then
800     status = -1
801     return
802     end if
803     SimHasAtypeMap = .false.
804     end if
805 chuckv 630
806 gezelter 575 ! Loop through the local atoms and grab the atypes present
807 chuckv 563 do me_i = 1,nLocal
808     SimHasAtypeMap(atid(me_i)) = .true.
809     end do
810 gezelter 575 ! For MPI, we need to know all possible atypes present in
811     ! simulation on all processors. Use LOR operation to set map.
812 chuckv 563 #ifdef IS_MPI
813 chuckv 630 if (.not.allocated(SimHasAtypeMapTemp)) then
814     allocate(SimHasAtypeMapTemp(nAtypes),stat=alloc_stat)
815     if (alloc_stat /= 0 ) then
816     status = -1
817     return
818     end if
819     end if
820     call mpi_allreduce(SimHasAtypeMap, SimHasAtypeMaptemp, nAtypes, &
821 gezelter 575 mpi_logical, MPI_LOR, mpi_comm_world, mpiErrors)
822 chuckv 630 simHasAtypeMap = simHasAtypeMapTemp
823     deallocate(simHasAtypeMapTemp)
824 gezelter 575 #endif
825 chuckv 563 end subroutine createSimHasAtype
826 gezelter 575
827 chuckv 563 subroutine InitializeSimGlobals(thisStat)
828 gezelter 507 integer, intent(out) :: thisStat
829     integer :: alloc_stat
830    
831     thisStat = 0
832    
833     call FreeSimGlobals()
834    
835 gezelter 1286 allocate(excludes(2,nExcludes), stat=alloc_stat)
836 gezelter 507 if (alloc_stat /= 0 ) then
837     thisStat = -1
838     return
839     endif
840    
841     allocate(molMembershipList(nGlobal), stat=alloc_stat)
842     if (alloc_stat /= 0 ) then
843     thisStat = -1
844     return
845     endif
846    
847     end subroutine InitializeSimGlobals
848    
849     subroutine FreeSimGlobals()
850    
851     !We free in the opposite order in which we allocate in.
852 gezelter 1286 if (allocated(topoDistance)) deallocate(topoDistance)
853     if (allocated(toposForAtom)) deallocate(toposForAtom)
854     if (allocated(nTopoPairsForAtom)) deallocate(nTopoPairsForAtom)
855 gezelter 507 if (allocated(skipsForAtom)) deallocate(skipsForAtom)
856     if (allocated(nSkipsForAtom)) deallocate(nSkipsForAtom)
857 gezelter 1286 if (allocated(skipsForAtom)) deallocate(skipsForAtom)
858     if (allocated(nSkipsForAtom)) deallocate(nSkipsForAtom)
859 gezelter 507 if (allocated(mfactLocal)) deallocate(mfactLocal)
860     if (allocated(mfactCol)) deallocate(mfactCol)
861     if (allocated(mfactRow)) deallocate(mfactRow)
862     if (allocated(groupListCol)) deallocate(groupListCol)
863     if (allocated(groupListRow)) deallocate(groupListRow)
864     if (allocated(groupStartCol)) deallocate(groupStartCol)
865     if (allocated(groupStartRow)) deallocate(groupStartRow)
866 gezelter 1286 if (allocated(molMembershipList)) deallocate(molMembershipList)
867     if (allocated(excludes)) deallocate(excludes)
868 gezelter 507
869     end subroutine FreeSimGlobals
870    
871     pure function getNlocal() result(n)
872     integer :: n
873     n = nLocal
874     end function getNlocal
875    
876 gezelter 889 subroutine setHmatDangerousRcutValue(dangerWillRobinson)
877     real(kind=dp), intent(in) :: dangerWillRobinson
878     DangerRcut = dangerWillRobinson
879 chuckv 563
880 gezelter 889 call checkBox()
881 chuckv 563
882 gezelter 889 return
883     end subroutine setHmatDangerousRcutValue
884 chuckv 563
885    
886 gezelter 889
887 gezelter 507 end module simulation