Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Charge solver #2077

Merged
merged 1 commit into from
Jan 26, 2025
Merged

Charge solver #2077

merged 1 commit into from
Jan 26, 2025

Conversation

marc-flex
Copy link
Contributor

@marc-flex marc-flex commented Nov 19, 2024

Introducing Charge simulations with Devsim.

  • A new class named DevsimConvergenceSettings has been introduced in which users can specify convergence criteria an other Devsim related settings.
  • A new monitor, ChargeSimulationMonitor, has been created that deals with all charge data (C-V curve, charge, doping and potential)
  • The HeatChargeSimulation has been adapted so that it copes with the new simulation type DEVSIM. This includes the plotting function
  • Data arrays IVCurveDataArray and CapacianceDataArray have been created to deal with the I-V and C-V curves and its dimensions in a consistent manner

@momchil-flex @dbochkov-flexcompute for your reference

@marc-flex marc-flex marked this pull request as ready for review November 19, 2024 15:38
@marc-flex
Copy link
Contributor Author

@tylerflex do tell me if you'd prefer someone else to review this.

@marc-flex marc-flex requested a review from tylerflex November 19, 2024 15:40
@marc-flex marc-flex added the 2.8 will go into version 2.8.* label Nov 19, 2024
@marc-flex marc-flex self-assigned this Nov 19, 2024
@tylerflex tylerflex requested review from dbochkov-flexcompute and daquinteroflex and removed request for tylerflex November 19, 2024 16:59
Copy link
Collaborator

@daquinteroflex daquinteroflex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did a first pass through it, want to look into it in a bit more detail afterwards possibly as we chat.

I guess most of my comments are actually semi-philosophical implementation questions that are kind of open and a bit in the air anyways - so quite interested to hear everyone's related future vision-thoughts on integration considerations!

But looks incredible, such a great effort and really well done - congrats Marc! Really cool that it's coming together quite nicely 💪

Copy link
Contributor

@dbochkov-flexcompute dbochkov-flexcompute left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some initial comments and questions. Definitely, will give a couple more passes. Major comments so far:

  • It seems currently we have only one monitor type for charge simulations that returns all data. This seems to contradict the approach we took with fdtd simulations, where we have separate monitors or each type of data, like FieldMonitor, FluxMonitor, PermittivityMonitor, etc. This also allows to record and transfer only data which is needed. For example, if I am solving charge equations to compute waveguide index change due to free carriers I would like to download only free carrier concentrations. If my waveguide index change is due to electric field, then I would only want to download that (or potential). Would there be any issues with following that approach? Meaning having something like PotentialMonitor, FreeCarriersMonitor, CapacitanceMonitor, CurrentMonitor, etc?
  • From what I understand currently setting electric_spec to SemiConductorSpec means that the material is silicon. Would it make sense to generalize SemiConductorSpec and make it have explicit parameters that go into material model inside the charge solver? Like mobilities, effective mass, life time, bandgap, etc

@marc-flex
Copy link
Contributor Author

marc-flex commented Nov 26, 2024

  • It seems currently we have only one monitor type for charge simulations that returns all data. This seems to contradict the approach we took with fdtd simulations, where we have separate monitors or each type of data, like FieldMonitor, FluxMonitor, PermittivityMonitor, etc. This also allows to record and transfer only data which is needed. For example, if I am solving charge equations to compute waveguide index change due to free carriers I would like to download only free carrier concentrations. If my waveguide index change is due to electric field, then I would only want to download that (or potential). Would there be any issues with following that approach? Meaning having something like PotentialMonitor, FreeCarriersMonitor, CapacitanceMonitor, CurrentMonitor, etc?

No problem at all with that. I just thought it'd be annoying to have to rerun a simulation if, say, you wanted to retrieve what the electric potential looks like. Currently modifying this behavior along the lines you suggested above

  • From what I understand currently setting electric_spec to SemiConductorSpec means that the material is silicon. Would it make sense to generalize SemiConductorSpec and make it have explicit parameters that go into material model inside the charge solver? Like mobilities, effective mass, life time, bandgap, etc

Yes, 100%. Right now, thought, what I'm not sure about is what to do with the model parameters. Currently I have these for Si:

Si = {
    # Properties at 300K
    "Nc": 2.86e19,  # cm^(-3)
    "Nv": 3.1e19,  # cm^(-3)
    "Eg": 1.11,  # eV
    "Chi": 4.05,  # V (electron affinity) from lumerical
    # auger recombination parameters
    "Cn": 2.8e-31,  # cm^6/s
    "Cp": 9.9e-32,  # cm^6/s
    # Radiative recombination parameters
    "Rr": 1.6e-14,  # cm^3/s
    # mobility parameters
    # Cuaghey-Thomas model as implemented in Lumerical
    "eta1": -0.57,
    "eta2": 2.4,
    "eta3": -0.146,
    "N300_n": 9.68e16,
    "mu_min300_n": 52.2 * 1e8,
    "p300_n": 0.68,
    "N300_p": 2.23e17,
    "mu_min300_p": 44.9 * 1e8,
    "p300_p": 0.719,
}

These models are, in general, dependent on the Material. So my initial thought was to add material to the class:

class SemiConductorDatabase:
    Si = {...}

class SemiConductorSpec(...):
    acceptors: ...
    donors: ...
    material: SemiConductorDatabase = ...

An issue with this approach is that I'd need to expose SemiConductorDatabase to users so that they can modify these parameters (for whatever reason?)

All this, highlights another task that I have in my pipeline. I.e., currently, all these material models are active by default. I have a task so that users can deactivate these models at will.

@daquinteroflex
Copy link
Collaborator

What is SemiconductorDatabase? Just to think if as a user I'd want to edit it. Is it like the internal mesh model?

@daquinteroflex
Copy link
Collaborator

Also thought Chapter 11.3 of the ngspice documentation might be of interest in terms of inspired data types and simultion configuration parameters https://ngspice.sourceforge.io/docs/ngspice-manual.pdf . If you see some modulator design papers you'll see everyone ultimately is building equivalent circuit models. See this pretty decent paper if you're interested to have in mind ultimately how some of this simulation data could be transformed

@marc-flex
Copy link
Contributor Author

What is SemiconductorDatabase? Just to think if as a user I'd want to edit it. Is it like the internal mesh model?

SemiConductorDatabase would be this:

class SemiConductorDatabase:
    Si = {
      # Properties at 300K
      "Nc": 2.86e19,  # cm^(-3)
      "Nv": 3.1e19,  # cm^(-3)
      "Eg": 1.11,  # eV
      "Chi": 4.05,  # V (electron affinity) from lumerical
      # auger recombination parameters
      "Cn": 2.8e-31,  # cm^6/s
      "Cp": 9.9e-32,  # cm^6/s
      # Radiative recombination parameters
      "Rr": 1.6e-14,  # cm^3/s
      # mobility parameters
      # Cuaghey-Thomas model as implemented in Lumerical
      "eta1": -0.57,
      "eta2": 2.4,
      "eta3": -0.146,
      "N300_n": 9.68e16,
      "mu_min300_n": 52.2 * 1e8,
      "p300_n": 0.68,
      "N300_p": 2.23e17,
      "mu_min300_p": 44.9 * 1e8,
      "p300_p": 0.719,
  }

Basically it'd store all model parameters associated with the material.

@marc-flex
Copy link
Contributor Author

Also thought Chapter 11.3 of the ngspice documentation might be of interest in terms of inspired data types and simultion configuration parameters https://ngspice.sourceforge.io/docs/ngspice-manual.pdf . If you see some modulator design papers you'll see everyone ultimately is building equivalent circuit models. See this pretty decent paper if you're interested to have in mind ultimately how some of this simulation data could be transformed

Thanks @daquinteroflex, I'll be reading through this!

@dbochkov-flexcompute
Copy link
Contributor

These models are, in general, dependent on the Material. So my initial thought was to add material to the class:

would it make sense to do something like:

class SemiConductorSpec:
    valence_dos: PositiveFloat = pd.field(...)
    conduction_dos: PositiveFloat = pd.field(...)
    band_gap: PositiveFloat = pd.field(...)
    electron_affinity: float = pd.field(...)
    mobility_model: MobilityModelType = pd.field(...)
    recombination_models: Tuple[RecombinationModelType] = pd.field(...)

then to define a material one would do

si_spec = td.SemiConductorSpec(
    valence_dos=...,
    conduction_dos=...,
    band_gap=...,
    electron_affinity=...,
    mobility_model=td.CuagheyThomasMobility(...)
    recombination_models=[
        AugerRecombination(...),
        RadiativeRecombination(...),
    ]
)

so that depending on material different models can swapped, added, removed, etc?

@marc-flex
Copy link
Contributor Author

While I like the solution you propose, this implies that the user must know what values to add depending on the material. So far, I'm coding this with default values for Silicon but maybe we should consider having a database for these models for other semiconductors.

@daquinteroflex
Copy link
Collaborator

daquinteroflex commented Nov 28, 2024

So just to add, this is kind of a complicated topic. For example, say this type of semiconductor spec can be defined in other tools - but it can be extremely difficult to know how to define these models. However, advanced users do need to have an interface for these material definitions and it'd be expected that those users would know how to define this. However, we need to make sure we can abstract on top of this and provide the most common easy-to-use models for the most common materials that can accurately represent the device physics.

