Browse Source

initial support of moving the origin of near-field simulation frame

Konstantin Ladutenko 3 years ago
parent
commit
5a14303f3e

+ 122 - 0
guiapp/src/components/nearfield/GetNearFieldRefinedSettings.vue

@@ -0,0 +1,122 @@
+<template>
+  <div class="row items-baseline">
+    <div class="col-xs-12 col-sm-auto text-weight-bold text-center q-pr-md q-py-sm">
+      <div :style="flexRowTitleStyle">
+        Plot
+      </div>
+    </div>
+    <div class="col-xs-grow col-sm">
+      <div class="row justify-center items-baseline">
+        <div class="col-auto text-center q-py-xs q-pr-md">
+          <div :style="flexRowTitleStyle">
+            <span  class="text-italic">2<sup>&thinsp;nd</sup></span> side resolution
+          </div>
+        </div>
+        <div class="col-xs-grow col-sm">
+          <div class="row justify-xs-center justify-sm-start items-center">
+            <input-with-units
+                v-model:input-result="plotYSideResolution"
+                v-model:is-showing-help="isShowingHelpForInputWithUnits"
+                :initial-expression="plotYSideResolution.toString()"
+                title="points"
+                units=""
+            /></div>
+        </div>
+      </div>
+      <div class="row justify-center items-baseline">
+        <div class="col-auto text-center q-py-xs q-pr-md">
+          <div :style="flexRowTitleStyle" >
+        relative center
+          </div>
+        </div>
+        <div class="col-xs-grow col-sm">
+          <div class="row justify-xs-center justify-sm-start items-center">
+            <div class="col-auto">
+              <q-tooltip anchor="center start" self="center end" >
+                E-field vector direction
+              </q-tooltip><input-with-units
+                  v-model:input-result="atRelativeX0"
+                  v-model:is-showing-help="isShowingHelpForInputWithUnits"
+                  :initial-expression="atRelativeX0.toString()"
+                  title="𝑋𝑜&thinsp;/&hairsp;𝑅"
+                  units=""
+              />
+            </div>
+            <div class="col-auto">
+              <q-tooltip anchor="center start" self="center end" >
+                H-field vector direction
+              </q-tooltip><input-with-units
+                v-model:input-result="atRelativeY0"
+                v-model:is-showing-help="isShowingHelpForInputWithUnits"
+                :initial-expression="atRelativeY0.toString()"
+                title="𝑌𝑜&thinsp;/&hairsp;𝑅"
+                units=""
+            />
+            </div>
+            <div class="col-auto">
+              <q-tooltip anchor="center start" self="center end" >
+                k-vector direction
+              </q-tooltip><input-with-units
+                v-model:input-result="atRelativeZ0"
+                v-model:is-showing-help="isShowingHelpForInputWithUnits"
+                :initial-expression="atRelativeZ0.toString()"
+                title="𝑍𝑜&thinsp;/&hairsp;𝑅"
+                units=""
+            />
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="q-ma-xs"/>
+
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import {
+  defineComponent,
+  computed,
+  // watch
+  } from 'vue'
+import { useStore } from 'src/store'
+import InputWithUnits from 'components/InputWithUnits.vue'
+import { flexRowTitleStyle } from 'components/config'
+
+export default defineComponent({
+
+  name: 'GetNearFieldRefinedSettings',
+  components: {InputWithUnits,},
+
+  setup() {
+    const $store = useStore()
+
+    const isShowingHelpForInputWithUnits = computed({
+      get: () => $store.state.guiRuntime.isShowingHelpForInputWithUnits,
+      set: val => $store.commit('guiRuntime/setIsShowingHelpForInputWithUnits', val)
+    })
+
+    const atRelativeX0 = computed({
+      get: () => $store.state.simulationSetup.gui.nearFieldSetup.atRelativeX0,
+      set: val => $store.commit('simulationSetup/setNearFieldAtRelativeX0', val)
+    })
+    const atRelativeY0 = computed({
+      get: () => $store.state.simulationSetup.gui.nearFieldSetup.atRelativeY0,
+      set: val => $store.commit('simulationSetup/setNearFieldAtRelativeY0', val)
+    })
+    const atRelativeZ0 = computed({
+      get: () => $store.state.simulationSetup.gui.nearFieldSetup.atRelativeZ0,
+      set: val => $store.commit('simulationSetup/setNearFieldAtRelativeZ0', val)
+    })
+
+    const plotYSideResolution = computed({
+      get: () => $store.state.simulationSetup.gui.nearFieldSetup.plotYSideResolution,
+      set: val => $store.commit('simulationSetup/setNearFieldPlotYSideResolution', Math.floor(val))
+    })
+
+    return {isShowingHelpForInputWithUnits, flexRowTitleStyle,
+      plotYSideResolution,
+      atRelativeX0, atRelativeY0, atRelativeZ0}
+  },
+})
+</script>

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

