This example provides a demonstration of using PyMKS to compute the linear strain field for a three phase composite material. It demonstrates how to generate data for delta microstructures and then use this data to calibrate the first order MKS influence coefficients. The calibrated influence coefficients are used to predict the strain response for a random microstructure and the results are compared with those from finite element. Finally, the influence coefficients are scaled up and the MKS results are again compared with the finite element data for a large problem.

PyMKS uses the finite element tool SfePy to generate both the strain fields to fit the MKS model and the verification data to evaluate the MKS model's accuracy.

The governing equations for elasticostaics and the boundary conditions used in this example are the same as those provided in the Linear Elastic in 2D example.

Note that an inappropriate boundary condition is used in this example because current version of SfePy is unable to implement a periodic plus displacement boundary condition. This leads to some issues near the edges of the domain and introduces errors into the resizing of the coefficients. We are working to fix this issue, but note that the problem is not with the MKS regression itself, but with the calibration data used. The finite element package ABAQUS includes the displaced periodic boundary condition and can be used to calibrate the MKS regression correctly.

The first order MKS influence coefficients are all that is needed to compute a strain field of a random microstructure as long as the ratio between the elastic moduli (also known as the contrast) is less than 1.5. If this condition is met we can expect a mean absolute error of 2% or less when comparing the MKS results with those computed using finite element methods [1].

Because we are using distinct phases and the contrast is low enough to only need the first order coefficients, delta microstructures and their strain fields are all that we need to calibrate the first order influence coefficients [2].

Here we use the `make_delta_microstructure`

function from `pymks.datasets`

to create the delta microstructures needed to calibrate the first order influence coefficients for a two phase microstructure. The `make_delta_microstructure`

function uses SfePy to generate the data

```
In [1]:
```%matplotlib inline
%load_ext autoreload
%autoreload 2
import numpy as np
import matplotlib.pyplot as plt

```
In [2]:
```n = 21
n_phases = 3
from pymks.tools import draw_microstructures
from pymks.datasets import make_delta_microstructures
X_delta = make_delta_microstructures(n_phases=n_phases, size=(n, n))

`draw_microstructures`

from `pymks.tools`

.

```
In [3]:
```draw_microstructures(X_delta[::2])

```
```

The `make_elasticFEstrain_delta`

function from `pymks.datasets`

provides an easy interface to generate delta microstructures and their strain fields, which can then be used for calibration of the influence coefficients. The function calls the `ElasticFESimulation`

class to compute the strain fields.

In this example, lets look at a three phase microstructure with elastic moduli values of 80, 100 and 120 and Poisson's ratio values all equal to 0.3. Let's also set the macroscopic imposed strain equal to 0.02. All of these parameters used in the simulation must be passed into the `make_elasticFEstrain_delta`

function. The number of Poisson's ratio values and elastic moduli values indicates the number of phases. Note that `make_elasticFEstrain_delta`

does not take a number of samples argument as the number of samples to calibrate the MKS is fixed by the number of phases.

```
In [4]:
```from pymks.datasets import make_elastic_FE_strain_delta
from pymks.tools import draw_microstructure_strain
elastic_modulus = (80, 100, 120)
poissons_ratio = (0.3, 0.3, 0.3)
macro_strain = 0.02
size = (n, n)
X_delta, strains_delta = make_elastic_FE_strain_delta(elastic_modulus=elastic_modulus,
poissons_ratio=poissons_ratio,
size=size, macro_strain=macro_strain)

Let's take a look at one of the delta microstructures and the $\varepsilon_{xx}$ strain field.

```
In [5]:
```draw_microstructure_strain(X_delta[0], strains_delta[0])

```
```

`slice(None)`

(the default slice operator in Python, equivalent to array[:]) was passed in to the `make_elasticFEstrain_delta`

function as the argument for `strain_index`

, the function returns all the strain fields. Let's also take a look at the $\varepsilon_{yy}$ and $\varepsilon_{xy}$ strain fields.

Now that we have the delta microstructures and their strain fields, we will calibrate the influence coefficients by creating an instance of the `MKSLocalizatoinModel`

class. Because we are going to calibrate the influence coefficients with delta microstructures, we can create an instance of `PrimitiveBasis`

with `n_states`

equal to 3, and use it to create an instance of `MKSLocalizationModel`

. The delta microstructures and their strain fields will then be passed to the `fit`

method.

```
In [6]:
```from pymks import MKSLocalizationModel
from pymks import PrimitiveBasis
prim_basis =PrimitiveBasis(n_states=3, domain=[0, 2])
model = MKSLocalizationModel(basis=prim_basis)

`fit`

method to calibrate the first order influence coefficients.

```
In [7]:
```model.fit(X_delta, strains_delta)

That's it, the influence coefficient have be calibrated. Let's take a look at them.

```
In [8]:
```from pymks.tools import draw_coeff
draw_coeff(model.coeff)

```
```

Let's now use our instance of the `MKSLocalizationModel`

class with calibrated influence coefficients to compute the strain field for a random two phase microstructure and compare it with the results from a finite element simulation.

The `make_elasticFEstrain_random`

function from `pymks.datasets`

is an easy way to generate a random microstructure and its strain field results from finite element analysis.

```
In [9]:
```from pymks.datasets import make_elastic_FE_strain_random
np.random.seed(101)
X, strain = make_elastic_FE_strain_random(n_samples=1, elastic_modulus=elastic_modulus,
poissons_ratio=poissons_ratio, size=size,
macro_strain=macro_strain)
draw_microstructure_strain(X[0] , strain[0])

```
```

**Note that the calibrated influence coefficients can only be used to reproduce the simulation with the same boundary conditions that they were calibrated with**

Now to get the strain field from the `MKSLocalizationModel`

just pass the same microstructure to the `predict`

method.

```
In [10]:
```strain_pred = model.predict(X)

Finally let's compare the results from finite element simulation and the MKS model.

```
In [11]:
```from pymks.tools import draw_strains_compare
draw_strains_compare(strain[0], strain_pred[0])

```
```

Let's plot the difference between the two strain fields.

```
In [12]:
```from pymks.tools import draw_differences
draw_differences([strain[0] - strain_pred[0]], ['Finite Element - MKS'])

```
```

The influence coefficients that were calibrated on a smaller microstructure can be used to predict the strain field on a larger microstructure though spectral interpolation [3], but accuracy of the MKS model drops slightly. To demonstrate how this is done, let's generate a new larger random microstructure and its strain field.

```
In [13]:
```m = 3 * n
size = (m, m)
print size
X, strain = make_elastic_FE_strain_random(n_samples=1, elastic_modulus=elastic_modulus,
poissons_ratio=poissons_ratio, size=size,
macro_strain=macro_strain)
draw_microstructure_strain(X[0] , strain[0])

```
```

```
In [14]:
```model.resize_coeff(X[0].shape)

Let's now take a look that ther resized influence coefficients.

```
In [15]:
```draw_coeff(model.coeff)

```
```

`predict`

method to get the strain field.

```
In [16]:
```strain_pred = model.predict(X)
draw_strains_compare(strain[0], strain_pred[0])

```
```

Again, let's plot the difference between the two strain fields.

```
In [17]:
```draw_differences([strain[0] - strain_pred[0]], ['Finite Element - MKS'])

```
```

[1] Binci M., Fullwood D., Kalidindi S.R., A new spectral framework for establishing localization relationships for elastic behavior of composites and their calibration to finite-element models. Acta Materialia, 2008. 56 (10) p. 2272-2282 doi:10.1016/j.actamat.2008.01.017.

[2] Landi, G., S.R. Niezgoda, S.R. Kalidindi, Multi-scale modeling of elastic response of three-dimensional voxel-based microstructure datasets using novel DFT-based knowledge systems. Acta Materialia, 2009. 58 (7): p. 2716-2725 doi:10.1016/j.actamat.2010.01.007.

[3] Marko, K., Kalidindi S.R., Fullwood D., Computationally efficient database and spectral interpolation for fully plastic Taylor-type crystal plasticity calculations of face-centered cubic polycrystals. International Journal of Plasticity 24 (2008) 1264–1276 doi;10.1016/j.ijplas.2007.12.002.

[4] Marko, K. Al-Harbi H. F. , Kalidindi S.R., Crystal plasticity simulations using discrete Fourier transforms. Acta Materialia 57 (2009) 1777–1784 doi:10.1016/j.actamat.2008.12.017.