There are multiple research groups that do their own photonic device fabrication in house, and they have different recipes in the cleanroom that can change like crystal alginments(polarization) etc. properties that directly affects RF electrostatic perturbation, device purity, etc. I think ultimately we want to give them tools to try to match simulations to their fabrication by enabling them to access the lower level fundamental material representations (on the lines maybe of CustomMedium) and abstract for common materials. This way people manufacturing say custom GaAs or LiNiO3 active devices can still model them. Maybe we can think about how to progressively implement this anyway as to not completely write everything now - but we might want to think about this in the background.

It sounds like something on the lines of this SemiconductorSpec could do the trick. However, it'd be good to check that it's not just silicon specific and can be defined as broadly complete for other materials in order not to have to change it largely later. My main concern is that I'd want to be sure that we're including the core properties of these different active materials at the most fundamental level, and abstract from that for simple use.

@marc-flex marc-flex force-pushed the marc/dd-devsim branch 2 times, most recently from 7c2399e to 73ef52f Compare November 30, 2024 15:30
@marc-flex
Copy link
Contributor Author

Thanks @daquinteroflex @dbochkov-flexcompute @momchil-flex for all the comments.
I have addressed your suggestions and comments. If you have another look you'll notice some parts have changed significantly, namely, monitor_data.py and charge_settings.py. New naming for the DataArrays have been modified as suggested by @daquinteroflex.

This has, consequently, influenced the backend PR, which has been updated accordingly. Any more suggestions/comments are welcome!

description="A current source",
units=CURRENT_DENSITY,
)
# TODO translation between currentsource amps and currentdensity, why not amps here?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also this @marc-flex

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd just remove the TODO and maybe open an issue to support the integral quantity in the future?

The main issue here is that, as far as I know, there isn't an easy way to get the area of a contact in the heat solver before you start simulating. Even if this is not currently supported, it shouldn't the end of the world to implement it.

I guess the second issue is a mathematical one. If one imposes an integral quantity as BC, you're forcing the solution to have uniform flux through a surface which may not make much sense depending on the geometry.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like an important functionality also for RF as per Damian's comments. Yeah also in the future we might want to specify a varying current intensity for a given area so probably need to extend this type of definition in a slightly different way eventually. (or compute the total effective current for a given area etc. as observed for DC frequencies)

@daquinteroflex daquinteroflex mentioned this pull request Jan 17, 2025
4 tasks
Copy link
Contributor

@dbochkov-flexcompute dbochkov-flexcompute left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addition to comments below, probably my major concern is about that all charge medium models have default values for Si. I think this can be extremely dangerous. For example, if I want to define a SemicondutorMedium specification for, say, Ge, then I would need to remember all the parameters and models that I need to change and which would be otherwise set to Si values. I think not having any default parameters and let it just error if not provided is safer. While this example specification for Si with charge models and parameters could be added to materials_library dictionary. Maybe as _multiphysicsSi to highlight it's a temporary convenience until materials_library is properly generalized to multiphysics mediums?

@daquinteroflex
Copy link
Collaborator

daquinteroflex commented Jan 20, 2025

In addition to comments below, probably my major concern is about that all charge medium models have default values for Si. I think this can be extremely dangerous. For example, if I want to define a SemicondutorMedium specification for, say, Ge, then I would need to remember all the parameters and models that I need to change and which would be otherwise set to Si values. I think not having any default parameters and let it just error if not provided is safer. While this example specification for Si with charge models and parameters could be added to materials_library dictionary. Maybe as _multiphysicsSi to highlight it's a temporary convenience until materials_library is properly generalized to multiphysics mediums?

Yep, agree, am implementing the silicon library in #2180 (comment)

EDIT: Sorted now.

Copy link
Contributor

@dbochkov-flexcompute dbochkov-flexcompute left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just trying to catch anything small. I noticed that many new introduced fields don't have units=... specified, I commented under one, but saw many others

"""The sigma parameter of the pseudo-gaussian"""
return np.sqrt(-self.width * self.width / 2 / np.log(self.ref_con / self.concentration))

def get_contrib(self, coords: dict, meshgrid: bool = True):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this a user-facing function? if not, can rename it as _get_contrib

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be used by users to validate their own dopings. I guess that's why I made a test specific for this function. Though I doubt they'll ever use it? So happy to change the name

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find it useful to not expose such functions to the user by adding a _, so that if I need to change something later I don't need to worry about backward compatibility

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. I'll change it to have _

@marc-flex marc-flex force-pushed the marc/dd-devsim branch 2 times, most recently from ed78fc8 to 9a371e7 Compare January 24, 2025 16:34
@daquinteroflex daquinteroflex force-pushed the marc/dd-devsim branch 3 times, most recently from 708f8e3 to a7c3c62 Compare January 24, 2025 17:43
Co-authored-by: Dario Quintero <dario@flexcompute.com>
@marc-flex marc-flex merged commit 948098a into pre/2.8 Jan 26, 2025
15 checks passed
@marc-flex marc-flex deleted the marc/dd-devsim branch January 26, 2025 07:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2.8 will go into version 2.8.* Charge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants