Browse Source

added dispersion into simulation

Konstantin Ladutenko 5 years ago
parent
commit
f08a7d014f

+ 10 - 3
README.md

@@ -22,6 +22,7 @@ How to use scattnlay
 ====================
 
 **Table of contents:**
+- [Web application](#web-application)
 - [Compile code](#compile-code)
 - [Binary install](#binary-install)
 - [Use](#use)
@@ -29,7 +30,13 @@ How to use scattnlay
 - [Acknowledgment](#acknowledgment)
 - [License](#license)
 
-Compile Code:
+Web application
+---------------
+
+Limited web version is available at https://physics.ifmo.ru/mie/
+
+
+Compile Code
 -------------
 To compile the source you will need a C++11 capable compiler. To use
 MultiPrecision feature you need to install Boost.Multiprecision
@@ -60,7 +67,7 @@ Compilation options
  - **make clean** - Delete temporal files
   
 
-Binary install:
+Binary install
 --------------
 
 Binary files for Ubuntu and derivative distributions can be found at
@@ -81,7 +88,7 @@ sudo pip install python-scattnlay
 
 You can also ```git clone``` and ```pip install -e .``` to develop python package.
 
-Use:
+Use
 ----
 
 1. Python library

+ 43 - 8
vue-cli3-webapp/src/App.vue

@@ -54,6 +54,9 @@
         <b-switch v-model="plotSelector.isPlotQabs">
           Qabs
         </b-switch>
+        <b-switch v-model="plotSelector.isPlotQext">
+          Qext
+        </b-switch>
       </div>
       <!--        <b-table :data="plotSelectorData" :columns="plotSelectorColumns" :mobile-cards="isShowInfo"></b-table>-->
       <table class="table is-narrow">
@@ -193,6 +196,7 @@
               {
                 R: 100.0,
                 material: 'nk',
+                isMaterialLoaded:true,
                 reN: 4.0,
                 imN: 0.01,
                 index: 0
@@ -222,6 +226,7 @@
             WLs: [],
             Qsca: [],
             Qabs: [],
+            Qext: [],
             Qsca_n: [[], []],
             Qabs_n: [[], []],
             layout: {},
@@ -233,6 +238,7 @@
             pWLs: [],
             pQsca: [],
             pQabs: [],
+            pQext: [],
             pQsca_n: [[], []],
             pQabs_n: [[], []],
           },
@@ -244,7 +250,8 @@
             isPlotModeE: [],
             isPlotModeH: [],
             isPlotQabs: true,
-            isPlotQsca: true
+            isPlotQsca: true,
+            isPlotQext: false,
           },
           // plotSelectorData: undefined,
           // plotSelectorColumns: undefined,
@@ -476,7 +483,7 @@
         this.simulationRuntime.fromWL = this.simulationSetup.fromWL;
         this.simulationRuntime.toWL = this.simulationSetup.toWL;
         this.simulationRuntime.stepWL = this.simulationSetup.stepWL;
-        this.simulationRuntime.layers = JSON.parse(JSON.stringify(this.simulationSetup.layers));
+        this.simulationRuntime.layers =this.simulationSetup.layers; // TODO: not a copy, but we need spline_n.at() method in every layer.
 
         let t0 = performance.now();
         let fromWL = parseFloat(this.simulationSetup.fromWL);
@@ -485,7 +492,7 @@
         let host = parseFloat(this.simulationSetup.hostIndex);
 
 
-        let Qsca = [], Qabs = [];
+        let Qsca = [], Qabs = [], Qext = [];
         let Qsca_n = [[], []], Qabs_n = [[], []];
 
         let WLs = range(fromWL, toWL, stepWL);
@@ -517,9 +524,19 @@
           for (let num_layer = 0;
                num_layer < this.simulationRuntime.layers.length; 
                num_layer++) {
-            let R = parseFloat(this.simulationRuntime.layers[num_layer].R);
-            let reN = parseFloat(this.simulationRuntime.layers[num_layer].reN);
-            let imN = parseFloat(this.simulationRuntime.layers[num_layer].imN);
+            let layer = this.simulationRuntime.layers[num_layer];
+            let R = parseFloat(layer.R);
+            if (layer.material === 'PEC') {
+              //  TODO: set PEC layer
+              continue;
+            }
+            if (layer.material !== 'nk') {
+              if ( layer.spline_n === undefined ) return;
+              layer.reN = layer.spline_n.at(WL);
+              layer.imN = layer.spline_k.at(WL);
+            }
+            let reN = parseFloat(layer.reN);
+            let imN = parseFloat(layer.imN);
             nmie.AddTargetLayerReIm( this.convertUnits2nm(this.units, R)*host,
                     reN/host, imN/host);
             
@@ -529,6 +546,7 @@
           nmie.RunMieCalculation();
           Qsca.push(nmie.GetQsca());
           Qabs.push(nmie.GetQabs());
+          Qext.push(nmie.GetQsca()+nmie.GetQabs());
           mode_types.forEach(function (mode_type) {
             mode_n.forEach(function (n) {
               nmie.SetModeNmaxAndType(n, mode_type);
@@ -540,9 +558,11 @@
         }
         this.simulationRuntime.Qsca = Qsca;
         this.simulationRuntime.Qabs = Qabs;
+        this.simulationRuntime.Qext = Qext;
+
         this.simulationRuntime.Qsca_n = Qsca_n;
         this.simulationRuntime.Qabs_n = Qabs_n;
-        this.filterBug();  // TODO: fix the algorithm instead of filtering the final output
+        // this.filterBug();  // TODO: fix the algorithm instead of filtering the final output
 
         let t1 = performance.now();
         this.ttime = ((t1 - t0) / 1000).toFixed(2);
@@ -551,6 +571,7 @@
         this.plotData.pWLs = WLs.slice();
         this.plotData.pQsca = Qsca;
         this.plotData.pQabs = Qabs;
+        this.plotData.pQext = Qext;
         this.plotData.pQsca_n = Qsca_n;
         this.plotData.pQabs_n = Qabs_n;
 
@@ -560,6 +581,7 @@
       filterBug: function () {
         let Qsca = this.simulationRuntime.Qsca;
         let Qabs = this.simulationRuntime.Qabs;
+        let Qext = this.simulationRuntime.Qext;
         let Qsca_n = this.simulationRuntime.Qsca_n;
         let Qabs_n = this.simulationRuntime.Qabs_n;
         let total_mode_n = this.simulationSetup.total_mode_n;
@@ -571,8 +593,14 @@
         }
         this.filterMedian(Qsca);
         this.filterMedian(Qabs);
+        for (let i = 0; i < Qsca.length; i++) {
+          Qext[i] = Qsca[i] + Qabs[i];
+        }
+        // this.filterMedian(Qext);
+
         this.simulationRuntime.Qsca = Qsca;
         this.simulationRuntime.Qabs = Qabs;
+        this.simulationRuntime.Qext = Qext;
         this.simulationRuntime.Qsca_n = Qsca_n;
         this.simulationRuntime.Qabs_n = Qabs_n;
 
@@ -649,7 +677,7 @@
         this.simulationRuntime.mode_n_names = mode_n_names;
       },
       setQtotalChart: function () {
-        let traceQsca, traceQabs;
+        let traceQsca, traceQabs, traceQext;
         traceQsca = {
           x: this.plotData.pWLs,
           y: this.plotData.pQsca,
@@ -662,9 +690,16 @@
           type: 'scatter',
           name: 'Qabs'
         };
+        traceQext = {
+          x: this.plotData.pWLs,
+          y: this.plotData.pQext,
+          type: 'scatter',
+          name: 'Qext'
+        };
         this.chart.traces = [];
         if (this.plotSelector.isPlotQsca === true) this.chart.traces.push(traceQsca);
         if (this.plotSelector.isPlotQabs === true) this.chart.traces.push(traceQabs);
+        if (this.plotSelector.isPlotQext === true) this.chart.traces.push(traceQext);
       },
       plotResults: function () {
         this.setQtotalChart();

+ 19 - 1
vue-cli3-webapp/src/components/GetLayerParameters.vue

@@ -37,6 +37,12 @@
                                                {{material.spline_n.xs[material.spline_n.xs.length-1]}} nm)
                         </option>
                     </b-select>
+                    <div v-if="layer.isMaterialLoaded">
+                        <font-awesome-icon icon="check-circle" class="has-text-success"/>
+                    </div>
+                    <div v-else>
+                        <font-awesome-icon icon="ban" class="has-text-danger"/>
+                    </div>
                     <!--  TODO: convert to source units in b-select above-->
 
                 </div>
@@ -87,12 +93,24 @@
         watch: {
             'layer.material': {
                 handler: function () {
-                    console.log('update');
+                    // console.log('update');
+                    this.layer.isMaterialLoaded = false;
                     if (this.layer.material == 'nk') {
                         this.isDisabled = false;
+                        this.layer.reN = 4;
+                        this.layer.imN = 0.01;
+                        this.layer.isMaterialLoaded = true;
                     } else {
                         this.isDisabled = true;
                     }
+                    for (const mat of this.materials) {
+                        if (mat.name != this.layer.material) continue;
+                        this.layer.spline_n = mat.spline_n;
+                        this.layer.spline_k = mat.spline_k;
+                        console.log(mat.spline_n.at(500));
+                        console.log(this.layer.spline_n.at(500));
+                        this.layer.isMaterialLoaded = true;
+                    }
                 }
             }
         },

+ 1 - 8
vue-cli3-webapp/src/components/GetMaterials.vue

@@ -42,7 +42,7 @@
                         <td>{{material.name}}  ({{material.spline_n.xs[0]}} -
                             {{material.spline_n.xs[material.spline_n.xs.length-1]}} nm)</td>
                         <td><b-checkbox v-model="material.isPlot"/></td>
-                        <td>{{material.fname}}
+                        <td><a v-bind:href="material.fname">{{material.fname}}</a>
                             <span class="rh-input">
                                 <b-button @click="deleteMaterial(material.fname);" class="is-danger is-small is-outlined">
                                     <font-awesome-icon icon="trash"/>
@@ -310,13 +310,6 @@
                 material.spline_n = spline_n;
                 material.spline_k = spline_k;
                 material.isLoaded = true;
-                // const spline = new Spline(xs, ys);
-                // // get Y at arbitrary X
-                // console.log(spline.at(1.4));
-                // // interpolate a line at a higher resolution
-                // for (let i = 0; i < 50; i++) {
-                //     console.log(spline.at(i * 0.1));
-                // }
             },
             async loadMaterialData(URL){
                 const yaml = require('js-yaml');

+ 14 - 2
vue-cli3-webapp/src/components/GetParticleParameters.vue

@@ -1,5 +1,6 @@
 <template>
     <div class="field">
+        <!--            Select particle type-->
         <div class="field is-horizontal">
             <div class="field-label is-normal">
                 <label class="label">Spherical particle</label>
@@ -19,7 +20,7 @@
             </div>
         </div>
         <div v-for="layer in layers" v-bind:key="layer.index">
-        <GetLayerParameters v-bind:layer="layer"
+            <GetLayerParameters v-bind:layer="layer"
                             v-bind:units="units"
                             v-bind:particle="particle"
                             v-bind:index="layer.index"
@@ -53,6 +54,14 @@
                     if (this.particle === 'multilayer') {this.layersNum = 3;}
                 }
             },
+            // layers: {
+            //     handler: function () {
+            //         if ( this.layers[0].spline_n === undefined ) return;
+            //         console.log('GPP1', Object.getOwnPropertyNames(this.layers[0].spline_n));
+            //         console.log('GPP2', this.layers[0].spline_n.at(500));
+            //     },
+            //     deep:true
+            // },
             layersNum: {
                 handler: function () {
                     while (this.layersNum < this.layers.length) {
@@ -65,9 +74,12 @@
                             {
                                 R: r_prev*0.1,
                                 material: 'nk',
+                                isMaterialLoaded:true,
                                 reN: 4.0,
                                 imN: 0.01,
-                                index: 1
+                                index: 1,
+                                spline_n: undefined,
+                                spline_k: undefined,
                             }
                         );
                     }

+ 11 - 0
vue-cli3-webapp/src/components/ShowInfo.vue

@@ -23,6 +23,17 @@
                     <span style="font-weight: bold">Comp. Phys. Comm., vol. 214, pp. 225–230, 2017</span>
                 </article>
             </div>
+            <div class="message" style="padding: 2rem">
+                <span style="text-decoration: underline;text-emphasis: before;font-weight: bold;">Alternatives:</span>
+                <div class="content">
+                    <ul>
+                        <li><a href="https://nanocomposix.com/pages/mie-theory-calculator">Nanocomposix.</a>  Bulk or core-shell, only dipole and quadrupole contributions.</li>
+                        <li><a href="https://de.ifmo.ru/miecalculator/">Ivan Toftul.</a>  Only bulk particles.</li>
+                        <li>Lucien Saviot. <a href="https://saviot.cnrs.fr/mie/index.en.html">Bulk</a> and <a href="https://saviot.cnrs.fr/miecoat/index.en.html">core-shell</a> calculators.</li>
+                        <li><a href="https://omlc.org/calc/mie_calc.html">Scott Prahl.</a> Angle distribution. </li>
+                    </ul>
+                </div>
+            </div>
         </b-modal>
     </section>
 </template>