# **6.2 Frictional pullout and energy dissipation**
[](https://moodle.rwth-aachen.de/mod/page/view.php?id=633308) part 1

        Starting point

The energy evaluation procedure described in notebook [6.1](../tour6_energy/6_1_energy_dissipation.ipynb#top) is applicable to any boundary value problem. In this notebook, we apply it to the pullout of elastic bar, rigid matrix and frictional interface behavior.

        Where are we heading

The analytical solution of the pullout test provides a suitable model to demonstrate the evaluation of the energy dissipation within an initial boundary value problem with including an inelastic deformation.
The frictional bond exhibits a purely dissipative behavior with no elastic deformation included. On the other hand, the fiber represents a purely elastic behavior able to recover all the deformation upon unloading. We will use this configuration to evaluate the total, stored and dissipated energy in two ways. First we will use the concept presented in notebook [6.1](6_1_energy_dissipation.ipynb#top). Then, we will show a more efficient way employing directly the inelastic deformation with the corresponding stress components.

```python
%matplotlib widget
import sympy as sp
import numpy as np
import matplotlib.pylab as plt
sp.init_printing()
```

# **Recap of the analytical solution of the pullout model**

In [Tour 2](../index.ipynb#tour2) we derived an analytical solution of the pullout model [PO_LEF_LRM](../tour2_constant_bond/2_1_1_PO_observation.ipynb#PO_LEM_LRM_summary.ipynb) which delivers the square root function as the pullout curve

$$
P = \sqrt{2 p E_\mathrm{f} A_\mathrm{f} \bar{\tau} w}
$$
and the quadratic profile of displacement at a given level of load

$$
u_\mathrm{f}(P, x) = \frac{P^{2}}{2 A_\mathrm{f} E_\mathrm{f} \bar{\tau} p} + \frac{P x}{A_\mathrm{f} E_\mathrm{f}} + \frac{\bar{\tau} p x^{2}}{2 A_\mathrm{f} E_\mathrm{f}}, \; x \in (a,0)
$$

The fiber deforms only within the debonded length $x \in (a,0)$. The variable $a$ is obtained by realizing that the pullout force is distributed evenly over the debonded zone, i.e.
\begin{align}
a = -\frac{P}{p \bar{\tau}}
\end{align}

To be able to verify the derivation below of energy evaluation provided below, let us retype these equations in `sympy`

```python
# symbol definition
E_f, A_f, tau, p = sp.symbols(r'E_\mathrm{f}, A_\mathrm{f}, \bar{\tau}, p')
x, w = sp.symbols('x, w')
P, u_f, a  = sp.symbols(r'P, u_\mathrm{f}, a')
eps_f, sig_f = sp.symbols(r'\varepsilon_\mathrm{f}, \sigma_\mathrm{f}')
# expressions
P_w_ = sp.sqrt(2*p*E_f*A_f*tau*w)
u_f_ = P**2 / (2*A_f*E_f*tau*p) + P*x / (A_f * E_f) + tau*p*x**2 / (2*A_f*E_f)
a_ = -P / (p*tau)
{P:P_w_, u_f:u_f_, a:a_}
```

**Representative boundary value problem:** Using these three equations we can completely describe the strain and stress state of the pullout problem for a given value of the control displacement $w$. These three equations represents a solution of a boundary value problem needed to evaluate energy supply, stored energy and energy dissipation. The energy evaluations made below can be performed with any solved boundary value problem, no matter if the solution was obtained using analytical solutions or finite-element numerical solvers.

# **Global evaluation of dissipated energy**

## **Work supply $\mathcal{W}$**

Energy supplied to a pullout test controlled by the displacement $w$
associated with the measured force $P$ is evaluated by integrating the force over the control displacement $w$
$$
\mathcal{W}_w = \int_0^w P(w) \, \mathrm{d}w.
$$

In case of the pullout test, the energy needed to achieve a pullout displacement $w$ can be derived by substituting to the pullout curve into the above integral to obtain the result

```python
W_w = sp.symbols(r'\mathcal{W}_w')
W_w_ = sp.integrate(P_w_,w)
{W_w:W_w_}
```

## **Stored energy $\mathcal{U}$**

The stress and slip distributions along the bond zone are not uniform anymore so that we need to evaluate the  stored energy by integrating over the whole bond length.
The evaluation of the stored energy for generally nonlinear material behavior involved in the pullout test is obtained as the sum of integrals of elastic energy contributions from the matrix, the reinforcement and the interface, i.e.
\begin{align}
    \label{eq:stored_energy_pullout}
\mathcal{U}
=
\frac{1}{2}
\int_{\Omega_\mathrm{m}}
\sigma_\mathrm{m}(x)
\varepsilon^\mathrm{el}_\mathrm{m}(x)
\;
\mathrm{d}x
+
\frac{1}{2}
\int_{\Omega_\mathrm{f}}
\sigma_\mathrm{f}(x)
\varepsilon_\mathrm{f}^\mathrm{el}(x)
\;
\mathrm{d}x
+
\frac{1}{2}
\int_{\Omega_\mathrm{mf}}
\tau_\mathrm{mf}(x)
s^\mathrm{el}_\mathrm{mf}(x)
\;
\mathrm{d}x.
\end{align}

This equation is valid for any kind of material behavior ascribed to the matrix, reinforcement or to the bond zone (damage or plasticity), (softening or hardening).
Its evaluation may be regarded as counting of intact, undamaged material links/spring in every single material point in matrix, reinforcement and along the bond zone.

For considered case with elastic fiber, rigid matrix and frictional bond-slip behavior presented in [Tour 2](../index.ipynb#tour2), the stored energy evaluation can be simplified
Since the only elastic deformation occurs in the fiber the integration over the bond zone and matrix can be omitted. The elastic strain in the fiber is obtained by differentiating the fiber [displacement profile](#u_f) with respect to the spatial coordinate $x$ along the bond zone, i.e.

\begin{align}
\varepsilon_\mathrm{f}(P, x) =
\frac{P}{A_\mathrm{f} E_\mathrm{f}} + \frac{\bar{\tau} p x}{A_\mathrm{f} E_\mathrm{f}}, \; x \in (a,0)
\end{align}
The corresponding stress is given as

$$
\sigma_\mathrm{f} = E_\mathrm{f} \varepsilon_\mathrm{f}.
$$

The fiber stress and strain profiles exemplified for the values of $P=1, E_\mathrm{f}=1, A_\mathrm{f}=1, \bar{\tau}=1, p=1$ have the following form:

```python
eps_f_ = u_f_.diff(x) # strain - differentiate the displacement profile
sig_f_ = E_f * eps_f_ # stress apply the elastic constitutive relation
{eps_f:eps_f_, sig_f:sig_f_}
```

Since the fiber is assumed elastic, i.e. $\varepsilon_\mathrm{f}^\mathrm{el} = \varepsilon_\mathrm{f}$ within the debonded zone, we can directly evaluate the stored energy as an integral over the bond zone multiplied with the fiber cross-sectional area $A_\mathrm{f}$ as
$$
\mathcal{U} = \frac{1}{2} A_\mathrm{f} \int_a^0 \sigma_\mathrm{f}
\varepsilon_\mathrm{f}  \, \mathrm{d}x.
$$
By substituting for [fiber strain](#strain_f) and [stress](#stress_f) variables and after rearranging terms we obtain the stored energy as a function of the load $P$
\begin{align}
\mathcal{U}(P) &=
\frac{P^{3}}{6 A_\mathrm{f} E_\mathrm{f} \bar{\tau} p}
\end{align}

To relate the stored energy to the control pullout displacement $w$ let us substitute the [pullout curve $P(w)$](#pullout_w) for the pullout force, delivering the final result
\begin{align}
\mathcal{U}(w) &=
\frac{\sqrt{2}}{3} \cdot \sqrt{E_\mathrm{f} A_\mathrm{f} p\bar{\tau}}
\cdot w^{\frac{3}{2}}.
\end{align}

```python
U_P, U_w = sp.symbols(r'\mathcal{U}_P, \mathcal{U}_w')
U_P_ = sp.simplify( sp.Rational(1,2) * A_f * sp.integrate(sig_f_ * eps_f_, (x,a_,0)) )
U_w_ = U_P_.subs(P,P_w_) # substitute the pullout curve
{U_P:U_P_, U_w:U_w_}
```

        Remark - purely inelastic interface behavior

Note that the constant bond-slip law implies that there is no elastic deformation and, thue, the energy stored in the bond layer is zero. The slip along the interface represents a purely plastic, irreversible deformation.

## **Released energy $G$**

The released energy is obtained as the difference between the supplied and stored energies
$$
G = \mathcal{W} - \mathcal{U}
$$

```python
G_w_global = sp.simplify(W_w_ - U_w_)
G_w_global
```

By comparing this expression with the expression for stored energy and dissipated energyes are equivalent. This comes by chance and does not represent any objective result.

        Side remark 1: if we know the stored energy, we can derive the plastic slip

In the analytical model at hand, we have two distinct material components, one elastic and one purely plastic. There is either elastic unloading in the fiber or ideally plastic unloading in the interface. These unloading characteristics are local to a material point. The determined amount of stored energy is a global structural property. We can use it to determine the linear unloading branch be realizing that the global elastic energy is given as
$$
U = \frac{1}{2} P w_\mathrm{el}
$$
where $w_\mathrm{el}$ represents the recoverable pullout displacement upon the force release, which is equal to

\begin{align}
w_\mathrm{el} = \frac{2U}{P}
=
\frac{2 \sqrt{2} \cdot \sqrt{E_\mathrm{f} A_\mathrm{f} p \bar{\tau} } }
{3 \sqrt{2} \cdot \sqrt{E_\mathrm{f} A_\mathrm{f} p \bar{\tau} }}
\cdot \frac{w^\frac{3}{2}}{w^\frac{1}{2}} = \frac{2}{3} w.
\end{align}

This result is depicted in the [figure above](#pullout_energies) showing that the relation between the stored and released energies can be used to decompose the total control displacement into the recoverable and plastic parts, i.e.
\begin{align}
 w_\mathrm{el} = \frac{2}{3} w, \;\;\; w_\mathrm{pl} &= \frac{1}{3} w
\end{align}

        Side remark 2: what is the value of unloading stiffness?

By evaluating the ration between the force level and elastic displacement we can evaluate the instantaneous value of unloading stiffness at any stage of loading, i.e.

\begin{align}
 K = \frac{P}{w_\mathrm{el}} = \frac{3\sqrt{2}}{2} \cdot \sqrt{E_\mathrm{f}A_\mathrm{f}p\bar{\tau}}
 \cdot    \frac{1}{\sqrt{w}}
\end{align}
To verify this result, let us use `sympy` expressions and symbols defined above

```python
K_w_ = P_w_ / (sp.Rational(2,3)*w)
K_w_
```

# **Local evaluation of dissipated energy**

[](https://moodle.rwth-aachen.de/mod/page/view.php?id=633308) part 2

In the above evaluation, the dissipated energy has been evaluated as a difference between the total supplied energy $\mathcal{W}$ and the elastic stored energy in the whole volume of the specimen $\mathcal{U}$, i.e.

$$
G = \mathcal{W} - \mathcal{U}
$$

However, this evaluation can be computationally expensive, since elastic deformation is distributed over the whole domain of a specimen. Therefore, an alternative evaluation of energy dissipation associated with inelastic deformation is more effective. This method is particularly important for the characterization of material behavior exhibiting softening.

The evaluation of energies involves products of conjugate variables, e.g. displacement-force for work supply or strain-stress for elastic stored energy. In case of energy dissipated by a frictional interface, the energy released by a unit bond interface is given as the product $\tau s$. Thus, the dissipation by the whole interface reads

$$
G = p \int_{\Omega_\mathrm{diss}} \tau(s,x) s(x) \, \mathrm{d}x
$$

Let us evaluate this expression using the analytical solution of the pullout test. The inelastic deformation is represented by the slip variable $s$, which is equivalent to the fiber displacement $u_\mathrm{f}$. The corresponding conjugate stress variable inducing the energy dissipation is the bond stress $\tau = \bar{\tau}$.

In an intermediate state of loading, the profile of bond stress and of the slip have a constant and quadratic shapes, respectively.

Since the debonding length directly represents the irreversible change of the material structure, the energy dissipation can be evaluated by integrating the dissipative term over the length $a$. The rest of the domain, i.e. the elastic bar and the intact part of the bond zone can be omitted from the dissipation integral as they do not contribute to energy dissipation.

Thus, the integration domain $\Omega_\mathrm{diss}$ representing the dissipative part of the domain is equal to the debonded zone $x\in(a,0)$ in our case. The particular form of the integral directly delivering the energy dissipation then reads
\begin{align}
G &= p \int_{a}^{0} \tau s \; \mathrm{d} x \\
  &= p \int_{a}^{0} \bar{\tau} u_\mathrm{f} \; \mathrm{d} x
\end{align}

This integral expressed in `sympy` delivers the result

```python
G_P_local = p * sp.integrate(tau * u_f_, (x,a_,0))

G_w_local = G_P_local.subs(P,P_w_) # substitute the pullout curve for P
G_w_local
```

```python
u_f_
```

By evaluating the dissipated energies evaluated globally and locally we find out that they are equivalent, i.e.

```python
G_w_global - G_w_local
```

As we have already learned, materials exhibiting softening exhibit stress concentration within in a small volume of the material. This concentration is connected with local  inelastic effects of damage and plasticity that release energy. As a result, the energy dissipation of the whole structure can be evaluated by integration of the coupled stress and inelastic strain variables within a small volume of material. This concept constitutes the basis for an objective characterization of fracture.

# **Graphical presentation of energetic response**

        Let us make the formulas executable

To see the correspondence between the stored and dissipated energy studied in the case of the pullout test, let us visualize the correspondence between the force displacement curves and the energy displacement curves. First, we transport the expressions for the pullout curve `P_w_`, total energy `W_w_`, stored energy `U_w_`, dissipated energy `G_w_` and the derivatives of the stored and dissipated energy with respect to the control displacement to executable functions named as `get_[function]`

```python
get_G_w = sp.lambdify((w, E_f, A_f, p, tau), G_w_local)
get_U_w = sp.lambdify((w, E_f, A_f, p, tau), U_w_)
get_W_w = sp.lambdify((w, E_f, A_f, p, tau), W_w_)
get_P_w = sp.lambdify((w, E_f, A_f, p, tau), P_w_)
get_dot_U_w = sp.lambdify((w, E_f, A_f, p, tau), U_w_.diff(w))
get_dot_G_w = sp.lambdify((w, E_f, A_f, p, tau), G_w_local.diff(w))
```

        Visualization of energy profiles

Two graphs are produced to show the pullout curve and the corresponding energy profiles using the following code

```python
fig, (ax_P, ax_E) = plt.subplots(1,2, figsize=(10,4))
fig.canvas.header_visible = False
w_range = np.linspace(1e-9,.1,100)
params = (210000, np.pi*8**2, np.pi*16, 10)
U_w_range = get_U_w(w_range, *params)
G_w_range = get_G_w(w_range, *params)
W_w_range = get_W_w(w_range, *params)
ax_E.plot(w_range, W_w_range, linestyle='dashed', color='black', lw=3, label=r'$\mathcal{W}$')
ax_E.plot(w_range, U_w_range, color='green', label=r'$\mathcal{U}$')
ax_E.fill_between(w_range, U_w_range, 0, color='green', alpha=0.3)
ax_E.plot(w_range, U_w_range+G_w_range, color='red', label=r'$G$')
ax_E.fill_between(w_range, U_w_range+G_w_range, U_w_range, color='red', alpha=0.3)
ax_E.set_xlabel(r'$w$ [mm]'); ax_E.set_ylabel(r'Energy [Nmm]')
ax_E.legend();
P_w_range = get_P_w(w_range, *params)
dot_G_w_range = get_dot_G_w(w_range, *params)
dot_U_w_range = get_dot_U_w(w_range, *params)
ax_P.plot(w_range, P_w_range, color='black', lw=3, label=r'$P = \dot{\mathcal{W}}$')
ax_P.fill_between(w_range, dot_U_w_range, 0, color='green', alpha=0.3, label=r'$\mathcal{U}$')
ax_P.fill_between(w_range, dot_U_w_range+dot_G_w_range, dot_U_w_range, color='red', alpha=0.3, label=r'$G$')
ax_P.set_xlabel(r'$w$ [mm]'); ax_P.set_ylabel(r'$P$ [N]')
ax_P.legend();
```

    Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …

The left diagram shows the total energy $\mathcal{W}$ as the sum of the stored ($\mathcal{U}$) and dissipated ($G$) energies. The right diagram shows the pullout curve with the force decomposed into the part which is used for the storage of energy and the part that cannot be recovered.

As already mentioned above, in the present case of the pullout test with elastic fiber, frictional bond and rigid matrix, the amount of stored and dissipated energies is equivalent, i.e.
$$
G = \mathcal{U}
$$

        Takeaways

 * Domains of a structure that unload or load elastically do not contribute to the energy dissipation
 * Energy dissipation can be evaluated locally only in those parts where irreversible changes in material structure occur
 * The more brittle material the smaller the dissipative zones within the volume of a structural member

        Behind the corner ...

Note that in the present frictional case, integration only over the debonded zone was needed.

Consider other examples with a stress concentration and strain localization, e.g. a pullout test with bond softening, notched bending test or wedge splitting test.

In these tests only a small zone contributes to energy dissipation. We shall illuminate this using the last example of a pullout test with softening behavior, now including the global evaluation of the energy dissipation.

      6.1 Energy games

    6.3 Softening and fracture energy

```python

```


| |Pierre Proulx, ing, professeur|
|:---|:---|
|Département de génie chimique et de génie biotechnologique |** GCH200-Phénomènes d'échanges I **|

### Section 6.3, trouver la vitesse terminale de chute libre par méthode graphique

```python
#
# Préparation de l'affichage et des outils de calcul symbolique
#
import sympy as sp               # pour utiliser sympy, on lui donne l'alias sp
from IPython.display import *   # pour utiliser display qui formate les équations
sp.init_printing(use_latex=True) # pour utiliser LaTeX, formattage de grande qualité
%matplotlib inline
f1,f2,vinf,g,D,rhop,rho,mu=sp.symbols('f1,f2,vinf,g,D,rhop,rho,mu')
Re=rho*vinf*D/mu
f1=(24/Re**0.5+0.5407)**2
f2=4./3.*g*D/(vinf**2)*(rhop-rho)/rho
dico={'rho':1.4,'rhop':2900,'D':0.001,'g':9.81,'mu':0.000018}
vmin,vmax=2,2.25
sp.plot(f1.subs(dico)-f2.subs(dico),(vinf,vmin,vmax));
```

```python

```


```python
import numpy as np
from scipy.optimize import root as solve
from scipy.integrate import quad as integrate
import matplotlib.pyplot as plt
```

# The single impurity Anderson model

The single impurity Anderson model (SIAM) was proposed by Philip W. Anderson \cite{Anderson1961} to describe the formation of local moments by combining two main ideas from preceding research: Friedel and Blandin's observation \cite{blandin1959} that localized $d$-states form resonances with the electron sea and Peierls and Mott reasoning \cite{MottPeierls} that strong Coulomb repulsion could convert a metal into an insulator. This is captured by the Hamiltonian:
\begin{align}
	H_{SIAM} &= H_{con} + H_{imp} + H_{hyb} ~,\\
	H_{con} &= \sum_{k,\sigma}\epsilon_{k}c_{k\sigma}^{\dagger}c_{k\sigma} ~,\\
	H_{imp} &= \sum_{m,\sigma}\epsilon_{m}d_{m\sigma}^{\dagger}d_{m\sigma} +
    \frac{1}{2}\sum_{\substack{m,m^{\prime}m^{\prime\prime}m^{\prime\prime\prime} \\ \sigma\sigma^{\prime}}}
    U_{mm^{\prime}m^{\prime\prime}m^{\prime\prime\prime}}d_{m\sigma}^{\dagger}d_{m^{\prime}\sigma^{\prime}}^{\dagger}d_{m^{\prime\prime\prime}\sigma^{\prime}} d_{m^{\prime\prime}\sigma} ~,\\
	H_{hyb} &= \sum_{k,m,\sigma}\left(V_{k m}c_{k\sigma}^{\dagger}d_{m\sigma}+\operatorname{h.c}\right)~,
    \end{align}
where $H_{con}$ describes conduction electrons, $H_{imp}$ local electrons and $H_{hybr}$ the hybridization between these.

```python
def nFermi (w, invT):
  """
      Fermi distribution function
      beta = `invT`
  """
  return 0.5 * ( 1.0 - np.tanh(0.5 * invT * w) )
```

## Mean-field theory

A traditional starting point for the analysis of interactions in many-electron systems is the mean-field theory; here many-body correlations are treated as a mean density (or field). In this procedure, the correlations are "averaged", leaving a solvable, single-particle problem.

Even though mean-field theory is a powerful tool, one must be very aware of its limitations. To achieve a correct description of strongly correlated systems, many-body correlations cannot be averaged, as this washes out crucial underlying dynamics.

The fundamental deficiency of the Anderson model mean-field (Hartree-Fock approximation) is that it leads to a broken spin symmetry. The approximation misses quantum fluctuations between the mean-field solutions, a process intrinsic to the Kondo effect that effectively restores the spin-rotational symmetry. A single impurity cannot lead to a magnetic solution; correspondingly, the mean-field solution cannot explain the singlet ground state known from the exact Bethe ansatz solution
\cite{Andrei1980}.

## Single orbital solutions
$\newcommand{\dx}[1]{ \mathrm{d}{#1} \,}$

By only considering one local orbital, the hybridization $\Delta^{\sigma \sigma^{\prime}}_{m m^{\prime}}\left(i\omega_n\right)$ reduces to
\begin{equation}
	\Delta^{\sigma \sigma^{\prime}}_{m m^{\prime}}\left(i\omega_n\right) \rightarrow
    \sum_{k}\frac{V^2_k}{i\omega_n - \epsilon_k}~.
\end{equation}
For simplicity, we ignore the momentum dependence of the hybridization. Performing an analytic continuation $i\omega_n\rightarrow\omega-i0^+$ and replacing the sum over $k$ by an integral over the density of states $\rho$, we obtain an expression for $\Delta\left(\omega-i0^+\right)$
\begin{equation}
	\Delta\left(\omega-i0^+\right) = \sum_k \frac{V^2}{\omega-\epsilon_k - i 0^+} =
    \int \dx{\epsilon} \rho\left(\epsilon\right) \frac{V^2}{\omega - \epsilon - i 0^+} =
    \int \dx{\epsilon} \frac{\pi\rho\left(\epsilon\right) V^2}{\pi} \frac{1}{\omega - \epsilon - i 0^+}~.
\end{equation}
Defining $\pi\rho\left(\epsilon\right) V^2 \equiv \bar{\Delta}\left(\epsilon\right)$ and assuming a constant $\bar{\Delta}\left(\epsilon\right)$ inside the bandwidth, i.e., $\epsilon\in \left[-D,D\right]$
\begin{equation}
	\Delta\left(\omega - i0^+\right) = \frac{\bar{\Delta}}{\pi} \log\left[\frac{\omega + D - i 0^+}{\omega - D - i 0^+}\right] =
    \frac{\bar{\Delta}}{\pi} \log\left[\frac{\omega/D + 1 - i0^+}{\omega/D - 1 - i0^+}\right] =
    i \bar{\Delta} + \mathcal{O}\left(\omega/D\right)~.
\end{equation}
Relabeling $\Delta\rightarrow \bar{\Delta}$, the mean-field equations reduce to
\begin{equation}
	\left\langle n_{d_{\sigma}}\right\rangle = \frac{1}{\pi} \int_{-\infty}^{+\infty} \dx{\omega}
    n_f\left(\omega\right)\frac{\Delta}{\left[\omega - \left(\epsilon_d +
    	U \left\langle n_{d_{\bar{\sigma}}}\right\rangle \right)\right]^2+\Delta^2}~.
\end{equation}

Taking the broad bandwidth $D\rightarrow \infty$ and zero-temperature $T\rightarrow0$ limits, one arrives at the same set of equations Anderson derived in his seminal work \cite{Anderson1961} that qualitatively explained the experimentally observed formation of local moments
\begin{equation}
	\left\langle n_{f_{\sigma}}\right\rangle = \frac{1}{\pi}
    	\cot^{-1}\left(\frac{\epsilon_f + U \left\langle n_{f_{\bar{\sigma}}}\right\rangle}{\Delta}\right)~,
\end{equation}
for which he determined an approximate condition for moment formation
\begin{equation}
	U \geq \pi\,\Delta~.
\end{equation}

```python
def eqs(n0, params):
    '''
        Anderson mean-field equations for finite non-zero temperature.

        Normalize by \Delta, obtaining the following integrand:
            1/\pi n_f(\omega) \frac{1}{1 + (x + y n_)^2}

        n0 = [n0_up, n0_down]
    '''

    bounds = {'a': -np.inf, 'b': np.inf}

    invT = params['invT']

    c_up = params['x'] - params['y'] * n0[1]
    n_up = 1 / np.pi * \
        integrate(func=lambda w: nFermi(w, invT) /
                  (1 + (w + c_up)**2), **bounds)[0]

    c_dw = params['x'] - params['y'] * n0[0]
    n_dw = 1 / np.pi * \
        integrate(func=lambda w: nFermi(w, invT) /
                  (1 + (w + c_dw)**2), **bounds)[0]

    # return residual
    return [n_up, n_dw] - n0
```

## Mean-field phase diagram

```python
params = {'invT': np.nan, 'x': np.nan, 'y': np.nan}

# parameter scan settings
params['invT'] = 1e4
ax_X = np.linspace(0, 10.0, num=100)
ax_Y = np.linspace(0, 10.0, num=100)

# solution vector
magnetization = np.zeros([len(ax_X), len(ax_Y)])

# scan parameters region
for i, x in enumerate(ax_X):
    for j, y in enumerate(ax_Y):
        params['x'] = x
        params['y'] = y

        # it's advisable to have asymetric trial solutions
        sol = solve(eqs, x0=[0.9, 0.2], args=params).x

        magnetization[i,j] = sol[0] - sol[1]

# chop solution
magnetization[np.abs(magnetization) < 1e-8] = 0
```

```python
%matplotlib notebook
%matplotlib notebook

# fancy plotting
base = plt.contourf(ax_X, ax_Y, magnetization.T, 4, cmap = 'Spectral_r', alpha=0.90)
line = plt.contour (ax_X, ax_Y, magnetization.T, levels = base.levels, colors='black', linewidth=0.5)
plt.xlabel(r'$ x = (\varepsilon_F - \varepsilon_d) / \Delta $')
plt.ylabel(r'$ y = U / \Delta $')
plt.clabel(line, inline=1, fontsize=8)
bar = plt.colorbar(base)
bar.add_lines(line)
bar.ax.set_ylabel("magnetization")
plt.tight_layout()
```

    <IPython.core.display.Javascript object>

The solution shows a competition effect between the Coulomb interaction and hybridization
The magnetization is defined as $\left\langle n_{f_{\uparrow}} \right\rangle - \left\langle n_{f_{\downarrow}} \right\rangle$. Two asymptotic limits can be identified in this mean-field description:
* The atomic limit, when the Coulomb interaction $U$ wins over the hybridization and impedes the double occupation of the impurity level. At this limit, the ground state corresponds to a singly occupied impurity. At low temperatures/energies, the interaction of this local moment with the conduction sea gives rise to the Kondo effect: a many-body spin-singlet state is formed, as the moment is screened dynamically by conduction sea;
* The unpolarized limit, when $\left\langle n_{d_{\uparrow}} \right\rangle = \left\langle n_{d_{\downarrow}} \right\rangle = \frac{1}{2} n_d$. The Coulomb interaction is on average relatively small and the impurity has equal probability of being occupied, with a spin-up and spin-down electron. The ground state is a paramagnetic Fermi liquid.

Increasing the temperature would change the phase diagram since it would allow increasingly equal average occupations of the split spin-up and spin-down resonances. Forming a local moment will consequently require a larger splitting between the spin-up and spin-down resonances, which will push the atomic limit island upwards and flatten its tip.

```python

```


```python
from datascience import *

import sympy
import matplotlib.pyplot as plt
import matplotlib as mpl
import matplotlib.patches as patches
plt.style.use('seaborn-muted')
%matplotlib inline

from IPython.display import display
import numpy as np
import pandas as pd
solve = lambda x,y: sympy.solve(x-y)[0] if len(sympy.solve(x-y))==1 else "Not Single Solution"

import warnings
warnings.filterwarnings('ignore')
```

# Demand Curves

In this chapter, we will explore one of the most foundational yet important concepts in economics: demand curves. The demand curve shows the graphical relationship between the price of a good or service and the quantity demanded for it over a given period of time.
In other words, it shows the quantity of goods or services consumers are willing to buy at each market price.
The quantity of goods or services demanded or supplied can be modeled as a function of price, as in:

$$\text{Quantity} = f(\text{Price})$$

Notably, the curve is downwards sloping because of the law of demand, which states that *as the price of a good or service increases, the quantity demanded for it decreases, assuming all other factors are held constant*.

This should make intuitive sense: as prices increase, fewer people are willing to pay the higher price for the same good. On the other hand, as prices decrease, more people are willing to pay the lower price for the same good. Hence, the quantity demanded of a good or service has an inverse relationship with the price.

For now, let's assume that the relationship is somewhat linear and can be described as

$$\text{Quantity}_{d}=-a \cdot \text{Price}_{d} + b$$

We can interpret the equation above as follows: *as the price of a unit increases by 1, there is an $a$ unit decrease in the quantity demanded.* For example, $\text{Quantity}_{d}=-2 \cdot \text{Price}_{d} + 3$ would suggest that a price increase by 1 would decrease overall quantity demanded in the market by 2.

Price can also be measured as function of quantity to denote demand. In this case, we use an inverse demand function, as it is the inverse function of the demand function above. Since price is a function of quantity,

$$\text{Price} = f(\text{Quantity})$$

As we are solving for the inverse of the previous demand function, the inverse demand function for the example above is

$$\text{Price}_{d}=-\frac{1}{2} \cdot \text{Quantity}_{d} - \dfrac{3}{2}$$

## Movement and the Demand Curve

### Shifts in the Demand Curve
The demand curve can shift in or out based on exogenous events that occur outside of the market.
Some factors other than a change in price of the good/service could be changes in:

*  buyer's income
*  consumer preferences
*  expectation of future price/supply/demand
*  changes in the price of related goods

If any of these changes occur and causes the demand for the selected good/service to decrease, then the curve shifts to the left as less of the good or service will be demanded at every price. Similarly, if any of these changes causes the demand for the selected good/service to increase, the curve would shift to the right. This signifies that more of the good or service will be demanded at every price. For example, consumers' incomes decreased during the 2008 recession, thus decreasing overall buying power and shifting the demand curve leftwards; a left shift in the demand curve suggests that consumers would purchase fewer quantities of goods at every price.

```python
xs = np.linspace(-10, 20, 100)
ys = -3 * xs + 8
ys2 = -3 * xs + 3

arx = 5
ary = -8
ardx = -1
ardy = 0

plt.figure(figsize=[7,7])
plt.plot(xs, ys, label="Original Demand Curve")
plt.plot(xs, ys2, label="Shifted Demand Curve")
plt.arrow(arx, ary, ardx, ardy, head_width=0.8, head_length=0.5, length_includes_head=True)
plt.xticks([])
plt.yticks([])
plt.xlabel("Quantity", size=16)
plt.ylabel("Price", size=16)
plt.xlim([-0.5, 10.5])
plt.ylim([-25, 10])
plt.legend();
```

### Movements along the Demand Curve

Above, we looked at when exogenous events affect the demand curve. Another concept is movements along the demand curve, which would be considered endogenous events. In movements along the demand curve, changes in price affect the quantity demanded of the good or service. This assumes ceteris paribus, which means holding all other factors constant. This phenomenom is called the Movement of the Demand Curve. With a change in price, the quantity demanded for the good or service can shift the quantity demanded either upward or downward on the demand curve. For example, consider the shift on the graph below from quantity $q_1$ at price $p_1$ to quantity $q_2$ at price $p_2$.

```python
xs = np.linspace(-10, 20, 100)
ys = -3 * xs + 8

q_1, p_1 = 1, 5
q_2, p_2 = 8, -16

plt.figure(figsize=[7,7])
plt.plot(xs, ys)
plt.scatter([q_1, q_2], [p_1, p_2], s=200, color="g", zorder=15)
plt.arrow(q_1, p_1, q_2 - q_1, p_2 - p_1, color="tab:orange", width=.1, head_length=1.5, head_width=0.5, length_includes_head=True, zorder=-1)

# (q_1, p_1)
plt.vlines(q_1, -1000, p_1, linestyle="dashed")
plt.hlines(p_1, -1000, q_1, linestyle="dashed")

# (q_2, p_2)
plt.vlines(q_2, -1000, p_2, linestyle="dashed")
plt.hlines(p_2, -1000, q_2, linestyle="dashed")

plt.xticks([q_1, q_2], [r"$q_1$", r"$q_2$"], size=14)
plt.yticks([p_1, p_2], [r"$p_1$", r"$p_2$"], size=14)
plt.xlabel("Quantity", size=16)
plt.ylabel("Price", size=16)
plt.xlim([-0.5, 10.5])
plt.ylim([-25, 10]);
```

## Income and Substitution Effect

Changes in the price of a good also leads to 2 effects, which can help explain the law of demand:

- **Income Effect**: Examines how the change in price of the good affects income, which then affects the quantity demanded of a good or service. If the price of a good increases, it would require the consumer to spend more of their income on the good. This dissuades consumers from purchasing more of the good, decreasing the quantity demanded. If the price of a good decreases, consumers would spend less money to receive the same good. This increases the quantity demanded for the good, because consumers would have more income remaining to purchase additional units, given the increase in the amount of purchasing power required to obtain the good.
- **Substitution Effect**: Examines how the change in price of the good affects its demand relative to other goods and services. If the price of a good increases, then consumers might look at similar goods that function in the same way or yield an equivalent amount of utility as the original good. Consumers are effectively shifting or substituting away from the relatively more expensive good to a cheaper alternative, thereby decreasing the quantity demanded for the original good. The converse is also true: if the price of a good decreases, then consumers that currently purchase other similar goods might start consuming this good instead, because it would cost less money for them to obtain.

For example, if the price of gas increases, the higher price for gas might encourage consumers to look at purchasing more efficient cars, such as electric or hybrid cars, thus decreasing the demand for gas. This is the subsitution effect. If the consumer stays with their original car, then they would have less disposable income after purchasing the now-more-expensive gas, so they might purchase less gas. This is the income effect.