Skip to content

Action surface tension - #1189

Merged
drroe merged 18 commits into
Amber-MD:masterfrom
ndlevinzon:action-surface_tension
Sep 3, 2026
Merged

drroe merged 18 commits into
Amber-MD:masterfrom
ndlevinzon:action-surface_tension

Conversation

@ndlevinzon

Copy link
Copy Markdown
Contributor

Changelog: surftension Action

Branch: action-surface_tension
Started: 2026-08-31
Target version: V7.11.0
Author: Nathan D Levinzon ndlevinzon@gmail.com

Working log for the capillary-wave surface-tension Action.


ChangeLog.v7.md (landed)

New command surftension added under New Commands. Internal version V7.11.0.

surftension [<name>] <mask> [mask2 <mask2>] temp <T>
  [normal {x|y|z}] [nsurf {1|2}] [side {upper|lower}]
  [interface {willard|itim}]
  [gridspacing <d>] [dz <d> | dnormal <d>]
  [sigmaxy <d>] [sigmaz <d> | sigmanormal <d>]
  [bulkhalfwidth <d>] [threshold <frac>]
  [qmin <q>] [qmax <q>] [lx <Lx>] [ly <Ly>] [lz <Lz>]
  [nblock <frames>] [dt <ps>] [blocktime <ps>]
  [out <file> | spectrumout <file>] [roughout <file>] [blockout <file>]
  [summaryout <file>]
  [spectrumagr <file>] [roughagr <file>] [blockagr <file>]
  [spectrumgnu <file>] [roughgnu <file>] [blockgnu <file>]

Files changed

File Change
src/Action_SurfaceTension.h New Action class; MPI SyncAction / trajComm_
src/Action_SurfaceTension.cpp Init / Setup / DoAction / Print / SyncAction + helpers
src/Command.cpp #include and AddCmd(..., "surftension")
src/cpptrajfiles Action_SurfaceTension.cpp in COMMON_SOURCES
src/cpptrajheaders Install header for libcpptraj
src/Version.h V7.10.0 → V7.11.0
doc/ChangeLog.v7.md New Commands entry
test/Test_SurfTension/RunTest.sh Help + smoke test
test/Makefile test.surftension target

Development log

2026-08-31

  • Created this changelog on branch action-surface_tension before any Action source.
  • Implemented Action_SurfaceTension: z-slab capillary-wave γ from Gaussian-smoothed
    density interfaces, 2D DFT height spectrum, q-shell averaging, optional *out files.
  • Wired surftension in Command.cpp and cpptrajfiles.
  • Bumped version to V7.11.0; documented in ChangeLog.v7.md.
  • Added test/Test_SurfTension smoke test (help + 1-frame Init/Setup).
  • NVT (fixed Lx, Ly). No plots.
  • MPI SyncAction: packed ReduceMaster SUM of the three |h_q|² spectra
    (Radial-style). Frame counts / leftover nblock frames AllReduce SUM;
    nx, ny, |q|, Lx, Ly AllReduce/ReduceMaster MAX so empty ranks (zeros) do
    not clobber. Roughness and block DataSets keep default concat sync.
    nblock is per-rank. Print block SEM uses block_gamma_->Size() after
    DataSet sync, not the master's local n_blocks_.
  • interface {willard|itim}: default Willard-Chandler is the existing Gaussian
    density isosurface. itim is per-column min/max of <mask>, split at Lz/2
    after circular recenter (empty half-column skips the frame). dz / Gaussian
    / threshold apply only to Willard-Chandler.
  • OpenMP on the 2-D DFT (ST_HeightPower): flattened (kx, ky) loop with
    schedule(dynamic), same style as radial / rms2d (no collapse()).
  • OpenMP on the 3-D Gaussian filter: one parallel region, three separable
    passes; each 1-D line is an independent omp for with thread-local buffers.
  • Grace (xmgrace) and gnuplot DataFile writers: *out uses the extension
    (.agr/.xmgr, .gnu); spectrumagr/spectrumgnu (and rough/block)
    force the format. Spectrum meshes get xlabel q (Ang^-1).
  • Bending modulus κ: Helfrich linear fit of 1/(q² S) vs q² on [qmin,qmax]
    (≥ 3 shells). Reports κ in kT (and J); kappaq / kappaqtop / kappaqbot
    vs q; bkappa with nblock. Plateau γ is unchanged (Python).
  • normal {x|y|z} (default z): permute Cartesian coordinates into
    (lateral 1, lateral 2, normal) before wrap / circular recenter / Willard /
    ITIM / DFT. Freeze lateral lengths only (NVT). Area = Lt1×Lt2.
    lx/ly/lz override Cartesian box lengths. dnormal ≡ dz,
    sigmanormal ≡ sigmaz (error if both given and they differ).
    Init/Print report e.g. Slab normal: z (interface plane x-y). Warns on
    non-orthogonal boxes.
  • Height-field 2-D FFT uses cpptraj PubFFT (row-column 1-D FFTs), then
    divides by nx*ny (numpy fft2 convention). Same S(q) as the old
    direct DFT. Per-block γ/κ print in Print(), not during the frame loop.
  • Default qmin is the smallest fundamental wavevector from the unit-cell
    laterals, 2π/max(Lt1,Lt2), set on the first good frame. Both 2π/Lt1
    and 2π/Lt2 are printed. summaryout writes a parseable key/value file
    (γ, κ, roughness, q window, box, frames). Skip-frame warnings are capped
    at 5. blocktime (ps) with dt (analyzed-frame spacing) sets nblock.
    Output directories are not created; the user must give existing paths.
  • nsurf {1|2} (default 2, vacuum or a second phase on both sides of the
    film). nsurf 1 with side {upper|lower} uses one interface. mask2
    is a second mask for the lower surface (leaflet / liquid–liquid); the
    upper surface then comes from <mask> with no mid-box split. Both
    masks share one circular recenter so the film is not split apart.
  • out is an alias for spectrumout. Init now errors if an *out path
    names a directory that does not exist (DataFiles are opened only after
    run, which previously lost a full trajectory write).

Not in this change

  • ITIM probe-sphere radius (min/max is the probe → 0 limit)
  • Numeric regression vs a water-slab trajectory (no slab traj in the test suite yet)

… of a liquid slab

- Introduced the 'surftension' command with detailed options for calculating surface tension based on height fluctuations.
- Updated ChangeLog to reflect the new command and its usage.
- Registered the command in Command.cpp and included necessary source and header files.
- Added a test target for 'surftension' in the Makefile and included it in the complete tests list.
- Bumped version to 7.11.0 to signify the addition of this new functionality.
…nd consistency

- Updated log messages to improve readability, changing "bins along" to "bins along" for better context.
- Enhanced output in the Print function to include completed block information, displaying gamma, kappa, and roughness more clearly.
- Removed redundant error message logging for kappa when it is not applicable.
- Adjusted variable names in output for consistency with other parts of the code.
- Introduced a new HeightPower function that computes the 2-D FFT of height fields using cpptraj's PubFFT, matching numpy's fft2 convention.
- Updated ChangeLog to reflect the new FFT implementation and its usage.
- Adjusted output messages to include details about the new FFT method.
- Removed the old direct DFT implementation for height power spectrum calculation.
- Updated the 'surftension' command to support an additional mask for lower surfaces, allowing for single or double interface configurations.
- Introduced new parameters: 'nsurf' to specify the number of interfaces, 'side' to select the interface for single interface cases, and 'summaryout' for outputting a key/value summary file.
- Adjusted the default behavior for 'qmin' and added 'blocktime' and 'dt' parameters for better control over analysis.
- Enhanced documentation in ChangeLog to reflect these changes and added tests for new functionalities in the RunTest script.
- Bumped version to 7.11.0 to signify the addition of these features.
- Changed the 'spectrumout' parameter to be aliased as 'out' for simplified usage.
- Implemented error handling in the initialization phase to ensure that the parent directory for output files exists, preventing loss of data during long trajectory writes.
- Updated documentation in ChangeLog to reflect these changes and clarify output file handling.
- Updated author name formatting for consistency.
- Corrected mathematical symbols in comments for clarity, including replacing "n" with "−n" and "≤" with "≤".
- Enhanced descriptions of functions and parameters to improve understanding of the capillary-wave theory and its implementation.
- Adjusted comments to reflect accurate mathematical expressions and units, ensuring clarity in the context of surface tension calculations.
- Improved overall readability of the code documentation.
…tail

- Expanded comments to provide a clearer understanding of the capillary-wave surface tension calculations and the per-frame processing pipeline.
- Improved descriptions of functions, parameters, and mathematical expressions to ensure accuracy and readability.
- Updated variable and function comments to reflect consistent terminology and units, enhancing overall documentation quality.
… checks

- Introduced a static inline function, ST_Finite, to determine if a given double value is finite (not NaN or ±Inf).
- This addition enhances the robustness of numerical calculations by providing a utility for validating input values in surface tension computations.
- Renamed 'q_fund_' to 'q_fundamental_' to better reflect its purpose as 2π / max(L₁, L₂) from the first good frame.
- This change enhances code readability and maintains consistency in terminology.
…for improved clarity

- Updated the initialization of gamma and kappa variables to use ST_NaN() for better handling of uninitialized values.
- This change enhances code readability and ensures that variables are explicitly set to a known state before use.
…ith Action_SurfaceTension.h

