lammpskit.ecellmodel.plot_displacement_comparison

lammpskit.ecellmodel.plot_displacement_comparison(file_list, loop_start, loop_end, labels, analysis_name, repeat_count=0, output_dir=os.getcwd())[source]

Generate comparative displacement analysis for multi-species ion migration in HfTaO devices.

Processes multiple thermodynamic output files to extract and visualize final displacement patterns across different atomic species, experimental conditions, or temporal states. Provides comprehensive mobility characterization essential for understanding ion migration mechanisms, filament formation pathways, and electrochemical switching dynamics in resistive memory devices through spatial displacement profiling.

Parameters:
  • file_list (list of str) –

    List of file paths to LAMMPS thermodynamic output files containing spatially-binned displacement data. Each file represents a different analysis case (species, condition, or temporal state). Common examples:

    • Species Files: [“Hf_mobility.dat”, “Ta_mobility.dat”, “O_mobility.dat”]

    • Condition Files: [“low_field.dat”, “medium_field.dat”, “high_field.dat”]

    • Temporal Files: [“early.dat”, “middle.dat”, “late.dat”]

    Files must follow thermodynamic output format with consistent spatial binning.

  • loop_start (int) – Starting loop index (inclusive) for temporal analysis range. Corresponds to simulation timestep ranges or voltage cycle iterations. Minimum value: 0. Used to select specific time windows within displacement evolution data.

  • loop_end (int) – Ending loop index (inclusive) for temporal analysis range. Must be ≥ loop_start. Defines the final temporal point for displacement analysis.

  • labels (list of str) –

    Descriptive identifiers for each file in file_list, used in plot legends and output filenames. Must match file_list length. Examples:

    • Species Labels: [“Hf”, “Ta”, “O”] for multi-species comparison

    • Condition Labels: [“Low Field”, “High Field”] for parametric studies

    • State Labels: [“Initial”, “Intermediate”, “Final”] for temporal analysis

  • analysis_name (str) – Base identifier for output file naming and plot titles. Should describe the comparative analysis context. Examples: “species_mobility”, “field_dependence”, “temporal_evolution”

  • repeat_count (int, optional) – Number of times the first timestep is repeated in data files. Used for file format correction when initial conditions are duplicated. Default: 0.

  • output_dir (str, optional) – Directory path for saving generated displacement comparison plots. Default: current working directory. Creates directory if non-existent.

Returns:

displacement_figures – Dictionary of matplotlib Figure objects for comprehensive displacement analysis:

Z-Direction Analysis: - ‘z_displacement’: Signed z-displacement profiles showing migration direction - ‘z_magnitude’: Absolute z-displacement magnitude for migration extent analysis

Lateral Displacement Analysis: - ‘lateral_displacement’: Radial displacement patterns indicating spreading behavior

All figures include publication-ready formatting with comparative legends, axis labels, and consistent styling for multi-case analysis visualization.

Return type:

dict[str, plt.Figure]

Notes

Data Processing Methodology:

Final State Extraction: The function processes the last temporal frame (loop_end) from each file: ` z_displacement = data[file_index, -1, :, -3]      # Column -3: Z-displacement lateral_displacement = data[file_index, -1, :, -2] # Column -2: Lateral displacement bin_position = data[file_index, -1, :, 1]          # Column 1: Spatial position atom_count = data[file_index, -1, :, 2]            # Column 2: Atoms per bin `

Spatial Binning Framework: - Uniform z-direction discretization across electrode separation - Bin centers represent average displacement for contained atoms - Statistical significance ensured through atom count validation - Cross-file spatial alignment for comparative analysis

Performance Characteristics: - Memory Usage: O(N_files × N_loops × N_bins × N_columns) for data storage - Processing Speed: ~2-8s per file depending on loop range and bin count - Output Quality: Publication-ready SVG figures with comparative legends - Scalability: Efficient batch processing for parametric studies

Integration with LAMMPSKit Analysis Pipeline: - Data Reading: Uses read_displacement_data() for robust file parsing - Visualization: Leverages plot_multiple_cases() for comparative plotting - Error Handling: Inherits validation from displacement data reading functions - Workflow Integration: Compatible with plot_displacement_timeseries() analysis

Examples

Multi-species mobility comparison:

>>> from lammpskit.ecellmodel.filament_layer_analysis import plot_displacement_comparison
>>> # Compare displacement patterns of different atomic species
>>> mobility_files = ["Hf_mobility.dat", "Ta_mobility.dat", "O_mobility.dat"]
>>> species_labels = ["Hf", "Ta", "O"]
>>>
>>> displacement_figures = plot_displacement_comparison(mobility_files,
...                                                   loop_start=0, loop_end=99,
...                                                   labels=species_labels,
...                                                   analysis_name="species_mobility")
>>> print(f"Generated {len(displacement_figures)} displacement comparison plots")
>>>
>>> # Analyze species-specific migration behavior
>>> z_disp_fig = displacement_figures['z_displacement']      # Migration direction
>>> lateral_fig = displacement_figures['lateral_displacement'] # Spreading behavior
>>> magnitude_fig = displacement_figures['z_magnitude']       # Migration extent

Field-dependent displacement analysis:

>>> # Parametric study of electric field effects on mobility
>>> field_files = ["low_field_Hf.dat", "medium_field_Hf.dat", "high_field_Hf.dat"]
>>> field_labels = ["Low Field", "Medium Field", "High Field"]
>>>
>>> field_displacement = plot_displacement_comparison(field_files,
...                                                 loop_start=50, loop_end=150,
...                                                 labels=field_labels,
...                                                 analysis_name="field_dependence",
...                                                 output_dir="./field_study")
>>>
>>> print("Field-dependent mobility analysis completed")
>>> print("Available plots:", list(field_displacement.keys()))

Temporal evolution analysis:

>>> # Time-resolved displacement evolution study
>>> temporal_files = ["early_mobility.dat", "mid_mobility.dat", "late_mobility.dat"]
>>> time_labels = ["Early (0-100ps)", "Mid (500-600ps)", "Late (1900-2000ps)"]
>>>
>>> temporal_analysis = plot_displacement_comparison(temporal_files,
...                                                loop_start=0, loop_end=50,
...                                                labels=time_labels,
...                                                analysis_name="temporal_evolution")
>>>
>>> # Examine long-term migration trends
>>> z_evolution = temporal_analysis['z_displacement']
>>> lateral_evolution = temporal_analysis['lateral_displacement']
>>> print("Temporal displacement evolution analysis completed")

Device condition comparison:

>>> # Compare displacement under different device conditions
>>> condition_files = ["pristine_mobility.dat", "cycled_mobility.dat", "degraded_mobility.dat"]
>>> condition_labels = ["Pristine", "After 1000 Cycles", "Degraded"]
>>>
>>> condition_analysis = plot_displacement_comparison(condition_files,
...                                                 loop_start=80, loop_end=120,
...                                                 labels=condition_labels,
...                                                 analysis_name="device_degradation")
>>>
>>> print("Device condition comparison completed")

Comprehensive multi-case analysis:

>>> # Large-scale comparative study with multiple parameters
>>> import os
>>> analysis_cases = {
...     "species_comparison": {
...         "files": ["Hf_mobility.dat", "Ta_mobility.dat", "O_mobility.dat"],
...         "labels": ["Hf", "Ta", "O"]
...     },
...     "voltage_dependence": {
...         "files": ["1V_mobility.dat", "2V_mobility.dat", "3V_mobility.dat"],
...         "labels": ["1V", "2V", "3V"]
...     },
...     "temperature_effects": {
...         "files": ["300K_mobility.dat", "400K_mobility.dat", "500K_mobility.dat"],
...         "labels": ["300K", "400K", "500K"]
...     }
... }
>>>
>>> all_displacement_analyses = {}
>>> for case_name, case_params in analysis_cases.items():
...     try:
...         if all(os.path.exists(f) for f in case_params["files"]):
...             figures = plot_displacement_comparison(case_params["files"],
...                                                   loop_start=0, loop_end=75,
...                                                   labels=case_params["labels"],
...                                                   analysis_name=case_name,
...                                                   output_dir=f"./analysis_{case_name}")
...             all_displacement_analyses[case_name] = figures
...             print(f"Completed {case_name}: {len(figures)} figures")
...         else:
...             print(f"Missing files for {case_name}")
...     except Exception as e:
...         print(f"Error in {case_name}: {e}")
>>>
>>> total_figures = sum(len(figs) for figs in all_displacement_analyses.values())
>>> print(f"Total displacement analyses: {total_figures} figures across {len(all_displacement_analyses)} cases")

Advanced data extraction and analysis:

>>> # Detailed analysis of displacement patterns
>>> mobility_files = ["oxygen_mobility.dat"]
>>> labels = ["O Mobility"]
>>>
>>> displacement_data = plot_displacement_comparison(mobility_files, 0, 50, labels,
...                                                "detailed_oxygen_analysis")
>>>
>>> # Access raw displacement data for further analysis
>>> print("Available displacement analyses:", list(displacement_data.keys()))
>>>
>>> # Examine displacement characteristics
>>> # Note: To access raw data, you would typically use read_displacement_data directly
>>> from lammpskit.ecellmodel.filament_layer_analysis import read_displacement_data
>>> raw_data = read_displacement_data("oxygen_mobility.dat", 0, 50)
>>> final_frame = raw_data[-1]  # Last temporal frame
>>>
>>> z_positions = final_frame[:, 1]        # Spatial bin centers
>>> z_displacements = final_frame[:, -3]   # Z-direction displacements
>>> lateral_displacements = final_frame[:, -2]  # Lateral displacements
>>>
>>> print(f"Spatial resolution: {z_positions[1] - z_positions[0]:.2f} Å")
>>> print(f"Max z-displacement: {z_displacements.max():.3f} Å")
>>> print(f"Max lateral displacement: {lateral_displacements.max():.3f} Å")

Error handling and validation:

>>> # Robust displacement analysis with comprehensive error handling
>>> mobility_files = ["species1.dat", "species2.dat", "species3.dat"]
>>> species_labels = ["Species1", "Species2", "Species3"]
>>>
>>> try:
...     # Validate file existence before analysis
...     existing_files = [f for f in mobility_files if os.path.exists(f)]
...     existing_labels = [species_labels[i] for i, f in enumerate(mobility_files) if os.path.exists(f)]
...
...     if len(existing_files) >= 2:  # Require at least 2 files for comparison
...         displacement_figures = plot_displacement_comparison(existing_files,
...                                                           loop_start=0, loop_end=100,
...                                                           labels=existing_labels,
...                                                           analysis_name="validated_comparison")
...         print(f"Successfully analyzed {len(existing_files)} displacement files")
...     else:
...         print("Insufficient files for comparative analysis")
... except FileNotFoundError as e:
...     print(f"File access error: {e}")
... except ValueError as e:
...     print(f"Data format error: {e}")
... except Exception as e:
...     print(f"Analysis error: {e}")

Integration with other LAMMPSKit functions:

>>> # Combine displacement comparison with time series analysis
>>> from lammpskit.ecellmodel.filament_layer_analysis import plot_displacement_timeseries
>>>
>>> # Step 1: Comparative final displacement analysis
>>> comparative_files = ["condition_A.dat", "condition_B.dat"]
>>> comparative_labels = ["Condition A", "Condition B"]
>>>
>>> final_displacement = plot_displacement_comparison(comparative_files, 0, 100,
...                                                 comparative_labels, "comparison_study")
>>>
>>> # Step 2: Detailed time series for selected condition
>>> time_series = plot_displacement_timeseries(["condition_A.dat"], 0, 100, ["Condition A"],
...                                          "detailed_timeseries", time_step=0.0002,
...                                          dump_interval_steps=5000)
>>>
>>> print("Comprehensive displacement analysis completed:")
>>> print(f"  Comparative analysis: {len(final_displacement)} figures")
>>> print(f"  Time series analysis: {len(time_series)} figures")