109109HeatSourceTypes = (UniformHeatSource , HeatSource , HeatFromElectricSource )
110110ChargeSourceTypes = ()
111111ElectricBCTypes = (VoltageBC , CurrentBC , InsulatingBC )
112+ ChargeTypes = (
113+ SteadyChargeDCAnalysis ,
114+ IsothermalSteadyChargeDCAnalysis ,
115+ SSACAnalysis ,
116+ IsothermalSSACAnalysis ,
117+ )
118+ ChargeMonitorTypes = (
119+ SteadyPotentialMonitor ,
120+ SteadyFreeCarrierMonitor ,
121+ SteadyCapacitanceMonitor ,
122+ SteadyCurrentDensityMonitor ,
123+ )
112124
113125AnalysisSpecType = Union [ElectricalAnalysisType , UnsteadyHeatAnalysis ]
114126
@@ -683,13 +695,6 @@ def check_freqs_requires_ac_source(cls, values):
683695 def check_charge_simulation (cls , values ):
684696 """Makes sure that Charge simulations are set correctly."""
685697
686- ChargeMonitorType = (
687- SteadyPotentialMonitor ,
688- SteadyFreeCarrierMonitor ,
689- SteadyCapacitanceMonitor ,
690- SteadyCurrentDensityMonitor ,
691- )
692-
693698 simulation_types = cls ._check_simulation_types (values = values )
694699
695700 if TCADAnalysisTypes .CHARGE in simulation_types :
@@ -707,7 +712,7 @@ def check_charge_simulation(cls, values):
707712
708713 # check that we have at least one charge monitor
709714 monitors = values ["monitors" ]
710- if not any (isinstance (mnt , ChargeMonitorType ) for mnt in monitors ):
715+ if not any (isinstance (mnt , ChargeMonitorTypes ) for mnt in monitors ):
711716 raise SetupError (
712717 "Charge simulations require the definition of, at least, one of these monitors: "
713718 "'[SteadyPotentialMonitor, SteadyFreeCarrierMonitor, SteadyCapacitanceMonitor, SteadyCurrentDensityMonitor]' "
@@ -723,7 +728,13 @@ def check_charge_simulation(cls, values):
723728 "Currently, Charge simulations support only unstructured monitors. Please set "
724729 f"monitor '{ mnt .name } ' to 'unstructured = True'."
725730 )
726-
731+ # check that we have at least one semiconductor medium
732+ structures = values ["structures" ]
733+ sc_present = HeatChargeSimulation ._check_if_semiconductor_present (structures = structures )
734+ if not sc_present :
735+ raise SetupError (
736+ f"{ TCADAnalysisTypes .CHARGE } simulations require the definition of at least one semiconductor medium."
737+ )
727738 return values
728739
729740 @pd .root_validator (skip_on_failure = True )
@@ -880,23 +891,23 @@ def _check_simulation_types(
880891
881892 boundaries = list (values ["boundary_spec" ])
882893 sources = list (values ["sources" ])
894+ analysis_spec = values ["analysis_spec" ]
883895
884896 structures = list (values ["structures" ])
897+
898+ if isinstance (analysis_spec , ChargeTypes ):
899+ simulation_types .append (TCADAnalysisTypes .CHARGE )
900+
885901 semiconductor_present = HeatChargeSimulation ._check_if_semiconductor_present (
886902 structures = structures
887903 )
888- if semiconductor_present :
889- simulation_types .append (TCADAnalysisTypes .CHARGE )
890904
891905 for boundary in boundaries :
892906 if isinstance (boundary .condition , HeatBCTypes ):
893907 simulation_types .append (TCADAnalysisTypes .HEAT )
894908 if isinstance (boundary .condition , ElectricBCTypes ):
895- # for the time being, assume tha the simulation will be of
896- # type CHARGE if we have semiconductors
897- if semiconductor_present :
898- simulation_types .append (TCADAnalysisTypes .CHARGE )
899- else :
909+ # Add CONDUCTION type if we have no semiconductors
910+ if not semiconductor_present :
900911 simulation_types .append (TCADAnalysisTypes .CONDUCTION )
901912
902913 for source in sources :
@@ -1060,7 +1071,7 @@ def check_transient_heat(cls, values):
10601071 raise SetupError (
10611072 f"Unsteady simulations require the temperature monitor '{ mnt .name } ' to be unstructured."
10621073 )
1063- # additionaly check that the SolidSpec has capacity and density defined
1074+ # additionally check that the SolidSpec has capacity and density defined
10641075 capacities = []
10651076 densities = []
10661077 conductivities = []
@@ -1115,7 +1126,7 @@ def check_transient_heat(cls, values):
11151126
11161127 @pd .root_validator (skip_on_failure = True )
11171128 def check_non_isothermal_is_possible (cls , values ):
1118- """Make sure that when a non-isothermal case is defined the structrures
1129+ """Make sure that when a non-isothermal case is defined the structures
11191130 have both electrical and thermal properties."""
11201131
11211132 analysis_spec = values .get ("analysis_spec" )
@@ -1492,7 +1503,7 @@ def _construct_forward_boundaries(
14921503 ) -> tuple [tuple [HeatChargeBoundarySpec , Shapely ], ...]:
14931504 """Construct Simulation, StructureSimulation, Structure, and MediumMedium boundaries."""
14941505
1495- # forward foop to take care of Simulation, StructureSimulation, Structure,
1506+ # forward loop to take care of Simulation, StructureSimulation, Structure,
14961507 # and MediumMediums
14971508 boundaries = [] # bc_spec, structure name, shape, bounds
14981509 background_shapes = []
@@ -1583,7 +1594,7 @@ def _construct_reverse_boundaries(
15831594 ) -> tuple [tuple [HeatChargeBoundarySpec , Shapely ], ...]:
15841595 """Construct StructureStructure boundaries."""
15851596
1586- # backward foop to take care of StructureStructure
1597+ # backward loop to take care of StructureStructure
15871598 # we do it in this way because we define the boundary between
15881599 # two overlapping structures A and B, where A comes before B, as
15891600 # boundary(B) intersected by A
@@ -1690,7 +1701,7 @@ def _construct_heat_charge_boundaries(
16901701
16911702 # construct boundaries in 2 passes:
16921703
1693- # 1. forward foop to take care of Simulation, StructureSimulation, Structure,
1704+ # 1. forward loop to take care of Simulation, StructureSimulation, Structure,
16941705 # and MediumMediums
16951706 boundaries = HeatChargeSimulation ._construct_forward_boundaries (
16961707 shapes = shapes ,
@@ -1933,17 +1944,8 @@ def _get_simulation_types(self) -> list[TCADAnalysisTypes]:
19331944 """
19341945 simulation_types = []
19351946
1936- # NOTE: for the time being, if a simulation has SemiconductorMedium
1937- # then we consider it of being a 'TCADAnalysisTypes.CHARGE'
1938- ChargeTypes = (
1939- SteadyChargeDCAnalysis ,
1940- IsothermalSteadyChargeDCAnalysis ,
1941- SSACAnalysis ,
1942- IsothermalSSACAnalysis ,
1943- )
19441947 if isinstance (self .analysis_spec , ChargeTypes ):
1945- if self ._check_if_semiconductor_present (self .structures ):
1946- return [TCADAnalysisTypes .CHARGE ]
1948+ return [TCADAnalysisTypes .CHARGE ]
19471949
19481950 # check if unsteady heat
19491951 if isinstance (self .analysis_spec , UnsteadyHeatAnalysis ):
0 commit comments