Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mdstep refactor #108

Merged
merged 5 commits into from
Apr 7, 2022
Merged

Mdstep refactor #108

merged 5 commits into from
Apr 7, 2022

Conversation

danielhollas
Copy link
Contributor

@danielhollas danielhollas commented Apr 3, 2022

Trying to move more stuff out of the big init subroutine into smaller chunks.

I also wanted to make a nice interface to various integrators. I am hitting a problem here that various integrators have slightly different interface, e.g. some of them need extra force arrays. This problem in general and different ways to solve it are outlined here:
https://fortran-lang.org/learn/best_practices/type_casting

Even before this refactor this problem manifested for the MTS RESPA (doublerespastep()) integrator, where we have additional forces fx_diff, which we do not pass in as arguments but import them from global module. This is equivalent to approach no. 3 from the link above, and I have utilized this approach for the other integrators as well so that I could make a minimal common interface (see top of mdstep module). Long terms it would be nice to define our own derive types that would hold the simulation state and that we could pass explicitly into all functions (approach no. 2). I have outline how that could look in #107.

There are couple more unrelated refactors, mostly to pass data explicitly via subroutine arguments, instead of importing them from modules. This makes it more clear what depends on what.

@danielhollas danielhollas added the refactor No functional changes, just refactoring or cleaning up the code. label Apr 3, 2022
@danielhollas danielhollas self-assigned this Apr 3, 2022
@@ -276,77 +276,3 @@ subroutine force_quantum(fx, fy, fz, x, y, z, amg, quantum_energy)
quantum_energy = equant
end subroutine force_quantum

! Based on:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to mdstep.F90

@@ -206,15 +219,6 @@ subroutine initialize_pi_masses(amg, amt)
! write(*,*)'amg2',(amg(iat,iw)*2*sin(pi*(iw-1)/nwalk),iw=1,nwalk)
end if
end do

else if (inormalmodes == 1) then
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This case is covered by default, see top of the function

@codecov
Copy link

codecov bot commented Apr 3, 2022

Codecov Report

Merging #108 (3135eb8) into master (71c3e61) will decrease coverage by 0.11%.
The diff coverage is 97.84%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #108      +/-   ##
==========================================
- Coverage   87.08%   86.96%   -0.12%     
==========================================
  Files          41       42       +1     
  Lines        5805     5815      +10     
==========================================
+ Hits         5055     5057       +2     
- Misses        750      758       +8     
Impacted Files Coverage Δ
src/ekin.F90 100.00% <ø> (ø)
src/en_restraint.F90 0.00% <ø> (ø)
src/forces.F90 96.66% <ø> (-0.77%) ⬇️
src/plumed.F90 97.01% <ø> (ø)
src/mdstep.F90 98.12% <96.05%> (-1.88%) ⬇️
src/abin.F90 91.47% <100.00%> (+0.13%) ⬆️
src/analysis.F90 96.85% <100.00%> (ø)
src/force_terash.F90 94.85% <100.00%> (ø)
src/gle.F90 97.92% <100.00%> (ø)
src/init.F90 69.19% <100.00%> (-0.97%) ⬇️
... and 4 more

end select

sim_time = sim_time + dt
! PROPAGATE through one time step
Copy link
Contributor Author

@danielhollas danielhollas Apr 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's the nice part enabled by this refactor.

! nstep_ref - internal steps with reference potential pot_ref
integer, public :: nstep_ref = 1

abstract interface
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gettting a bit fancy here, here's a nice explanation:
https://fortran-lang.org/learn/best_practices/callbacks

Copy link
Contributor

@suchanj suchanj Apr 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a cool trick. 'Hello pointers my old friend.'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. The good thing here is that the logic for selecting the integrator is localized in one place, whereas before it was both in init.F90 and abin.F90.

@danielhollas danielhollas marked this pull request as ready for review April 4, 2022 00:09
allocate (ishake2(natom * 3 - 6))
ishake1 = 0
ishake2 = 0
allocate (ishake1(natom * 3 - 6), source=0)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New trick, allocation and initialization in one statement.

call finish(0)

call cpu_time(total_cpu_time)
write (stdout, '(A)') 'Total cpu time [s] (does not include ab initio calculations)'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the CPU time printing, because it's not indicative of anything as it does not account for external program execution.

@danielhollas danielhollas changed the title WIP: Mdstep refactor Mdstep refactor Apr 6, 2022
@danielhollas danielhollas requested a review from suchanj April 6, 2022 17:03
use mod_system, only: am
use mod_sh, only: en_array
use mod_terampi_sh, only: force_terash
real(DP), intent(inout) :: x(:, :), y(:, :), z(:, :)
! TODO: Eclas is not modified in this routine, but probably should be
real(DP), intent(inout) :: eclas
real(DP), intent(inout) :: px(:, :), py(:, :), pz(:, :)
! DH: I am surprised this works, since natom is not a constant
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw do you have the answer why this works? Maybe the variable is initialized once the subroutine is called and at that time the natom is known?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly. These are so called automatic arrays that get allocated on the stack when the function is called.
Instead of relying on the global natom variable, a slightly better way would be to use the size() intrinsic to get the size of the input arrays, like this:

real(DP) :: a(size(x, 1), size(x, 2))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The disadvantage in comparision to allocatable arrays that are allocated on the heap is that stack size is usually limited. So if we were simulating big system, we might get a segfault / stack overflow. So in general manually allocating arrays of size (natom, nwalk) is probably a bit better for the future.

On Unix, the stack size can be increased by

ulimit -s unlimited

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, reading that SO link I posted above, looks like whether automatic arrays are placed on the stack or on the heap depends on the compiler and compiler options. So if this ever became an issue in the future, tweaking compiler options would solve it.

@danielhollas danielhollas merged commit 3396c96 into master Apr 7, 2022
@danielhollas danielhollas deleted the mdstep-refactor branch April 7, 2022 08:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
refactor No functional changes, just refactoring or cleaning up the code.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants