This repository presents a reproducible workflow for fitting the Linear Second-order Fractional (LSF) model to mastercurves of thermoplastic polymers.
The dataset is associated with the publication Fauser et al. (2025) and complements the dataset Data Sets for a Fractional Moisture-Dependent Viscoelasticity Model for Thermoplastic Polymers.
The LSF model effectively captures the broad relaxation spectra typical of polymers, but its interdependent parameters require robust non-linear optimization. To ensure clarity and maintainability, the fitting workflow is organized into three modular components: Viscoelastic Models Class (models.py) Configuration File (configuration_file.py) Model Fitting Notebook (main.ipynb)
- Viscoelastic Models Class (models.py) This module serves as the core library of constitutive models. Each model is implemented as a self-contained, object-oriented class. Purpose Encapsulate mathematical definitions of viscoelastic models, enabling modular extensions and reuse. Key Component: The LSF Model The Second-Order Fractional (LSF) model is defined by its complex modulus:
E*(ω) = (Ξ₀ + (iω)^α₁ Ξ₁ + (iω)^α₂ Ξ₂) / (Λ₀ + (iω)^α₁ Λ₁ + (iω)^α₂ Λ₂)
Parameters:
Ξ₀, Ξ₁, Ξ₂ → strain-related coefficients
Λ₀, Λ₁, Λ₂ → stress-related coefficients
α₁, α₂ → fractional exponents
Parent Class: ViscoelasticityModel
Defines methods for computing the real/imaginary parts of the complex modulus, as well as the storage modulus, loss modulus, and loss factor:
class ViscoelasticityModel(torch.nn.Module):
"""
Parent class for viscoelasticity models
"""
def init(self):
super().init()
def complexModulus(self, w):
raise Exception
def forward(self, w):
comp = self.complexModulus(w)
return comp.imag / comp.real
def storageModulus(self,w):
comp = self.complexModulus(w)
return comp.real
def lossModulus(self,w):
comp = self.complexModulus(w)
return comp.imag
Subclass: SecondOrderFractionalDerivativeModel Implements the LSF model, with parameters represented as torch.nn.Parameter for optimization. A scaling factor normalizes experimental and model data for stability.
class SecondOrderFractionalDerivativeModel(ViscoelasticityModel):
"""
Class for a second order derivative model
(G0 + d/dt^alpha G1 + d/dt^beta G2) stress
= (E0 + d/dt^alpha E1 + d/dt^beta E2) strain
"""
def init(self,E0,E1,E2,G0,G1,G2,alpha,beta):
super().init()
self.E0 = torch.nn.Parameter(E0 * torch.ones(1, dtype=torch.float64))
self.E1 = torch.nn.Parameter(E1 * torch.ones(1, dtype=torch.float64))
self.E2 = torch.nn.Parameter(E2 * torch.ones(1, dtype=torch.float64))
# normalize G0 to 1, G0 is not fitted
self.G0 = 1 * torch.ones(1, dtype=torch.float64)
self.G1 = torch.nn.Parameter(G1 * torch.ones(1, dtype=torch.float64))
self.G2 = torch.nn.Parameter(G2 * torch.ones(1, dtype=torch.float64))
self.alpha1 = torch.nn.Parameter(alpha * torch.ones(1, dtype=torch.float64))
self.alpha2 = torch.nn.Parameter(beta * torch.ones(1, dtype=torch.float64))
def complexModulus(self, w):
w = w[:,None]
iw = torch.view_as_complex(torch.cat((torch.zeros(w.size()),w),1))
iw_alpha1 = iw ** self.alpha1
iw_alpha2 = iw ** self.alpha2
comp = ((self.E0 + self.E1 * iw_alpha1 + self.E2 * iw_alpha2)
/ (self.G0 + self.G1 * self.E1 * iw_alpha1 + self.G2 * self.E2 * iw_alpha2))
return comp
- Configuration File (configuration_file.py)
This module centralizes all hyperparameters for non-linear optimization. Separating configuration ensures reproducibility, readability, and simplified parameter tuning.
Example
def get_diaplex_50_optimization_params():
dict = {}
dict["lr"] = 1e-3
dict["n_iter"] = 40000
dict["data_range"] = [5e-6,1e4]
dict["w_threshold"] = 0.0032
dict["w_left"] = 1
dict["w_right"] = 2
dict["criterion"] = torch.nn.MSELoss(reduction="sum")
return dict
Key Parameters lr → learning rate for Adam optimizer n_iter → number of optimization iterations data_range → frequency range for fitting w_threshold → frequency of peak loss factor w_left, w_right → weighting around w_threshold criterion → loss function (L2 norm)
- Model Fitting (main.ipynb)
The Jupyter notebook orchestrates the full workflow for fitting fractional viscoelastic models to experimental mechanical data.
It performs data loading, preprocessing, model definition, and optimization of material parameters using Adam optimizer.
Workflow Overview
Load configuration and utilities
Imports helper functions and parameters from configuration_file.py:
get_diaplex_filenames() — returns paths to experimental CSV data.
get_diaplex_50_optimization_params() — provides hyperparameters (learning rate, iteration count, weighting, etc.).
Initializes the fractional viscoelastic model SecondOrderFractionalDerivativeModel for each dataset.
Load and preprocess experimental data
Reads CSV files, extracts and sorts:
Extensional Reduced Frequency
Extensional Storage Modulus (E′)
Extensional Loss Modulus (E″)
Data are converted to PyTorch tensors for GPU-based optimization.
Define training configuration
For each dataset:
Finds the frequency corresponding to the loss peak (tan δ = E″/E′).
Loads optimization settings: criterion, lr, n_iter, w_left, w_right, and data_range.
Computes data_scaling to weight frequency ranges differently around the loss peak.
Optimization Loop
for t in tqdm(range(n_iter)):
pred = models[key](angfreq[key][indices[key]])
meas = ((lossmod[key])/(stormod[key]))[indices[key]]
loss = criterion(meas/meas * data_scaling, pred/meas * data_scaling)
optimizer.zero_grad()
loss.backward()
optimizer.step()
The optimization minimizes the difference between measured and predicted loss factor (tan δ).
Weighting (w_left, w_right) emphasizes frequencies below or above the loss peak for improved robustness.
Convergence depends strongly on initial guesses, data range, and learning rate.
Visualization and Output
After convergence, the notebook produces log–log plots comparing model predictions and measurements:
Loss factor (tan δ)
Storage modulus (E′)
Figures are saved as _fig_loss_factor.pdf and _fig_storage_modulus.pdf, ready for publication.
Key Notes
Convergence sensitivity: Good initial parameter guesses and suitable step sizes are essential.
Weighting strategy: Improves robustness near the loss peak, particularly for noisy data.
Modular design: New datasets or model variants can be added easily through configuration files.
- Fitted Parameters
In addition to the Python scripts for non-linear optimization, this repository also provides the fitted parameters of each master curve. These parameters, published in the related dataset
(Data Sets for a Fractional Moisture-Dependent Viscoelasticity Model for Thermoplastic Polymers), are available for both the LSF model and the Generalized Maxwell model.