- Introduced the 'surftension' command to maintain consistency with the Action_SurfaceTension.h file.
- Added comments to clarify the need for synchronization due to the standalone Makefile's lack of header dependencies, preventing potential issues with stale object files.
@drroe

drroe commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Thanks for this! Make sure you update the dependencies by running make depend in the src subdirectory, then committing the changes to the cpptrajdepend file.

I have some questions about the tests. Typically the goal is to make sure the output from an Action stays consistent throughout any code changes. The tests should check as much of the functionality as possible; this is particularly important for downstream affects. For example, since this Action makes use of the PubFFT class, changes to that class could potentially adversely affect this Action's output, so we want to make sure we have a set of "good" outputs for surftension.

These comments pertain to the tests you added in test/Test_SurfTension.

  1. RunTest.sh should be made executable.
  2. There is no need to test whether "help" works, so you can omit that first test.
  3. The remaining tests don't actually seem to execute:
  CPPTRAJ: surftension smoke (Init/Setup)
Error: surftension: No frames were analyzed (1 skipped).

  CPPTRAJ: surftension smoke (interface itim)
Error: surftension: No frames were analyzed (1 skipped).

  CPPTRAJ: surftension smoke (normal x)
Error: surftension: No frames were analyzed (1 skipped).

  CPPTRAJ: surftension smoke (normal y, dnormal alias)
Error: surftension: No frames were analyzed (1 skipped).

  CPPTRAJ: surftension smoke (nsurf 1)
Error: surftension: No frames were analyzed (1 skipped).

  CPPTRAJ: surftension smoke (mask2, summaryout, blocktime)
Error: surftension: No frames were analyzed (1 skipped).
  1. There is currently no test output to compare to. From a cursory reading of the code it seems like at least summaryout should be specified so that output can be compared to a saved output file using the DoTest function from MasterTest.sh.

Another general comment: it looks like there are several files with hardcoded names, e.g.:

  DataFile* roughFile    = init.DFL().AddDataFile(actionArgs.GetStringKey("roughout"), actionArgs);
  DataFile* blockFile    = init.DFL().AddDataFile(actionArgs.GetStringKey("blockout"), actionArgs);
  DataFile* spectrumAgr  = init.DFL().AddDataFile(actionArgs.GetStringKey("spectrumagr"), actionArgs, DataFile::XMGRACE);

it might be best to give users an option to add a prefix to these files in case they want multiple runs in the same directory, e.g.

  std::string Fprefix = actionArgs.GetStringKey("fprefix", "ST");
  DataFile* roughFile    = init.DFL().AddDataFile(FileName(actionArgs.GetStringKey("roughout")).PrependFileName(Fprefix), actionArgs);

Last, it would be good to add a manual entry for this command, or if it's not ready for general consumption you can "hide" it (i.e. have it not show up in the online help) by adding SetHidden(true); to the Constructor.

Let me know if you have any questions!

… output files

- Modified the script to use a cubic lattice of O atoms for testing surface tension.
- Updated input files and commands for Willard-Chandler, ITIM, normal x, normal y, and nsurf 1 tests.
- Added summary output files for each test case to enhance result tracking and analysis.
- Removed obsolete smoke test sections to streamline the testing process.
…umentation updates

- Added 'fprefix' parameter to prepend a specified prefix to output file names, allowing for better organization of results.
- Updated documentation in Action_SurfaceTension and ChangeLog to reflect the new 'fprefix' functionality and its usage.
- Improved error handling for parent directory checks to ensure output files are correctly managed during execution.
- Enhanced RunTest.sh documentation to clarify the characteristics of slab.pdb.
- Updated surface tension data files with new gamma and roughness values for better simulation fidelity.
- Adjusted parameters in st.itim.dat.save, st.normalx.dat.save, st.normaly.dat.save, st.nsurf1.dat.save, st.willard.dat.save, and st2_summary.dat.save to reflect recent findings and improve test results.
- Included Nathan D. Levinzon (University of Utah, UT) as a contributor for the 'Action\surftension' implementation.
- This update acknowledges contributions and enhances the documentation of the project.
…ension tests

- Enhanced RunTest.sh to support dual frame analysis for both serial and MPI executions, ensuring consistent results across different ranks.
- Updated input parameters in st.itim.dat.save, st.normalx.dat.save, st.normaly.dat.save, st.nsurf1.dat.save, st.willard.dat.save, and st2_summary.dat.save to reflect the change from 1 to 2 frames, improving the accuracy of simulation outputs.
@drroe

drroe commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Looks like the CI framework is having some issues. I'll try rerunning in a few hours.

@drroe
drroe merged commit 8692b99 into Amber-MD:master Sep 3, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants