Skip to content

Commit 3a2048e

Browse files
committed
Merge branch 'dev'
2 parents 0a47c95 + a8635ef commit 3a2048e

24 files changed

+7051
-116
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
*.pptx
12
.ipynb_checkpoints/
23
.DS_Store
34
__pycache__/

example/Cooling_Opt.ipynb

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"### Optimization of a radiative cooling structure\n",
8+
"This notebook will optimize a multi-layer structure inspired by Raman 𝑒𝑡 𝑎𝑙. , Nature 515, 540-546 (2014), utilizing analytic gradients of the three terms that dominate\n",
9+
"the radiative flux: absorption of solar radiation, absorption of atmospheric thermal radiation (both warming), and thermal emission (cooling). \n",
10+
"\n",
11+
"**Note that the explit angle and polarization dependence will be included in these gradients, and so each gradient evaluation will be ~14 times slower than comparable gradient evaluations when angle- and polarization dependence are ignored as in other optimization demos [see, for example, here](http://localhost:8888/notebooks/CODE/wptherml/example/Incandescent_Opt.ipynb)**."
12+
]
13+
},
14+
{
15+
"cell_type": "code",
16+
"execution_count": 2,
17+
"metadata": {},
18+
"outputs": [
19+
{
20+
"name": "stdout",
21+
"output_type": "stream",
22+
"text": [
23+
" Temperature not specified!\n",
24+
" Proceeding with default T = 300 K\n",
25+
"xs is \n",
26+
"[230, 485, 688, 13, 73, 34, 54]\n",
27+
" This structure is net cooling with net power out being 63.525923254487594\n",
28+
" This structure is net cooling with net power out being 26.93358430958938\n",
29+
" This structure is net cooling with net power out being 26.987684491357246\n",
30+
" This structure is net cooling with net power out being 31.257424595611454\n",
31+
" This structure is net cooling with net power out being 59.933261081356505\n",
32+
" This structure is net cooling with net power out being 68.59349206988524\n",
33+
" This structure is net cooling with net power out being 69.19255314674987\n",
34+
" This structure is net cooling with net power out being 69.53944029636773\n",
35+
" This structure is net cooling with net power out being 69.07278380133678\n",
36+
" This structure is net cooling with net power out being 70.57523013190401\n",
37+
" This structure is net cooling with net power out being 70.49876027675884\n",
38+
" This structure is net cooling with net power out being 70.85380995302663\n",
39+
" This structure is net cooling with net power out being 70.79612870829939\n",
40+
" This structure is net cooling with net power out being 70.86055573829051\n",
41+
" This structure is net cooling with net power out being 70.56282333077554\n",
42+
" This structure is net cooling with net power out being 70.88045444055962\n",
43+
" This structure is net cooling with net power out being 70.89025678075966\n",
44+
" This structure is net cooling with net power out being 70.89100749911535\n",
45+
" This structure is net cooling with net power out being 70.89121169266468\n",
46+
" This structure is net cooling with net power out being 70.89166953716105\n",
47+
" This structure is net cooling with net power out being 70.89224257525305\n",
48+
" This structure is net cooling with net power out being 70.89260757037914\n",
49+
" This structure is net cooling with net power out being 70.89261054829753\n",
50+
" This structure is net cooling with net power out being 70.8926105873357\n",
51+
"[300. 296.22235003 300. 200.02210915 277.76544865\n",
52+
" 294.76122768 300. ]\n",
53+
"70.8926105873357\n"
54+
]
55+
}
56+
],
57+
"source": [
58+
"### Import WPTHERML class!\n",
59+
"from wptherml.wpml import multilayer\n",
60+
"from matplotlib import pyplot as plt\n",
61+
"from wptherml.datalib import datalib\n",
62+
"import numpy as np\n",
63+
"from scipy.optimize import minimize\n",
64+
"from scipy.optimize import basinhopping\n",
65+
"import time\n",
66+
"import numpy as np\n",
67+
"\n",
68+
"### Define structure!\n",
69+
"structure = {\n",
70+
"\n",
71+
" 'Material_List': ['Air', 'SiO2', 'HfO2', 'SiO2', 'HfO2', 'SiO2', 'HfO2', 'SiO2', 'Ag', 'Air'],\n",
72+
" 'Thickness_List': [0, 230e-9, 485e-9, 688e-9, 13e-9, 73e-9, 34e-9, 54e-9, 200e-9, 0],\n",
73+
" 'Lambda_List': [300e-9, 20000e-9, 1000],\n",
74+
" ### we will compute gradients wrt thickness of first 7 layers, Ag thickness will not change\n",
75+
" 'Gradient_List': [1,2,3,4,5,6,7],\n",
76+
" 'EXPLICIT_ANGLE': 1,\n",
77+
" 'COOLING': 1\n",
78+
" \n",
79+
" }\n",
80+
"\n",
81+
"### create instance of multilayer class called cool_ml\n",
82+
"cool_ml = multilayer(structure)\n",
83+
"### get length of gradient vector\n",
84+
"length = cool_ml.gradient_dimension\n",
85+
"\n",
86+
"def update_multilayer(x):\n",
87+
" for i in range(0,len(x)):\n",
88+
" cool_ml.d[i+1] = x[i]*1e-9\n",
89+
" ### now we have the new structure, update fresnel quantities\n",
90+
" cool_ml.fresnel_ea()\n",
91+
" cool_ml.thermal_emission_ea()\n",
92+
" ### now we have new emissivity, update thermal emission\n",
93+
" cool_ml.cooling_power()\n",
94+
"\n",
95+
" ### return negative of cooling power - minimize functions want \n",
96+
" ### to minimize, so trick them by passing negative of the objective you\n",
97+
" ### want to maximize\n",
98+
" return -cool_ml.cooling_power_val\n",
99+
"\n",
100+
"### given an array of thicknesses of the coating, update\n",
101+
"### the structure and compute the gradient vector of conversion efficiency wrt layer thicknesses\n",
102+
"def analytic_grad(x0):\n",
103+
" cur = update_multilayer(x0)\n",
104+
" cool_ml.fresnel_prime_ea()\n",
105+
" cool_ml.thermal_emission_prime_ea()\n",
106+
" cool_ml.cooling_power_prime()\n",
107+
" ### now there will be three contributions to the\n",
108+
" ### gradient vector... two warming contributions \n",
109+
" ### (solar_power_grad and atmospheric_power_grad)\n",
110+
" ### and one cooling contribution (radiative_power_grad)\n",
111+
" ### and the total gradient is the sum of all three\n",
112+
" g = cool_ml.cooling_power_grad\n",
113+
" ### scale gradient to be in nm^-1 rather than over m^-1\n",
114+
" return -g*1e-9\n",
115+
"\n",
116+
"### Function that gets the negative of the efficiency and the \n",
117+
"### negative of the gradient for use in the l-bfgs-b algorithm\n",
118+
"### also prints out the time for timing purposes!\n",
119+
"def SuperFunc(x0):\n",
120+
" en = update_multilayer(x0)\n",
121+
" c_time = time.time()\n",
122+
" if en<0:\n",
123+
" print(\" This structure is net cooling with net power out being\",-en)\n",
124+
" else:\n",
125+
" print(\" This structure is net warming with net poer in being\",-en)\n",
126+
" gr = analytic_grad(x0)\n",
127+
" return en, gr\n",
128+
"\n",
129+
"\n",
130+
"# the bounds for L-BFGS-B updates!\n",
131+
"bfgs_xmin = np.ones(length)\n",
132+
"bfgs_xmax = 300*np.ones(length)\n",
133+
"\n",
134+
"# rewrite the bounds in the way required by L-BFGS-B\n",
135+
"bfgs_bounds = [(low, high) for low, high in zip(bfgs_xmin, bfgs_xmax)]\n",
136+
"\n",
137+
"### initialize the solution vector xs to be the thicknesses from \n",
138+
"### Raman et al. paper\n",
139+
"xs = [230, 485, 688, 13, 73, 34, 54]\n",
140+
"\n",
141+
"### print out initial solution vector and initial efficiency\n",
142+
"print(\"xs is \")\n",
143+
"print(xs)\n",
144+
"pflux = -update_multilayer(xs)\n",
145+
"if pflux>0:\n",
146+
" print(\" This structure is net cooling with net power out being\",pflux) \n",
147+
"else:\n",
148+
" print(\" This structure is net warming with net poer in being\",pflux)\n",
149+
"\n",
150+
"\n",
151+
"### run l-bfgs-b algorithm!\n",
152+
"ret = minimize(SuperFunc, xs, method=\"L-BFGS-B\", jac=True, bounds=bfgs_bounds)\n",
153+
"\n",
154+
"### print optimal solution and its efficiency!\n",
155+
"print(ret.x)\n",
156+
"print(-update_multilayer(ret.x))\n",
157+
" \n"
158+
]
159+
},
160+
{
161+
"cell_type": "code",
162+
"execution_count": null,
163+
"metadata": {},
164+
"outputs": [],
165+
"source": []
166+
},
167+
{
168+
"cell_type": "code",
169+
"execution_count": null,
170+
"metadata": {},
171+
"outputs": [],
172+
"source": []
173+
}
174+
],
175+
"metadata": {
176+
"kernelspec": {
177+
"display_name": "Python 3",
178+
"language": "python",
179+
"name": "python3"
180+
},
181+
"language_info": {
182+
"codemirror_mode": {
183+
"name": "ipython",
184+
"version": 3
185+
},
186+
"file_extension": ".py",
187+
"mimetype": "text/x-python",
188+
"name": "python",
189+
"nbconvert_exporter": "python",
190+
"pygments_lexer": "ipython3",
191+
"version": "3.7.3"
192+
}
193+
},
194+
"nbformat": 4,
195+
"nbformat_minor": 2
196+
}

example/Example1.ipynb

Lines changed: 136 additions & 1 deletion
Large diffs are not rendered by default.

example/Incandescent_Opt.ipynb

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"This notebook demonstrates the local optimization of a filter coupled to a W thermal emitter,\n",
8+
"and should reproduce the efficiency reported in Table II \"W + F$_{opt}$\" in \n",
9+
"\"Accelerating the discovery of multi-layer nanostructures with analytic differentiation \n",
10+
"of the transfer matrix equations\" by J. F. Varner, D. Wert, A. Matari, R. Nofal, and J. J. Foley IV."
11+
]
12+
},
13+
{
14+
"cell_type": "code",
15+
"execution_count": null,
16+
"metadata": {},
17+
"outputs": [],
18+
"source": [
19+
"from wptherml.wpml import multilayer\n",
20+
"from matplotlib import pyplot as plt\n",
21+
"from scipy.optimize import minimize\n",
22+
"from scipy.optimize import basinhopping\n",
23+
"import time\n",
24+
"import numpy as np\n",
25+
"\n",
26+
"### This will define a thick tungsten slab\n",
27+
"w_struct = {\n",
28+
"\n",
29+
" 'Material_List': ['Air', 'W', 'Air'],\n",
30+
" 'Thickness_List': [0, 900e-9, 0],\n",
31+
" 'Lambda_List': [300e-9, 4000e-9, 1000],\n",
32+
" 'Temperature': 2700,\n",
33+
" 'LIGHTBULB': 1\n",
34+
"\n",
35+
" }\n",
36+
"\n",
37+
"### create instance of the tungsten emitter structure\n",
38+
"w = multilayer(w_struct)\n",
39+
"\n",
40+
"\n",
41+
"### Create a global variable called emissivity that will NOT change from the original emissivity of W slab\n",
42+
"e_emissivity = w.emissivity_array\n",
43+
"\n",
44+
"### This will define the base filter that will be optimized\n",
45+
"structure = {\n",
46+
" 'Material_List' : ['Air', 'Ta2O5','SiO2','Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5','SiO2', 'Ta2O5', 'SiO2', 'Air'],\n",
47+
" ### Thicknesses just chosen arbitrarily, replace with \"optimal\" values\n",
48+
" 'Thickness_List': [0, 18e-9, 47e-9, 156e-9, 212e-9, 178e-9, 23e-9, 51e-9, 224e-9, 150e-9, 205e-9, 258e-9, 187e-9, 243e-9, 190e-9, 266e-9, 215e-9, 153e-9, 227e-9, 154e-9, 226e-9, 152e-9, 245e-9, 24e-9, 229e-9, 263e-9, 190e-9, 257e-9, 200e-9, 260e-9, 224e-9, 27e-9, 229e-9, 154e-9, 219e-9, 274e-9, 198e-9, 405e-9, 211e-9, 166e-9, 233e-9, 47e-9, 66e-9, 17e-9, 125e-9, 153e-9, 237e-9, 151e-9, 225e-9, 147e-9, 193e-9, 127e-9, 214e-9, 135e-9, 173e-9, 112e-9, 165e-9, 130e-9, 223e-9, 130e-9, 163e-9, 112e-9, 164e-9, 114e-9, 167e-9, 121e-9, 378e-9, 114e-9, 160e-9, 113e-9, 174e-9, 117e-9, 211e-9, 23e-9, 221e-9, 261e-9, 399e-9, 266e-9, 390e-9, 28e-9, 18e-9, 367e-9, 198e-9, 302e-9, 28e-9, 33e-9, 426e-9, 31e-9, 15e-9, 222e-9, 96e-9, 0 ],\n",
49+
" 'Lambda_List': [300e-9, 4000e-9, 1000],\n",
50+
" 'Temperature': 2700,\n",
51+
" 'LIGHTBULB': 1\n",
52+
"\n",
53+
" }\n",
54+
"### create instance called cc\n",
55+
"cc = multilayer(structure)\n",
56+
"\n",
57+
"### get initial luminous efficiency of W-emitter / filter pair\n",
58+
"cc.luminous_efficiency_filter(e_emissivity)\n",
59+
"print(\" Filtered Multilayer Luminous Efficiency\", cc.luminous_efficiency_val*100)\n",
60+
"\n",
61+
"### How many elements in the filter will be varied over?\n",
62+
"length = len(cc.luminous_efficiency_grad)\n",
63+
"print(\"length is \",length)\n",
64+
"\n",
65+
"### given an array of thicknesses for the filter, update the filter and\n",
66+
"### re-compute the luminous efficiency of the W-emitter / filter pair\n",
67+
"def update_multilayer(x0):\n",
68+
" ### use gradient_list to define which layers are updated!\n",
69+
" dim = len(x0)\n",
70+
" for i in range(1,dim+1):\n",
71+
" cc.d[i] = x0[i-1]*1e-9\n",
72+
" \n",
73+
" cc.fresnel()\n",
74+
" cc.thermal_emission()\n",
75+
" cc.luminous_efficiency_filter(e_emissivity)\n",
76+
" ### return the negative of the efficiency since the \n",
77+
" ### scipy minimize functions find the MINIMUM not the MAXIMUM...\n",
78+
" ### we of course want the MAXIMUM efficiency which is the same\n",
79+
" ### as the MINIMUM of the negative of the efficiency\n",
80+
" return -cc.luminous_efficiency_val*100\n",
81+
"\n",
82+
"### given an array of thicknesses for the filter, update the filter\n",
83+
"### and compute the gradient of its transmissivity...\n",
84+
"### use that to compute the gradient of the luminous efficiency\n",
85+
"### return the negative of the luminous efficiency gradient \n",
86+
"### scaled by 10^-7 \n",
87+
"def analytic_grad(x0):\n",
88+
" dim = len(x0)\n",
89+
" g = np.zeros(dim)\n",
90+
" cur = update_multilayer(x0)\n",
91+
" cc.fresnel_prime()\n",
92+
" cc.luminous_efficiency_filter_prime(e_emissivity)\n",
93+
" g = cc.luminous_efficiency_grad\n",
94+
" return -g*1e-7\n",
95+
"\n",
96+
"### Function that gets the negative of the efficiency and the \n",
97+
"### negative of the gradient for use in the l-bfgs-b algorithm\n",
98+
"### also prints out the time for timing purposes!\n",
99+
"def SuperFunc(x0):\n",
100+
" en = update_multilayer(x0)\n",
101+
" c_time = time.time()\n",
102+
" print(en,\",\",c_time)\n",
103+
" gr = analytic_grad(x0)\n",
104+
" return en, gr\n",
105+
"\n",
106+
"\n",
107+
"# the bounds for L-BFGS-B updates!\n",
108+
"bfgs_xmin = np.ones(length)\n",
109+
"bfgs_xmax = 405*np.ones(length)\n",
110+
"\n",
111+
"# rewrite the bounds in the way required by L-BFGS-B\n",
112+
"bfgs_bounds = [(low, high) for low, high in zip(bfgs_xmin, bfgs_xmax)]\n",
113+
"\n",
114+
"### initialize the solution vector xs to be the thicknesses from \n",
115+
"### the structure dictionary\n",
116+
"xs = np.zeros(length)\n",
117+
"for i in range(0,length):\n",
118+
" xs[i] = cc.d[i+1]*1e9\n",
119+
"\n",
120+
"### print out initial solution vector and initial efficiency\n",
121+
"print(\"xs is \")\n",
122+
"print(xs)\n",
123+
"print(\"efficiency is \",update_multilayer(xs))\n",
124+
"\n",
125+
"### run l-bfgs-b algorithm!\n",
126+
"ret = minimize(SuperFunc, xs, method=\"L-BFGS-B\", jac=True, bounds=bfgs_bounds)\n",
127+
"\n",
128+
"### print optimal solution and its efficiency!\n",
129+
"print(ret.x)\n",
130+
"print(update_multilayer(ret.x))\n",
131+
" "
132+
]
133+
},
134+
{
135+
"cell_type": "code",
136+
"execution_count": null,
137+
"metadata": {},
138+
"outputs": [],
139+
"source": []
140+
}
141+
],
142+
"metadata": {
143+
"kernelspec": {
144+
"display_name": "Python 3",
145+
"language": "python",
146+
"name": "python3"
147+
},
148+
"language_info": {
149+
"codemirror_mode": {
150+
"name": "ipython",
151+
"version": 3
152+
},
153+
"file_extension": ".py",
154+
"mimetype": "text/x-python",
155+
"name": "python",
156+
"nbconvert_exporter": "python",
157+
"pygments_lexer": "ipython3",
158+
"version": "3.7.4"
159+
}
160+
},
161+
"nbformat": 4,
162+
"nbformat_minor": 2
163+
}

example/Incandescent_Plot.ipynb

Lines changed: 459 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)