123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- <template>
- <div class="row items-baseline">
- <div class="col-xs-12 col-sm-auto text-weight-bold text-center q-px-md q-py-sm">
- <q-tooltip
- v-if=" $store.state.guiRuntime.safeFromWL > $store.state.simulationSetup.gui.nearFieldSetup.atWL ||
- $store.state.guiRuntime.safeToWL < $store.state.simulationSetup.gui.nearFieldSetup.atWL "
- anchor="top middle" self="center middle"
- class="bg-amber-4 text-black shadow-4">
- Will use materials<br> spectrum range.
- </q-tooltip>
- <q-btn :loading="isRunning"
- :disable="isRunning||!isNmieLoaded"
- color="primary"
- no-caps
- :label="isNmieLoaded ? 'Run simulation' : 'Loading...'"
- @click="runNearFieldSimulation">
- <template #loading>
- <q-spinner-gears />
- </template>
- </q-btn>
- </div>
- <div class="col-xs-grow col-sm q-px-xs">
- <div class="row justify-xs-center justify-sm-start items-baseline">
- <div class="col-auto">
- <q-btn
- color="primary"
- no-caps
- @click="saveSpectrumSimulation"
- >Save</q-btn>
- </div>
- </div>
- </div>
- </div>
- </template>
- <script lang="ts">
- 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',
- setup() {
- const $store = useStore()
- const isRunning = computed({
- get: ()=> $store.state.simulationSetup.nmies.nearField.isNmieRunning,
- set: val => {
- val ? $store.commit('simulationSetup/markNmieNearFieldAsStarted') : $store.commit('simulationSetup/markNmieNearFieldAsFinished')
- }
- })
- const isNmieLoaded = computed(()=>{ return $store.state.simulationSetup.nmies.nearField.instance })
- const atWL = computed(
- () => $store.state.simulationSetup.current.nearFieldSetup.atWL)
- //-------------------------------------------------------------------------//
- //--------------------- Main --------------------------------------------//
- //-------------------------------------------------------------------------//
- function runNearFieldSimulation() {
- if (isRunning.value) {
- console.log('Some Nmie is already running!')
- return
- }
- isRunning.value = true
- 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)
- }
- 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)
- }
- watch(isRunning, ()=>{
- console.log(isRunning.value)
- })
- // onActivated(()=>{
- // if (isNmieLoaded.value) runNearFieldSimulation()
- // })
- return { isRunning, isNmieLoaded,
- runNearFieldSimulation,
- saveSpectrumSimulation(){
- const fileHeader = '# # You can open and plot this file using Python\n' +
- '# # (without manually removing this header, it will be skipped), see example below.\n' +
- '# import numpy as np\n' +
- '# from matplotlib import pyplot as plt\n' +
- '# data = np.genfromtxt(\'scattnlay-spectra.txt\', skip_header=21, names=True, delimiter=\', \')\n' +
- '# x = data[data.dtype.names[0]] # x-axis has units\n' +
- '# # Possible labels for spectrum data: Qsca, Qabs, Qext,\n' +
- '# # Qsca_E_dipole, etc. (see last comment before spectra data)\n' +
- '# a = data[\'Qsca\']\n' +
- '# b = data[\'Qsca_E_dipole\']\n' +
- '# c = data[\'Qsca_H_dipole\']\n' +
- '# \n' +
- '# plt.figure()\n' +
- '# plt.plot(x, a, label=\'Qsca\')\n' +
- '# plt.plot(x, b, label=\'Qsca E dipole\')\n' +
- '# plt.plot(x, c, label=\'Qsca H dipole\')\n' +
- '# plt.legend()\n' +
- '# plt.xlabel(data.dtype.names[0].replace(\'_\', \', \'))\n' +
- '# plt.ylabel(\'Normalized cross-sections\')\n' +
- '# plt.show()\n\n'
- let xTitle = 'x'
- if ( $store.state.plotRuntime.spectrumPlots.layout.xaxis ) {
- xTitle = String($store.state.plotRuntime.spectrumPlots.layout.xaxis.title)
- }
- let columnNames = '# ' + xTitle + ', Qsca, Qabs, Qext, '
- const mode_n = rangeInt($store.state.simulationSetup.current.numberOfModesToPlot, 1);
- const mode_types = range(0, 1);
- for (const n of mode_n) {
- for (const mode_type of mode_types) {
- const modeTypeName = mode_type == 0 ? 'E' : 'H'
- columnNames += 'Qsca_' + modeTypeName + '_' +getModeName(n)+', '
- columnNames += 'Qabs_' + modeTypeName + '_' +getModeName(n)+', '
- columnNames += 'Qext_' + modeTypeName + '_' +getModeName(n)+', '
- }
- }
- columnNames = columnNames.slice(0, -2)
- columnNames += '\n'
- let body = ''
- const WLs = $store.state.plotRuntime.WLsInUnits
- const Qsca = $store.state.plotRuntime.Qsca
- const Qabs = $store.state.plotRuntime.Qabs
- const Qext = $store.state.plotRuntime.Qext
- const Qsca_n = $store.state.plotRuntime.Qsca_n
- const Qabs_n = $store.state.plotRuntime.Qabs_n
- const Qext_n = $store.state.plotRuntime.Qext_n
- for (let i = 0; i < WLs.length; ++i) {
- let row = WLs[i].toString() + ', '
- + Qsca[i].toString() + ', '
- + Qabs[i].toString() + ', '
- + Qext[i].toString() + ', '
- for (const n of mode_n) {
- for (const mode_type of mode_types) {
- row += Qsca_n[mode_type][n - 1][i].toString() + ', '
- row += Qabs_n[mode_type][n - 1][i].toString() + ', '
- row += Qext_n[mode_type][n - 1][i].toString() + ', '
- }
- }
- row = row.slice(0, -2)
- row += '\n'
- body += row
- }
- const scattnlaySpectra = new Blob([fileHeader+columnNames+body],
- {type: 'text/plain;charset=utf-8',
- endings: 'native'} //TODO test if newline is correctly written in Windows, MacOS
- )
- saveAs(scattnlaySpectra, 'scattnlay-spectra.txt');
- }
- }
- },
- })
- </script>
|