image0

Case Studies: Copolymers

There are many challenges to studying copolymer systems with PRISM with the primary challenge being that PRISM cannot describe the phase-separated state, which is often of primary interest. Furthermore, due to the vast array of chain architectures, compositions, sequences, and chemistries that can be synthetically incorporated into block copolymers, analytical \(\hat{\omega}(k)\) are unlikely to be available for every system of interest. Despite this, many authors have used PRISM to study the disorded (mixed) state and to probe details about the spinodal phase transition.

Concepts

  • Multicomponent PRISM
  • Heterogeneous interactions
  • Complex Molecular Structure
  • Simulation derived \(\hat{\omega}(k)\)

Tools

  • pyPRISM.calculate.structure_factor

References

  1. Ivan Lyubimov, Daniel J. Beltran-Villegas, and Arthi Jayaraman; PRISM Theory Study of Amphiphilic Block Copolymer Solutions with Varying Copolymer Sequence and Composition, Macromolecules, 2017, 50 (18), 7419–7431 DOI: 10.1021/acs.macromol.7b01419

Notebook Setup

To begin, please run Kernel-> Restart & Clear Output from the menu at the top of the notebook. It is a good idea to run this before starting any notebook so that the notebook is fresh for the user. Next, run the cell below (via the top menu-bar or <Shift-Enter>. If the cell throws an import error, there is likely something wrong with your environment.

If successful, you should see a set of logos appear below the cell. Which logos appear depend on what is inside the hv.extension() command at the bottom of the cell. If no logos appear and the cell throws an error, there is likely something wrong with your environment.

Troubleshooting:

  • Did you activate the correct conda environment before starting the jupyter notebook?
  • If not using anaconda, did you install all dependencies before starting the jupyter notebook?
  • Is pyPRISM installed in your current environment on your PYTHONPATH?

Holoviews + Bokeh Logos: Logos

[1]:
import pyPRISM
import numpy as np
import holoviews as hv
hv.extension('bokeh')

Amphiphilic Block Copolymer Solution

image0

In this example, we use pyPRISM to predict the structure of amphiphilic block copolymer solutions. In this case, we show the impact of block copolymer sequence on self-assembly, in which the A block is hydrophilic and the B block is hydrophobic. The block sequences shown are A-B diblock (case 1), A-B-A triblock (case 2), and B-A-B triblock (case 2i), in which the fraction of A-block (f_A) is always 0.5. The system and comparison data are taken from reference 1.

Starting with the aesthetic definitions

[2]:
%opts Curve Scatter [width=500,height=400] Layout [shared_axes=False] Scatter (size=10,alpha=0.5)
%opts Curve Scatter [fontsize={'xlabel':14,'legend':14,'ylabel':14,'ticks':14}]
%opts Overlay [legend_position='bottom_left']
%opts Layout [shared_axes=False]


colors = {}
colors['1'] = 'blue'
colors['2'] = 'red'
colors['2i'] = 'orange'

ls = {}
ls['1'] = 'solid'
ls['2'] = 'solid'
ls['2i'] = 'solid'

lsc = {}
lsc['1'] = 'dotted'
lsc['2'] = 'dotted'
lsc['2i'] = 'dotted'

markers = {}
markers['1'] = 'o'
markers['2'] = '^'
markers['2i'] = 'd'

Next we’ll load in the data extracted from Ref. 1 that we’ll be comparing against.

[3]:
skAA_compare = {}
skBB_compare = {}
for case in ['1','2','2i']:

    fname = '../data/BCPSolution-Sk-AA-Case{}.dat'.format(case)
    dataAA = np.loadtxt(fname)
    skAA_compare[case] = dataAA[:,1]
    fname = '../data/BCPSolution-Sk-BB-Case{}.dat'.format(case)
    dataBB = np.loadtxt(fname)
    skBB_compare[case] = dataBB[:,1]

skAA_compare['k'] = dataAA[:,0]
skBB_compare['k'] = dataBB[:,0]

Next, we’ll use typyPRISM to calculate structural data for the three block copolymer sequences. We chose to solve in the order of case 2, case 2i, then case 1 because case 2 more easily converged to a solution from a naive initial guess.

[4]:

d = 1.0                             #diameter of beads
vd = 4.0/3.0 * np.pi * (d/2.0)**(3) #volume of beads
f_A = 0.5                           #volume fraction of A block
eta = 0.1                           #total occupied volume fraction
site_density = eta/vd
epsilon = 1.0                       #WCA epsilon for A-A and A-B interactions
epsilon_BB = 0.25                   #LJ epsilon for B-B interactions

sys = pyPRISM.System(['A','B'],kT=1.0)
sys.domain = pyPRISM.Domain(dr=0.1,length=1024)

sys.density['A'] = f_A*site_density
sys.density['B'] = (1.0-f_A)*site_density
sys.diameter['A'] = d
sys.diameter['B'] = d
print('--> rho=',sys.density['A'],sys.density['B'])

sys.closure['A','A'] = pyPRISM.closure.PercusYevick()
sys.closure['A','B'] = pyPRISM.closure.PercusYevick()
sys.closure['B','B'] = pyPRISM.closure.PercusYevick()

sys.potential['A','A'] = pyPRISM.potential.WeeksChandlerAndersen(epsilon)
sys.potential['A','B'] = pyPRISM.potential.WeeksChandlerAndersen(epsilon)
sys.potential['B','B'] = pyPRISM.potential.LennardJones(epsilon_BB)

skAA_results = {}
skBB_results = {}
guess = np.zeros(sys.rank*sys.rank*sys.domain.length)
for case in ['2','2i','1']:
    print('==> Solving for case {}'.format(case))

    fname = '../data/BCPSolution-Omega-AA-Case{}.dat'.format(case)
    print("Using omega "+fname)
    sys.omega['A','A'] = pyPRISM.omega.FromFile(fname)
    fname = '../data/BCPSolution-Omega-AB-Case{}.dat'.format(case)
    print("Using omega "+fname)
    sys.omega['A','B'] = pyPRISM.omega.FromFile(fname)
    fname = '../data/BCPSolution-Omega-BB-Case{}.dat'.format(case)
    print("Using omega "+fname)
    sys.omega['B','B'] = pyPRISM.omega.FromFile(fname)

    PRISM = sys.createPRISM()
    result = PRISM.solve(guess)
    guess = np.copy(PRISM.x)

    SAA = pyPRISM.calculate.structure_factor(PRISM)['A','A']
    SBB = pyPRISM.calculate.structure_factor(PRISM)['B','B']
    skAA_results[case] = SAA
    skBB_results[case] = SBB

skAA_results['k'] = sys.domain.k
skBB_results['k'] = sys.domain.k

print('Done!')
--> rho= 0.09549296585513722 0.09549296585513722
==> Solving for case 2
Using omega ../data/BCPSolution-Omega-AA-Case2.dat
Using omega ../data/BCPSolution-Omega-AB-Case2.dat
Using omega ../data/BCPSolution-Omega-BB-Case2.dat
0:  |F(x)| = 6.1997; step 1; tol 0.220434
1:  |F(x)| = 1.41862; step 1; tol 0.0471231
2:  |F(x)| = 0.0989687; step 1; tol 0.00438031
3:  |F(x)| = 0.000851413; step 1; tol 6.66082e-05
4:  |F(x)| = 5.3716e-08; step 1; tol 3.58236e-09
==> Solving for case 2i
Using omega ../data/BCPSolution-Omega-AA-Case2i.dat
Using omega ../data/BCPSolution-Omega-AB-Case2i.dat
Using omega ../data/BCPSolution-Omega-BB-Case2i.dat
0:  |F(x)| = 0.0578709; step 1; tol 0.000604868
1:  |F(x)| = 0.000226768; step 1; tol 1.38193e-05
2:  |F(x)| = 3.28947e-09; step 1; tol 1.89379e-10
==> Solving for case 1
Using omega ../data/BCPSolution-Omega-AA-Case1.dat
Using omega ../data/BCPSolution-Omega-AB-Case1.dat
Using omega ../data/BCPSolution-Omega-BB-Case1.dat
0:  |F(x)| = 0.109135; step 1; tol 0.00308876
1:  |F(x)| = 0.000506968; step 1; tol 1.9421e-05
2:  |F(x)| = 1.28353e-08; step 1; tol 5.76892e-10
Done!

We start by reproducing Figure 5a of Reference 1.

[5]:
%%opts Overlay [legend_position='top_right']

extents = (-0.25,0,8.75,7.25)

sk_plots = []
for ii,case in enumerate(['1','2','2i']):
    label = 'Case{} (pyPRISM)'.format(case)
    style = {'line_dash':ls[case],'color':colors[case]}
    x = np.array(skAA_results['k'])
    y = np.array(skAA_results[case])
    c1 = hv.Curve((x,y),label=label,extents=extents)(style=style)
    sk_plots.append(c1)
    label = 'Case{} (Ref 1)'.format(case)
    style = {'marker':markers[case],'color':colors[case]}
    x = np.array(skAA_compare['k'])[::5]
    y = np.array(skAA_compare[case])[::5]
    c2 = hv.Scatter((x,y),label=label,extents=extents)(style=style)
    sk_plots.append(c2)

hv.Overlay(sk_plots).redim.label(x='kd',y='S(k)')
[5]:

image0

Next, we reproduce Figure 5b:

[6]:
%%opts Overlay [legend_position='top_right']

extents = (-0.25,0,8.75,7.25)

sk_plots = []
for ii,case in enumerate(['1','2','2i']):
    label = 'Case{} (pyPRISM)'.format(case)
    style = {'line_dash':ls[case],'color':colors[case]}
    x = np.array(skBB_results['k'])
    y = np.array(skBB_results[case])
    c1 = hv.Curve((x,y),label=label,extents=extents)(style=style)
    sk_plots.append(c1)
    label = 'Case{} (Ref 1)'.format(case)
    style = {'marker':markers[case],'color':colors[case]}
    x = np.array(skBB_compare['k'])[::5]
    y = np.array(skBB_compare[case])[::5]
    c2 = hv.Scatter((x,y),label=label,extents=extents)(style=style)
    sk_plots.append(c2)

hv.Overlay(sk_plots).redim.label(x='kd',y='S(k)')
[6]:

image0

image0

NB0.Introduction \(\cdot\) NB1.PythonBasics \(\cdot\) NB2.Theory.General \(\cdot\) NB3.Theory.PRISM \(\cdot\) NB4.pyPRISM.Overview \(\cdot\) NB5.CaseStudies.PolymerMelts \(\cdot\) NB6.CaseStudies.Nanocomposites \(\cdot\) NB7.CaseStudies.Copolymers \(\cdot\) NB8.pyPRISM.Internals \(\cdot\) NB9.pyPRISM.Advanced

[ ]: