Bladeren bron

initial version of PlotNearField.vue

Konstantin Ladutenko 3 jaren geleden
bovenliggende
commit
1773e820bb

+ 0 - 1
guiapp/src/components/GetNearFieldSettings.vue

@@ -50,7 +50,6 @@
         <div class="col-xs-grow col-sm">
           <div class="row justify-xs-center justify-sm-start items-center">
             <div class="q-gutter-md q-py-sm q-px-xs">
-              <q-radio v-model="crossSection" dense size='sm' :val="nearFieldPlane.all" label="All" />
               <q-radio v-model="crossSection" dense size='sm' :val="nearFieldPlane.Ek" label="Ek" />
               <q-radio v-model="crossSection" dense size='sm' :val="nearFieldPlane.Hk" label="Hk" />
               <q-radio v-model="crossSection" dense size='sm' :val="nearFieldPlane.EH" label="EH" />

+ 218 - 0
guiapp/src/components/PlotNearField.vue

@@ -0,0 +1,218 @@
+<template>
+  <div>
+    <ReactiveChart :chart="nearFieldPlot"/>
+  </div>
+</template>
+
+<script lang="ts">
+import ReactiveChart from 'components/ReactiveChart.vue'
+import { useStore } from 'src/store'
+import {
+  defineComponent,
+  // onActivated,
+  // ref,
+    reactive,
+  computed,
+  watch
+} from 'vue'
+// import { flexRowTitleStyle } from 'components/config'
+import { plotlyChart } from 'src/store/plot-runtime/state'
+// import { Data, DataTitle } from 'plotly.js-dist-min'
+import {nearFieldPlane} from 'src/store/simulation-setup/state';
+
+
+export default defineComponent({
+  name: 'PlotNearField',
+  components: {
+    ReactiveChart,
+  },
+  setup () {
+    const $store = useStore()
+    const nearFieldPlotInit:plotlyChart = {
+      data: [],
+      layout: {
+        margin: {
+          l: 0,
+          r: 40,
+          b: 50,
+          t: 30
+        },
+        xaxis: {
+          title: ''
+        },
+        yaxis: {
+          scaleanchor: 'x',
+          title: ''
+        },
+        showlegend: false,
+      },
+      config: {responsive: true,
+        // showEditInChartStudio: true,
+        displaylogo: false}
+    }
+
+    const nearFieldPlot = reactive(nearFieldPlotInit)
+    const crossSection = computed(()=>$store.state.simulationSetup.current.nearFieldSetup.crossSection)
+    const nearFieldEk = computed( ()=>$store.state.plotRuntime.nearFieldEk)
+    const nearFieldHk = computed( ()=>$store.state.plotRuntime.nearFieldHk)
+    const nearFieldEH = computed( ()=>$store.state.plotRuntime.nearFieldEH)
+    watch([nearFieldEk, nearFieldHk, nearFieldEH], ()=>{
+      nearFieldPlot.data.length = 0
+      if (crossSection.value == nearFieldPlane.Ek) {
+        nearFieldPlot.data.push({ z: $store.state.plotRuntime.nearFieldEk,
+          type: 'heatmap',  colorscale: 'Jet', })
+      }
+      if (crossSection.value == nearFieldPlane.Hk) {
+        nearFieldPlot.data.push({ z: $store.state.plotRuntime.nearFieldHk,
+          type: 'heatmap',  colorscale: 'Jet', })
+      }
+      if (crossSection.value == nearFieldPlane.EH) {
+        nearFieldPlot.data.push({ z: $store.state.plotRuntime.nearFieldEH,
+          type: 'heatmap',  colorscale: 'Jet', })
+      }
+      // if (crossSection.value == nearFieldPlane.Hk) $store.commit('plotRuntime/setNearFieldHk')
+      // if (crossSection.value == nearFieldPlane.EH) $store.commit('plotRuntime/setNearFieldEH')
+
+    })
+    // const xaxisTitle = computed(()=>{
+    //   let title:string|Partial<DataTitle> = ''
+    //   if ($store.state.plotRuntime.spectrumPlots.layout.xaxis?.title) {
+    //     title = $store.state.plotRuntime.spectrumPlots.layout.xaxis.title
+    //   }
+    //   return title
+    // })
+    // if (nearFieldPlot.layout.xaxis) nearFieldPlot.layout.xaxis.title = xaxisTitle.value
+    // watch( xaxisTitle, ()=>{
+    //   if (nearFieldPlot.layout.xaxis) nearFieldPlot.layout.xaxis.title = xaxisTitle.value
+    // })
+    //
+    // const plotRange=ref('material data')
+    // const isPlotReN = ref(true)
+    // const isPlotImN = ref(true)
+    // const isPlotInterpolation = ref(true)
+    //
+    // const fromWL = computed(()=>$store.state.simulationSetup.gui.fromWL)
+    // const toWL = computed(()=>$store.state.simulationSetup.gui.toWL)
+    // const pointsWL = computed(()=>$store.state.simulationSetup.gui.pointsWL)
+    //
+    // // updatenearFieldPlot used to be a Vuex mutation with a single argument. As
+    // // long as it is in the component feel free as many arguments as needed.
+    // function updatenearFieldPlot( val:{activatedMaterials:material[], sourceUnits:string,
+    //     fromWL:number, toWL:number, pointsWL:number, plotRange: string,
+    //     isPlotReN: boolean, isPlotImN: boolean, isPlotInterpolation: boolean })
+    // {
+    //   nearFieldPlot.data.length = 0
+    //   for (const material of val.activatedMaterials) {
+    //     if (!material.isPlot) continue
+    //
+    //     if (!material.nSpline) continue
+    //     if (val.isPlotReN) {
+    //       const traceDataReN: Partial<Data> = {
+    //         x: material.nSpline.xs.map(x => toUnits(x, val.sourceUnits)),
+    //         y: material.nSpline.ys,
+    //         mode: 'markers',
+    //         marker:{size:5},
+    //         type: 'scatter',
+    //         name: 'Re(n) ' + material.name + ' data'
+    //       }
+    //       nearFieldPlot.data.push(traceDataReN)
+    //     }
+    //
+    //     if (!material.kSpline) continue
+    //     if (val.isPlotImN) {
+    //       const traceDataImN: Partial<Data> = {
+    //         x: material.kSpline.xs.map(x => toUnits(x, val.sourceUnits)),
+    //         y: material.kSpline.ys,
+    //         mode: 'markers',
+    //         marker:{size:5},
+    //         type: 'scatter',
+    //         name: 'Im(n) ' + material.name + ' data'
+    //       }
+    //       nearFieldPlot.data.push(traceDataImN)
+    //     }
+    //
+    //     if (val.isPlotInterpolation) {
+    //       let fromWL = val.fromWL
+    //       let toWL = val.toWL
+    //       let pointsWL = val.pointsWL-1
+    //       if (nearFieldPlot.layout.xaxis) nearFieldPlot.layout.xaxis.range = [fromWL, toWL]
+    //       if (val.plotRange == 'material data') {
+    //         fromWL = material.nSpline.xs[0]
+    //         toWL = material.nSpline.xs[material.nSpline.xs.length-1]
+    //         pointsWL = 1000
+    //         if (nearFieldPlot.layout.xaxis) nearFieldPlot.layout.xaxis.range = undefined
+    //       }
+    //       const stepWL = (toWL-fromWL)/pointsWL
+    //
+    //       const WLs:number[] =[]
+    //       const nSpline:number[] = []
+    //       const kSpline:number[] = []
+    //       for (let i=0; i<pointsWL; ++i) {
+    //         WLs.push(fromWL+i*stepWL)
+    //         nSpline.push(material.nSpline.at(fromWL+i*stepWL))
+    //         kSpline.push(material.kSpline.at(fromWL+i*stepWL))
+    //       }
+    //       WLs.push(toWL)
+    //       nSpline.push(material.nSpline.at(toWL))
+    //       kSpline.push(material.kSpline.at(toWL))
+    //
+    //       if (val.isPlotReN) {
+    //         if (!material.nSpline) continue
+    //         const traceDataReNi: Partial<Data> = {
+    //           x: WLs.map(x => toUnits(x, val.sourceUnits)),
+    //           y: nSpline,
+    //           type: 'scatter',
+    //           name: 'Re(n) ' + material.name + ' interpolate'
+    //         }
+    //         nearFieldPlot.data.push(traceDataReNi)
+    //       }
+    //
+    //       if (val.isPlotImN) {
+    //         if (!material.nSpline) continue
+    //         const traceDataImNi: Partial<Data> = {
+    //           x: WLs.map(x => toUnits(x, val.sourceUnits)),
+    //           y: kSpline,
+    //           type: 'scatter',
+    //           name: 'Im(n) ' + material.name + ' interpolate'
+    //         }
+    //         nearFieldPlot.data.push(traceDataImNi)
+    //       }
+    //
+    //     }
+    //   }
+    // }
+    //
+    // function updateSpectraPlot() {
+    //   updatenearFieldPlot(
+    //       {
+    //         activatedMaterials: $store.state.guiRuntime.activatedMaterials,
+    //         sourceUnits: sourceUnits.value,
+    //         fromWL: fromWL.value,
+    //         toWL: toWL.value,
+    //         pointsWL: pointsWL.value,
+    //         plotRange: plotRange.value,
+    //         isPlotReN: isPlotReN.value,
+    //         isPlotImN: isPlotImN.value,
+    //         isPlotInterpolation: isPlotInterpolation.value
+    //       })
+    // }
+    //
+    // updateSpectraPlot()
+    //
+    // const materialsToPlot=computed(()=>$store.state.guiRuntime.activatedMaterials
+    //     .filter((val)=>val.isPlot)
+    //     .map(val=>val.name))
+    //
+    // watch ([materialsToPlot, plotRange, isPlotReN, isPlotImN, isPlotInterpolation], ()=>{
+    //   updateSpectraPlot()
+    // })
+    //
+    // onActivated(()=>updateSpectraPlot())
+
+    return {
+      nearFieldPlot,
+
+    }
+  }
+})
+</script>

+ 58 - 50
guiapp/src/components/RunSimulationNearField.vue

@@ -36,17 +36,13 @@
 </template>
 
 <script lang="ts">
-import {
-  defineComponent,
-  computed,
-  // watch,
-    onActivated,
-    nextTick
-} from 'vue'
-import { useStore } from 'src/store'
-import { getModeName, range, rangeInt} from 'components/utils'
-import { cloneDeep } from 'lodash'
-import { saveAs } from 'file-saver'
+import {computed, defineComponent, nextTick, watch} from 'vue'
+import {useStore} from 'src/store'
+import {getModeName, range, rangeInt} from 'components/utils'
+import {cloneDeep} from 'lodash'
+import {saveAs} from 'file-saver'
+import {nearFieldPlane} from 'src/store/simulation-setup/state';
+
 
 export default defineComponent({
   name: 'RunSimulationNearField',
@@ -74,50 +70,62 @@ export default defineComponent({
         return
       }
       isRunning.value = true
-      void nextTick(()=> {
-        $store.commit('simulationSetup/copySetupFromGuiToCurrent')
-
-        const host = $store.state.simulationSetup.current.hostIndex
-
-        try {
-          if (!$store.state.simulationSetup.nmies.nearField.instance) throw 'ERROR! Scattnlay module was not loaded'
-          const nmie = $store.state.simulationSetup.nmies.nearField.instance
-          const layers = cloneDeep($store.state.simulationSetup.current.layers)
-          const nmieStartedTime = performance.now()
-
-          nmie.SetWavelength(atWL.value)
-          nmie.ClearTarget()
-          for (const layer of layers) {
-            if (layer.material.nSpline) layer.n = layer.material.nSpline.at(atWL.value)
-            if (layer.material.kSpline) layer.k = layer.material.kSpline.at(atWL.value)
-            nmie.AddTargetLayerReIm(layer.layerWidth * host, layer.n / host, layer.k / host)
-          }
-
-          nmie.SetModeNmaxAndType(-1, -1)
-
-          nmie.RunFieldCalculationCartesian(
-              $store.state.simulationSetup.current.nearFieldSetup.plotSideResolution,
-              $store.state.simulationSetup.current.nearFieldSetup.relativePlotSize,
-              $store.state.simulationSetup.current.nearFieldSetup.crossSection,
-              0, 0, 0, 0
-          )
-
-
-          const nmieTotalRunTime = (performance.now()-nmieStartedTime)/1000
-          // console.log('Total simulation time:', nmieTotalRunTime, 's')
-          $store.commit('simulationSetup/setNmieNearFieldTotalRunTime', nmieTotalRunTime)
+      void setTimeout(()=> {
+        void nextTick(()=> {
+          $store.commit('simulationSetup/copySetupFromGuiToCurrent')
+
+          const host = $store.state.simulationSetup.current.hostIndex
+          const plotSideResolution = $store.state.simulationSetup.current.nearFieldSetup.plotSideResolution
+          const relativePlotSize = $store.state.simulationSetup.current.nearFieldSetup.relativePlotSize
+          const crossSection = $store.state.simulationSetup.current.nearFieldSetup.crossSection
+          try {
+            if (!$store.state.simulationSetup.nmies.nearField.instance) throw 'ERROR! Scattnlay module was not loaded'
+            const nmie = $store.state.simulationSetup.nmies.nearField.instance
+            const layers = cloneDeep($store.state.simulationSetup.current.layers)
+            const nmieStartedTime = performance.now()
+
+            nmie.SetWavelength(atWL.value)
+            nmie.ClearTarget()
+            for (const layer of layers) {
+              if (layer.material.nSpline) layer.n = layer.material.nSpline.at(atWL.value)
+              if (layer.material.kSpline) layer.k = layer.material.kSpline.at(atWL.value)
+              nmie.AddTargetLayerReIm(layer.layerWidth * host, layer.n / host, layer.k / host)
+            }
 
-        } catch (e) {
-          console.log('Some error:', e)
-        }
-        isRunning.value = false
-      })
+            nmie.SetModeNmaxAndType(-1, -1)
+
+            nmie.RunFieldCalculationCartesian(
+                plotSideResolution,
+                relativePlotSize,
+                crossSection,
+                0, 0, 0, 1
+            )
+            let Eabs_list = Array.from(nmie.GetFieldEabs())
+            const Eabs = [];
+            while (Eabs_list.length) Eabs.push(Eabs_list.splice(0, plotSideResolution));
+            if (crossSection == nearFieldPlane.Ek) $store.commit('plotRuntime/setNearFieldEk', Eabs)
+            if (crossSection == nearFieldPlane.Hk) $store.commit('plotRuntime/setNearFieldHk', Eabs)
+            if (crossSection == nearFieldPlane.EH) $store.commit('plotRuntime/setNearFieldEH', Eabs)
+            const nmieTotalRunTime = (performance.now() - nmieStartedTime) / 1000
+            // console.log('Total simulation time:', nmieTotalRunTime, 's')
+            $store.commit('simulationSetup/setNmieNearFieldTotalRunTime', nmieTotalRunTime)
+
+          } catch (e) {
+            console.log('Some error:', e)
+          }
+          isRunning.value = false
+        })
+      }, 100)
     }
 
-    onActivated(()=>{
-      if (isNmieLoaded.value) runNearFieldSimulation()
+    watch(isRunning, ()=>{
+          console.log(isRunning.value)
     })
 
+    // onActivated(()=>{
+    //   if (isNmieLoaded.value) runNearFieldSimulation()
+    // })
+
 
 
     return { isRunning, isNmieLoaded,

+ 2 - 0
guiapp/src/components/RunSimulationSpectrum.vue

@@ -107,6 +107,7 @@ export default defineComponent({
         return
       }
       isRunning.value = true
+      setTimeout(()=>{
       void nextTick(()=> {
         $store.commit('simulationSetup/copySetupFromGuiToCurrent')
 
@@ -165,6 +166,7 @@ export default defineComponent({
         }
         isRunning.value = false
       })
+      }, 100)
     }
 
     watch(isNmieLoaded, ()=>{

+ 6 - 3
guiapp/src/layouts/MainLayout.vue

@@ -75,9 +75,10 @@
             <q-item-label caption> Requires a GitHub account</q-item-label></q-item-section>
         </q-item>
         <q-separator inset spaced/>
-
-        <q-item class="q-mt-auto">
-          Last spectrum simulation took {{$store.state.simulationSetup.nmies.spectrum.nmieTotalRunTime.toFixed(2)}} s.
+        <q-item class="q-mt-auto text-body2">
+          Last simulation took ...<br>
+           - spectrum  {{$store.state.simulationSetup.nmies.spectrum.nmieTotalRunTime.toFixed(2)}} s.<br>
+           - near-field  {{$store.state.simulationSetup.nmies.nearField.nmieTotalRunTime.toFixed(2)}} s.
         </q-item>
       </q-list>
 
@@ -103,6 +104,8 @@ import { defineComponent, ref } from 'vue'
 
 export default defineComponent({
   name: 'MainLayout',
+  components: {},
+
 
   // components: {
   //   EssentialLink

+ 4 - 0
guiapp/src/pages/Near-field.vue

@@ -7,6 +7,8 @@
     <GetNearFieldSettings/>
     <div class="q-ma-xs"/>
     <RunSimulationNearField/>
+    <div class="q-ma-xs"/>
+    <PlotNearField/>
     <div class="col-auto">
       Input result: {{$store.state.simulationSetup.gui.nearFieldSetup.plotSideResolution}}
     </div>
@@ -27,6 +29,7 @@ import GetWlFromPlot from 'components/GetWlFromPlot.vue'
 import GetNearFieldSettings from 'components/GetNearFieldSettings.vue'
 import RunSimulationSpectrum from 'components/RunSimulationSpectrum.vue'
 import RunSimulationNearField from 'components/RunSimulationNearField.vue'
+import PlotNearField from 'components/PlotNearField.vue'
 
 // import { useStore } from 'src/store'
 
@@ -34,6 +37,7 @@ import RunSimulationNearField from 'components/RunSimulationNearField.vue'
 export default defineComponent({
   name: 'NearField',
   components: {
+    PlotNearField,
     RunSimulationNearField,
     GetWlFromPlot, RunSimulationSpectrum,
     GetNearFieldSettings,

+ 4 - 0
guiapp/src/store/plot-runtime/mutations.ts

@@ -6,6 +6,10 @@ import { getModeName, toUnits } from 'components/utils'
 
 
 const mutation: MutationTree<prsi> = {
+  setNearFieldEk (state: prsi, val: number[][]) {state.nearFieldEk = cloneDeep(val)},
+  setNearFieldHk (state: prsi, val: number[][]) {state.nearFieldHk = cloneDeep(val)},
+  setNearFieldEH (state: prsi, val: number[][]) {state.nearFieldEH = cloneDeep(val)},
+
   setQ (state: prsi, val: spectraData) {
     state.WLs    = cloneDeep(val.WLs)
     state.Qsca   = cloneDeep(val.Qsca)

+ 10 - 1
guiapp/src/store/plot-runtime/state.ts

@@ -17,6 +17,10 @@ export interface spectraData {
 }
 
 export interface plotRuntimeStateInterface {
+  // Near field
+  nearFieldEk:number[][]
+  nearFieldHk:number[][]
+  nearFieldEH:number[][]
   // Spectra plots
   WLs: number[]
   WLsInUnits: number[]
@@ -42,6 +46,9 @@ export interface plotRuntimeStateInterface {
 }
 
 function state(): plotRuntimeStateInterface {
+  const nearFieldEk:number[][] = [[], []]
+  const nearFieldEH:number[][] = [[], []]
+  const nearFieldHk:number[][] = [[], []]
   const WLs:number[] = []
   const WLsInUnits:number[] = []
   const Qsca:number[] = [], Qabs:number[] = [], Qext:number[] = []
@@ -92,7 +99,9 @@ function state(): plotRuntimeStateInterface {
   const isRemovePlots = true
   const isLogPlot = false
 
-  return { WLs, WLsInUnits,
+  return {
+    nearFieldEk, nearFieldHk, nearFieldEH,
+    WLs, WLsInUnits,
     Qsca, Qabs, Qext, Qsca_n, Qabs_n, Qext_n,
     spectrumPlots,
     isPlotQsca, isPlotQabs, isPlotQext,

+ 14 - 10
guiapp/src/store/simulation-setup/actions.ts

@@ -6,7 +6,7 @@ import { useQuasar } from 'quasar'
 
 
 const actions: ActionTree<simulationSetupStateInterface, StateInterface> = {
-  async loadScattnlay ({commit/*,state*/}/* context */) {
+  async loadScattnlay ({commit,/*state*/}/* context */) {
     const $q = useQuasar()
     $q.loading.show({
       message: 'Loading Mie calculator. Please wait...',
@@ -18,27 +18,31 @@ const actions: ActionTree<simulationSetupStateInterface, StateInterface> = {
       nearField: new module.nmie(),
       farField: new module.nmie()}
     commit('setNmies', nmies)
+
+
     // // Test nmiejs if working
-    // if (state.nmie && !state.isNmieRunning) {
+    // if (state.nmies.spectrum.instance && !state.nmies.spectrum.isNmieRunning) {
     //   commit('markNmieAsStarted')
-    //   state.nmie.ClearTarget()
+    //   state.nmies.spectrum.instance.ClearTarget()
     //   const R = 100.0
     //   const reN = 4.0
     //   const imN = 0.01
-    //   state.nmie.AddTargetLayerReIm(R, reN, imN)
-    //   state.nmie.SetModeNmaxAndType(-1, -1)
+    //   state.nmies.spectrum.instance.AddTargetLayerReIm(R, reN, imN)
+    //   state.nmies.spectrum.instance.SetModeNmaxAndType(-1, -1)
     //   const WL = 800
-    //   state.nmie.SetWavelength(WL)
-    //   state.nmie.RunMieCalculation()
-    //   console.log(state.nmie.GetQsca())
+    //   state.nmies.spectrum.instance.SetWavelength(WL)
+    //   state.nmies.spectrum.instance.RunMieCalculation()
+    //   console.log(state.nmies.spectrum.instance.GetQsca())
     //   // outer_arc_points, radius_points, from_Rho, to_Rho,
     //   // from_Theta, to_Theta, from_Phi, to_Phi, isIgnoreAvailableNmax
-    //   state.nmie.RunFieldCalculationPolar(2, 2,
+    //   state.nmies.spectrum.instance.RunFieldCalculationPolar(2, 2,
     //       0.1, 1.5, 0, 3.1415, 0, 3.1415,
     //       0)
-    //   console.log('Field Eabs:', state.nmie.GetFieldEabs())
+    //   console.log('Field Eabs:', state.nmies.spectrum.instance.GetFieldEabs())
     //   commit('markNmieAsFinished')
     // }
+
+
     $q.loading.hide()
   }
 };

+ 1 - 2
guiapp/src/store/simulation-setup/state.ts

@@ -20,7 +20,6 @@ export interface layer {
 }
 
 export enum nearFieldPlane {
-  all = -1,
   Ek = 0,
   Hk,
   EH = 2
@@ -75,7 +74,7 @@ function setupFactory(hostIndex = 1,
                         atWL: 619,
                         relativePlotSize: 2,
                         plotSideResolution: 64,
-                        crossSection: nearFieldPlane.all,
+                        crossSection: nearFieldPlane.Ek,
                         maxComputeTime: 5 //in seconds
                       },
 

+ 1 - 1
src/nmie-applied-impl.hpp

@@ -306,7 +306,7 @@ namespace nmie {
                                                                  const int isIgnoreAvailableNmax) {
     ConvertToSP(); // Converts to size parameter units only the particle design,
     // so we need to convert input parameters too...
-    const a = 2*this->PI_/wavelength_;
+    const FloatType a = 2*this->PI_/wavelength_;
     this->MultiLayerMie<FloatType>::RunFieldCalculationPolar(outer_arc_points, radius_points, a*from_Rho, a*to_Rho,
                                                                from_Theta, to_Theta, from_Phi, to_Phi,
                                                                isIgnoreAvailableNmax == 0 ? false : true);

+ 20 - 3
src/nmie-nearfield.hpp

@@ -84,7 +84,7 @@ namespace nmie {
     isExpCoeffsCalc_ = false;
     aln_.clear(); bln_.clear(); cln_.clear(); dln_.clear();
 
-    std::complex<FloatType> c_one(1.0, 0.0), c_zero(0.0, 0.0);
+    std::complex<FloatType> /*c_one(1.0, 0.0),*/ c_zero(0.0, 0.0);
 
     const int L = refractive_index_.size();
 
@@ -104,8 +104,8 @@ namespace nmie {
     for (int n = 0; n < nmax_; n++) {
       aln_[L][n] = an_[n];
       bln_[L][n] = bn_[n];
-      cln_[L][n] = c_one;
-      dln_[L][n] = c_one;
+      cln_[L][n] = c_zero;
+      dln_[L][n] = c_zero;
     }
 
     std::vector<std::complex<FloatType> > D1z(nmax_ + 1), D1z1(nmax_ + 1), D3z(nmax_ + 1), D3z1(nmax_ + 1);
@@ -350,6 +350,23 @@ namespace nmie {
           nmm::isnan(Hdiff_ft.real()) || nmm::isnan(Hdiff_ft.imag())
           ) break;
     }  // end of for all n
+
+    const unsigned L = refractive_index_.size();
+    // Add the incident field
+    if(l==L) {
+      using nmm::sin;
+      using nmm::cos;
+      const auto z = Rho*cos(Theta);
+      const auto Ex = std::complex<FloatType>(cos(z), sin(z));
+      E[0] +=  Ex*cos(Phi)*sin(Theta);
+      E[1] +=  Ex*cos(Phi)*cos(Theta);
+      E[2] += -Ex*sin(Phi);
+      const auto Hy = Ex;
+      H[0] += Hy*sin(Theta)*sin(Phi);
+      H[1] += Hy*cos(Theta)*sin(Phi);
+      H[2] += Hy*cos(Phi);
+    }
+
     if( (!isConvergedE[0] || !isConvergedE[1] ||!isConvergedE[2] ||
         !isConvergedH[0] || !isConvergedH[1] ||!isConvergedH[2] ) && GetFieldConvergence()) {
       std::cout << "Field evaluation failed to converge an nmax = "<< nmax << std::endl;

+ 4 - 4
tests/test_near_field.cc

@@ -29,8 +29,8 @@ TEST(RunFieldCalculationCartesian, HandlesInput) {
 
 }
 
-TEST(RunFieldCalculationPolar, DISABLED_HandlesInput) {
-//TEST(RunFieldCalculationPolar, HandlesInput) {
+//TEST(RunFieldCalculationPolar, DISABLED_HandlesInput) {
+TEST(RunFieldCalculationPolar, HandlesInput) {
   nmie::MultiLayerMie<nmie::FloatType> nmie;
   EXPECT_THROW(nmie.RunFieldCalculationPolar(0), std::invalid_argument);
   EXPECT_THROW(nmie.RunFieldCalculationPolar(1,1,10,5), std::invalid_argument);
@@ -50,8 +50,8 @@ TEST(RunFieldCalculationPolar, DISABLED_HandlesInput) {
 
 }
 //#ifndef MULTI_PRECISION
-TEST(BulkSphere, DISABLED_HandlesInput) {
-//TEST(BulkSphere, HandlesInput) {
+//TEST(BulkSphere, DISABLED_HandlesInput) {
+TEST(BulkSphere, HandlesInput) {
   nmie::MultiLayerMie<nmie::FloatType> nmie;
   for (const auto &data : parameters_bulk_sphere) {
     auto x = std::get<0>(data);