@@ -9,7 +9,7 @@
       <div class="row justify-center items-baseline">
         <div class="col-auto text-center q-py-xs q-pr-md">
           <div :style="flexRowTitleStyle" >
-            max side resolution
+            side resolution
           </div>
         </div>
         <div class="col-xs-grow col-sm">

+ 31 - 10
guiapp/src/components/nearfield/PlotNearField.vue

@@ -67,14 +67,30 @@ export default defineComponent({
     const x0 = computed(()=>totalR.value*relativePlotSize.value)
     const dx = computed(()=>x0.value*2.0/(plotXSideResolution.value-1))
     const units = computed(()=>$store.state.guiRuntime.units)
+    const at_x = computed(()=>{
+      if (crossSection.value == nearFieldPlane.Ek || crossSection.value == nearFieldPlane.Hk) {
+        return $store.state.simulationSetup.current.nearFieldSetup.atRelativeZ0
+      }
+      return $store.state.simulationSetup.current.nearFieldSetup.atRelativeY0
+    })
+
+    const at_y = computed(()=>{
+      if (crossSection.value == nearFieldPlane.Hk) {
+        return $store.state.simulationSetup.current.nearFieldSetup.atRelativeY0
+      }
+      return $store.state.simulationSetup.current.nearFieldSetup.atRelativeX0
+    })
 
     const xy = computed(()=> {
       let x:number[] = []
       let y:number[] = []
+      const xi = at_x.value*totalR.value - dx.value*(plotXSideResolution.value-1)/2;
+      const yi = at_y.value*totalR.value - dx.value*(plotYSideResolution.value-1)/2;
+
       for (let j = 0; j< plotYSideResolution.value; ++j) {
         for (let i = 0; i< plotXSideResolution.value; ++i) {
-          x.push(toUnits(-x0.value + i * dx.value, units.value))
-          y.push(toUnits(-x0.value + j * dx.value, units.value))
+          x.push(toUnits(xi + i * dx.value, units.value))
+          y.push(toUnits(yi + j * dx.value, units.value))
         }
       }
       return {x:x, y:y}
@@ -86,14 +102,19 @@ export default defineComponent({
     const nearFieldEk = computed( ()=>$store.state.plotRuntime.nearFieldEk)
     const nearFieldHk = computed( ()=>$store.state.plotRuntime.nearFieldHk)
     const nearFieldEH = computed( ()=>$store.state.plotRuntime.nearFieldEH)
+    const nearFieldStore = computed(()=>{
+      let nearFieldStoreLocal = nearFieldEk.value
+      if (crossSection.value == nearFieldPlane.Hk) nearFieldStoreLocal = nearFieldHk.value
+      if (crossSection.value == nearFieldPlane.EH) nearFieldStoreLocal = nearFieldEH.value
+      $store.commit('plotRuntime/setNearFieldDataTo', getMaxFromHeatmap(nearFieldStoreLocal))
+      $store.commit('plotRuntime/setNearFieldDataFrom', getMinFromHeatmap(nearFieldStoreLocal))
+      $store.commit('plotRuntime/setNearFieldLimitTo', $store.state.plotRuntime.nearFieldDataTo)
+      $store.commit('plotRuntime/setNearFieldLimitFrom', $store.state.plotRuntime.nearFieldDataFrom)
+      return nearFieldStoreLocal
+    })
     const nearFieldProc = computed( ()=>{
-      let nearFieldStore = nearFieldEk.value
-      if (crossSection.value == nearFieldPlane.Hk) nearFieldStore = nearFieldHk.value
-      if (crossSection.value == nearFieldPlane.EH) nearFieldStore = nearFieldEH.value
-      if (!nearFieldStore) return nearFieldStore
-      $store.commit('plotRuntime/setNearFieldDataTo',getMaxFromHeatmap(nearFieldStore))
-      $store.commit('plotRuntime/setNearFieldDataFrom',getMinFromHeatmap(nearFieldStore))
-      return limitMap(nearFieldStore, limitFrom.value, limitTo.value)
+      if (!nearFieldStore.value) return nearFieldStore.value
+      return limitMap(nearFieldStore.value, limitFrom.value, limitTo.value)
       // return nearFieldStore.map(x=>x>limitTo.value?limitTo.value:x)
     })
     watch([nearFieldProc, xy], ()=>{
@@ -118,7 +139,7 @@ export default defineComponent({
             x1: toUnits(r, units.value),
             y1: toUnits(r, units.value),
             line: {
-              color: 'rgba(255, 255, 255, 0.7)',
+              color: 'rgba(235, 235, 235, 0.8)',
               width: 3
             }
           })

+ 6 - 1
guiapp/src/components/nearfield/RunSimulationNearField.vue

@@ -72,6 +72,10 @@ export default defineComponent({
           const plotYSideResolution = $store.state.simulationSetup.current.nearFieldSetup.plotYSideResolution
           const relativePlotSize = $store.state.simulationSetup.current.nearFieldSetup.relativePlotSize
           const crossSection = $store.state.simulationSetup.current.nearFieldSetup.crossSection
+          const atX = $store.state.simulationSetup.current.nearFieldSetup.atRelativeX0
+          const atY = $store.state.simulationSetup.current.nearFieldSetup.atRelativeY0
+          const atZ = $store.state.simulationSetup.current.nearFieldSetup.atRelativeZ0
+          const isMarkUnconvergedAsNaN = 1 // 0 - do not mark, else do mark
           try {
             if (!$store.state.simulationSetup.nmies.nearField.instance) throw 'ERROR! Scattnlay module was not loaded'
             const nmie = $store.state.simulationSetup.nmies.nearField.instance
@@ -93,7 +97,8 @@ export default defineComponent({
                 plotXSideResolution, // in simulation z-axis resolution for Ek and Hk cross-sections
                 relativePlotSize,
                 crossSection,
-                0, 0, 0, 1
+                atX, atY, atZ,
+                isMarkUnconvergedAsNaN
             )
             const Eabs = nmie.GetFieldEabs()
             if (crossSection == nearFieldPlane.Ek) $store.commit('plotRuntime/setNearFieldEk', Eabs)

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

@@ -313,8 +313,8 @@ namespace nmie {
   }
 
 template <typename FloatType>
-void MultiLayerMieApplied<FloatType>::RunFieldCalculationCartesian(const int side_1_points,
-                                                                   const int side_2_points,
+void MultiLayerMieApplied<FloatType>::RunFieldCalculationCartesian(const int first_side_points,
+                                                                   const int second_side_points,
                                                             const double relative_side_length,
                                                             const int plane_selected,
                                                             const double at_x, const double at_y,
@@ -322,7 +322,7 @@ void MultiLayerMieApplied<FloatType>::RunFieldCalculationCartesian(const int sid
                                                             const int isIgnoreAvailableNmax) {
 //  std::cout<<'test'<<std::endl;
   ConvertToSP();
-  this->MultiLayerMie<FloatType>::RunFieldCalculationCartesian( side_1_points, side_2_points,
+  this->MultiLayerMie<FloatType>::RunFieldCalculationCartesian( first_side_points, second_side_points,
                                                                 relative_side_length, plane_selected,
                                                                 at_x, at_y, at_z,
                                                                 isIgnoreAvailableNmax == 0 ? false : true);

+ 2 - 2
src/nmie-applied.hpp

@@ -64,8 +64,8 @@ namespace nmie {
                                   const double from_Theta, const double to_Theta,
                                   const double from_Phi, const double to_Phi,
                                   const int isIgnoreAvailableNmax);
-    void RunFieldCalculationCartesian(const int side_1_points,
-                                      const int side_2_points,
+    void RunFieldCalculationCartesian(const int first_side_points,
+                                      const int second_side_points,
                                       const double relative_side_length,
                                       const int plane_selected,
                                       const double at_x, const double at_y,

+ 18 - 24
src/nmie-nearfield.hpp

@@ -654,8 +654,8 @@ bool MultiLayerMie<FloatType>::GetFieldConvergence () {
 }
 
 template <typename FloatType>
-void MultiLayerMie<FloatType>::RunFieldCalculationCartesian(const int side_1_points,
-                                                            const int side_2_points,
+void MultiLayerMie<FloatType>::RunFieldCalculationCartesian(const int first_side_points,
+                                                            const int second_side_points,
                                                             const double relative_side_length,
                                                             const int plane_selected,
                                                             const double at_x, const double at_y,
@@ -665,35 +665,29 @@ void MultiLayerMie<FloatType>::RunFieldCalculationCartesian(const int side_1_poi
   SetMaxTerms(nmax_in);
   std::vector<FloatType> Xp(0), Yp(0), Zp(0);
   if (size_param_.size()<1) throw "Expect size_param_ to have at least one element before running a simulation";
-  const FloatType max_coord_value = size_param_.back() * relative_side_length;
-  const FloatType dx = max_coord_value*2/( (side_1_points<2 ? 2 : side_1_points) - 1.0);
-  const FloatType dy = dx, dz = dx;
-  auto push_coords = [&](
-      const int nx, const int ny, const int nz,
-      const FloatType xi, const FloatType yi, const FloatType zi) {
+  const FloatType total_R = size_param_.back();
+  const FloatType second_side_max_coord_value = total_R * relative_side_length;
+  // TODO add test if side_1_points <= 1 or side_2_points <= 1
+  const FloatType space_step = second_side_max_coord_value*2/( (second_side_points<2 ? 2 : second_side_points) - 1.0);
+  auto push_coords = [&](const int nx, const int ny, const int nz) {
+    const FloatType xi = at_x*total_R - space_step*(nx-1)/2;
+    const FloatType yi = at_y*total_R - space_step*(ny-1)/2;
+    const FloatType zi = at_z*total_R - space_step*(nz-1)/2;
     for (int i = 0; i < nx; i++) {
       for (int j = 0; j < ny; j++) {
         for (int k = 0; k < nz; k++) {
-          Xp.push_back(xi + static_cast<FloatType>(i) * dx);
-          Yp.push_back(yi + static_cast<FloatType>(j) * dy);
-          Zp.push_back(zi + static_cast<FloatType>(k) * dz);
+          Xp.push_back(xi + static_cast<FloatType>(i) * space_step);
+          Yp.push_back(yi + static_cast<FloatType>(j) * space_step);
+          Zp.push_back(zi + static_cast<FloatType>(k) * space_step);
         }
       }
     }
   };
-  if (plane_selected == Planes::kEk ) {
-    push_coords(side_1_points, 1, side_2_points,
-                -max_coord_value+at_x, at_y, -max_coord_value+at_z);
-  }
-  if (plane_selected == Planes::kHk ) {
-    push_coords(1, side_1_points, side_2_points,
-                at_x, -max_coord_value+at_y, -max_coord_value+at_z);
-  }
-  if (plane_selected == Planes::kEH) {
-    push_coords(side_1_points, side_2_points, 1,
-                -max_coord_value+at_x, -max_coord_value+at_y, at_z);
-  }
-  const unsigned int total_size = side_1_points*side_2_points;
+  // TODO add test to check that side_2_points is for z-axis
+  if (plane_selected == Planes::kEk) push_coords(first_side_points, 1, second_side_points);
+  if (plane_selected == Planes::kHk) push_coords(1, first_side_points, second_side_points);
+  if (plane_selected == Planes::kEH) push_coords(first_side_points, second_side_points, 1);
+  const unsigned int total_size = first_side_points*second_side_points;
   if (Xp.size() != total_size || Yp.size() != total_size || Zp.size() != total_size)
     throw std::invalid_argument("Error! Wrong dimension of field monitor points for cartesian grid!");
   SetFieldCoords({Xp, Yp, Zp});

+ 2 - 2
src/nmie.hpp

@@ -169,8 +169,8 @@ inline std::complex<T> my_exp(const std::complex<T> &x) {
                                   const double from_Phi=0, const double to_Phi=static_cast<double>(3.14159265358979323),
                                   const bool isMarkUnconverged = true,
                                   int nmax_in = -1);
-    void RunFieldCalculationCartesian(const int side_1_points = 2,
-                                      const int side_2_points = 2,
+    void RunFieldCalculationCartesian(const int first_side_points = 2,
+                                      const int second_side_points = 2,
                                       const double relative_side_length = 2,
                                       const int plane_selected = Planes::kEk,
                                       const double at_x = 0, const double at_y = 0,