Photonics

Photonics

Topics related to Lumerical and more.

Flexible Material Plugin Issue

    • jonathan.atkinson
      Subscriber
      Good Afternoon,
       
      I am a Post Doc at the University of Toronto in the Department of ECE in the Amr Helmy group.  We have a department Ansys account.  I am looking to adapt a flexible material plugin for Two Photon Absorption (TPA) based on C++ that was originally developed by the following source "Integrated Nanoplasmonic Waveguides and Devices for All-Optical Nanocircuitry" as recommended on a previous Ansys Forum post.  There are 3 files in the appendix of the thesis and I have attached them all.  I understand I need a .dll file in the material plugin folder for this to work in Lumerical.  However none of the 3 files seems to generate a .dll file or us a main{} function in the code which is required in C++.  Is there a "make" file that I need to do this to generate the .dll file?  I am a little confused as to how this work.  Any help would be greatly appreciated.  
       
      Best Regards,
       
      Jon Atkinson
       
      Si_TPA.cpp:
       
      #include "SiTPA.h"
      #include
      /*!
      \class NSiTPAPlugin
      For studying TPA and free carrier effects in Si in the telecom wavelengths
      around 1.55um.
      Based on the FDTD formulism for TPA and free carrier effects from [1].
      Does not take into account linear absorption and dispersive refractive
      index (assumes you use Si as the base material in Lumerical), and does not
      currently have Kerr or Raman effects (since these
      occur on a different scale than TPA and free carrier effects). All units are
      standard SI.
      [1] N. Suzuki, "FD-TD Analysis of Two-Photon Absorption and Free
      Carrier Absorption in Si High-Index-Contrast Waveguides," Journal of Lightwave
      Technology 25, 2495 (2007).
      */
      const double SiTPAPlugin::hbar = 1.05457148e-34; // [J/s]
      const double SiTPAPlugin::exp = 0.8; //constant
      const double SiTPAPlugin::eps0 = 8.854187817e-12; //vacuum permitivity [F/m]
      const double SiTPAPlugin::c = 2.99792458e8; //speed of light [m/s]
      const double SiTPAPlugin::tau = 1e-12; //free carrier recombination time in
      oxygen doped silicon[s]
      const double SiTPAPlugin::n0 = 3.48; //refractive index of Si at 1.55um
      const double SiTPAPlugin::betaTPA = 0.9e-11; // [m/W]
      const double SiTPAPlugin::pi = 3.1415926535897931;
      const double SiTPAPlugin::Nfi = 1.01e16; //[m^-3] intrinsic free carrier density
      of Si
      const char* SiTPAPlugin::names[4] = {"Peak Intensity of Input Pulse [W/m^2]",
      "Center Wavelength of Input Pulse [m]","Initial Free Carrier Concentration [m^- 3]", 0};
      void SiTPAPlugin::initialize(const double** parameters, double dt)
      {
      d_t=dt;
          for(int i=0; i<3; i++){
      Ip[i] = double(parameters[0][i]);
      lambda0[i] = float(parameters[1][i]);
      N_initial[i] = double(parameters[2][i]);
      lambda_n[i]=lambda0[i]/1.55e-6;
      }
      }
      float SiTPAPlugin::calculate(int i, float U, float V, float Et, float* storage)
      {
      double Nf = storage[0];
      double n_plasma_n = storage[1];
      double Vn = storage[2];
      double Un = storage[3];
      double En = double(Et);
      double E = double(Et);
      float firstUpdateDone = storage[4];
       
      n=1.;
       
      Nf = (2.*tau- d_t)/(2.*tau+d_t)*Nf+tau*d_t/(2.*tau+d_t)*lambda0[i]/2./pi/c/hbar*betaTPA*Ip[i
      ]*Ip[i]*abs(En*En*En*En); //free carrier concentration
      if (firstUpdateDone == 0.) //initial free carrier concentration
      Nf = N_initial[i];
      if (Nf
      for silicon
      Nf=Nfi;
       
      firstUpdateDone = 1.;
      n_plasma=-8.8e-28*Nf-8.5e- 24*(pow(Nf,exp))*lambda_n[i]*lambda_n[i]; //change in refractive index due to
      plasma dispersion
       
      //loop for iterating E field and effect of chi_TPA and chi_FCA. 6
      iterations was determiend to be sufficient for convergence
      while (n<6){
      g1=2*n0*n_plasma+c*n0*(1.45e- 21*lambda_n[i]*lambda_n[i]*Nf)*d_t/2+c*c*eps0*n0*n0*betaTPA*d_t*(E*E+
      En*En)*Ip[i]/8;
      g2=2*n0*n_plasma_n-c*n0*(1.45e- 21*lambda_n[i]*lambda_n[i]*Nf)*d_t/2- c*c*eps0*n0*n0*betaTPA*d_t*(E*E+En*En)*Ip[i]/8;
      E=1/(g1+U)*(g2*En+(V-Vn)+Un*En);
      n=n+1;
      }
       
      //update storage
      storage[0] = Nf;
      storage[1] = n_plasma;
      storage[2] = V;
      storage[3] = U;
      storage[4] = float(firstUpdateDone);
       
           return E;
      }
      float SiTPAPlugin::calculateEx( float U, float V, float Ex, float* storage )
      {
      return calculate(0, U, V, Ex, storage);
      }
      float SiTPAPlugin::calculateEy( float U, float V, float Ey, float* storage )
      {
      return calculate(1, U, V, Ey, storage);
      }
      float SiTPAPlugin::calculateEz( float U, float V, float Ez, float* storage )
      {
      return calculate(2, U, V, Ez, storage);
      }
      MATERIAL_PLUGIN(SiTPAPlugin);
       
      Si_TPA.h:
       
      #ifndef _SITPA_H
      #define _SITPA_H
       
      #include "imaterialplugin.h"
       
      class SiTPAPlugin : public IMaterialPlugin
      {
      public:
      SiTPAPlugin(){};
      virtual ~SiTPAPlugin(){};
       
      const char* name() const {return "SiTPA";};
      const char* uniqueId() const {return "{CFE9991C-6837-46a2-BBB4- E9EABD833DFC}";};
      const char** parameterNames() const {return names;};
      float calculateEx( float U, float V, float Ex, float* storage);
      float calculateEy( float U, float V, float Ey, float* storage);
      float calculateEz( float U, float V, float Ez, float* storage);
      void initialize(const double** parameters, double dt);
      void initializeStorageEx(float* storage){};
      void initializeStorageEy(float* storage){};
      void initializeStorageEz(float* storage){};
      size_t storageSizeE() const {return 5;}; //# of additional storage fields
       
      private:
      float calculate(int axis, float U, float V, float E, float* storage);
      void initializeStorageE(int axis, float* storage);
       
      static const double hbar;
      static const double eps0;
      static const double tau;
      static const double betaTPA;
      static const double n0;
      static const double exp;
      static const double c;
      static const double pi;
      static const double Nfi;
       
      double Ip[3];
      double N_initial[3];
      double lambda0[3];
      double Nf[3];
      double g1;
      double g2;
      double n_plasma;
      double n_plasma_n;
      double d_t;
      float n;
      float lambda_n[3];
       
      static const char* names[4];
      };
       
      #endif
       
      immaterialplugin:
       
      #ifndef _IMATERIALPLUGIN_H
      #define _IMATERIALPLUGIN_H
       
      #include
       
      /*!
      \brief The interface class definition for a material plugin for FDTD Solutions
       
      This pure abstract class defines the methods that must be implemented to create
      a plugin material in FDTD Solutions. A class that inherits from this interface class
      and implements all the methods can be compiled into a dynamic library that can
      be loaded into FDTD Solutions to define new materials.
      */
       
      class IMaterialPlugin
      {
      public:
      virtual ~IMaterialPlugin(){};
      virtual const char* name() const = 0;
      virtual const char* uniqueId() const = 0;
      virtual const char** parameterNames() const = 0;
      virtual float calculateEx( float U, float V, float Ex, float* storage) = 0;
      virtual float calculateEy( float U, float V, float Ey, float* storage) = 0;
      virtual float calculateEz( float U, float V, float Ez, float* storage) = 0;
      virtual void initialize(const double** parameters, double dt) = 0;
      virtual void initializeStorageEx(float* storage) = 0;
      virtual void initializeStorageEy(float* storage) = 0;
      virtual void initializeStorageEz(float* storage) = 0;
      virtual size_t storageSizeE() const = 0;
      };
       
      /*!
      \brief The interface class for a magnetic material plugin
      This extends the material plugin defined above with a few more methods that
      need to be
      defined for a magnetic material
      */
      class IMagneticMaterialPlugin : public IMaterialPlugin
      {
      public:
      virtual float calculateHx( float U, float V, float Ex, float* storage) = 0;
      virtual float calculateHy( float U, float V, float Ey, float* storage) = 0;
      virtual float calculateHz( float U, float V, float Ez, float* storage) = 0;
      virtual void initializeStorageHx(float* storage) = 0;
      virtual void initializeStorageHy(float* storage) = 0;
      virtual void initializeStorageHz(float* storage) = 0;
      virtual size_t storageSizeH() const = 0;
      };
       
      /*!
      \brief The interface for a factory class that creates and destroys material plugins
      */
      class IMaterialPluginFactory{
      public:
      virtual IMaterialPlugin* createInstance()=0;
      virtual void destroyInstance(IMaterialPlugin* i)=0;
      virtual IMagneticMaterialPlugin* toMagneticMaterialPlugin(IMaterialPlugin*p)=0;
      };
       
      /*!
      \brief A templated implementation of the IMaterialPluginFactory class
       
      Plugin authors do not need to write a factory class, they can just use this class.
      It is written
      as a template so that it can be compiled into the plugin easily. This is done in
      the plugin code
      usign the MATERIAL_PLUGIN(T) macro.
      */
      template
      class MaterialPluginFactory : public IMaterialPluginFactory
      {
      IMaterialPlugin* createInstance(){return new T();}
      void destroyInstance(IMaterialPlugin* i){delete i;}
      IMagneticMaterialPlugin* toMagneticMaterialPlugin(IMaterialPlugin*
      p){return dynamic_cast(p);}
      };
       
      #ifdef WIN32
      #define DLLEXPORT __declspec(dllexport)
      #else
      #define DLLEXPORT
      #endif
       
      //A macro to add the factory function to the plugin, instantiating the
      MaterialPluginFactory in the process
      //All plugins should include this macro once in a source file. The argument T is
      the name of the user's plugin class
      #define MATERIAL_PLUGIN(T) \
         extern "C" DLLEXPORT IMaterialPluginFactory* createFactoryV1(){ return
      new MaterialPluginFactory();} \
         extern "C" DLLEXPORT void destroyFactoryV1(IMaterialPluginFactory* f){
      delete f;}
       
      #endif
       
    • Kyle
      Ansys Employee

      Hello, you can see a demo of compiling material models in the videos on this page: Material Plugins: A Practical Implementation Demo

      I would recommend trying with one of the models provided on this page before trying with a custom model: Advanced and custom optical material models in FDTD and MODE – Ansys Optics

      It might work with a newer version of Visual Studio, but it is best to use Visual Studio 2013.

    • abubakarumar1097
      Subscriber
       

      It sounds like you're on the right track, but it seems the code provided might be incomplete for direct compilation into a .dll file. To create the .dll, you'll likely need to write a main function and set up a makefile or project in Visual Studio that properly compiles the C++ code into the required .dll. If the source files don't include this, you may need to adapt the code to fit into a C++ DLL project structure. Let me know if you'd like help with that!

    • jonathan.atkinson
      Subscriber

      Thank you everyone.

       

      Kyle it seems that I can not download Visual Studios 2013 and unfortunately have to use 2022.  When I build the solution after making a .dll project, it seems the immaterialplugin.h file seems to be the main problem.  I keep getting an unexpected end of file error.  Do you guys have a version that works with newer versions of Visual Studios?  

    • jonathan.atkinson
      Subscriber

      I am still at a loss with this issue.  I am not able to find Microsoft Visual Studio 2013 anywhere.  I was able to compile the fourelectrontwolevel example and get a .dll file.  However, it does not appear in the material explorer when you put it in the correct folder.  I read on another Ansys thread that this is because of the version of the Visual Studios used?  Is there any known way around this issue yet?  Or perhaps I can be directed to get Visual Studios 2013?  My files are correct, it just seems the version is now the problem

    • Kyle
      Ansys Employee

      If you can't get access to VS 2013,  try changing the default preprocessor definitions to those in VS 2013:

      WIN32;NDEBUG;_WINDOWS;_USRDLL;

Viewing 5 reply threads
  • You must be logged in to reply to this topic.