Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 10 additions & 12 deletions gpu_stack/presets/lithography.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,14 +175,10 @@ def _root_assignments(assignments: dict[str, float]) -> dict[str, float]:
return assignments


def _source_quark_assignments(protons: int, neutrons: int) -> dict[str, int]:
def _source_nucleon_assignments(protons: int, neutrons: int) -> dict[str, int]:
return {
"physical.lithography.source_valence_up_quark_count": (
2 * protons + neutrons
),
"physical.lithography.source_valence_down_quark_count": (
protons + 2 * neutrons
),
"physical.lithography.source_proton_count": protons,
"physical.lithography.source_neutron_count": neutrons,
}


Expand Down Expand Up @@ -242,18 +238,20 @@ def asml_euv_public_context_inventory() -> tuple[dict[str, object], ...]:
name="source_tin_120_composition_assumption",
description=(
"Assumption-labeled source-species composition closure for a 120Sn "
"tin plasma source, encoded through exact valence-quark root counts."
"tin plasma source, encoded at the proton-count and neutron-count "
"root layer."
),
assignments=_root_assignments(
_source_quark_assignments(protons=50, neutrons=70)
_source_nucleon_assignments(protons=50, neutrons=70)
),
source=_NIST_TIN_ATOMIC_DATA_SOURCE,
notes=(
"This preset says: model the source species as 120Sn for closure. It "
"does not say ASML uses isotopically selected 120Sn.",
"The root assignments are exact quark-count bookkeeping from Z=50 "
"and A=120: U=2Z+N and D=Z+2N. Binding, charge state, screening, "
"ionization, plasma temperature, and laser-drive roots remain open.",
"The root assignments are Z=50 and N=70 for tin-120. Valence quark "
"counts U=2Z+N=170 and D=Z+2N=190 are derived by the scope equations "
"from these root values. Binding, charge state, screening, ionization, "
"plasma temperature, and laser-drive roots remain open.",
),
)

Expand Down
74 changes: 32 additions & 42 deletions gpu_stack/presets/materials.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,52 +118,43 @@ def _root_assignments(assignments: dict[str, int]) -> dict[str, int]:
return assignments


def _source_quark_assignments(protons: int, neutrons: int) -> dict[str, int]:
def _source_nucleon_assignments(protons: int, neutrons: int) -> dict[str, int]:
return {
"physical.lithography.source_valence_up_quark_count": (
2 * protons + neutrons
),
"physical.lithography.source_valence_down_quark_count": (
protons + 2 * neutrons
),
"physical.lithography.source_proton_count": protons,
"physical.lithography.source_neutron_count": neutrons,
}


def _medium_component_quark_assignments(
def _medium_component_nucleon_assignments(
component: str,
protons: int,
neutrons: int,
) -> dict[str, int]:
return {
f"physical.lithography.medium_component_{component}_valence_up_quark_count": (
2 * protons + neutrons
),
f"physical.lithography.medium_component_{component}_valence_down_quark_count": (
protons + 2 * neutrons
),
f"physical.lithography.medium_component_{component}_proton_count": protons,
f"physical.lithography.medium_component_{component}_neutron_count": neutrons,
}


source_hydrogen_1 = Preset(
name="source_hydrogen_1",
description=(
"Composition-only lithography source isotope preset for hydrogen-1 "
"(protium): one proton and zero neutrons, encoded at the valence "
"up/down quark root layer."
"(protium): one proton and zero neutrons, encoded at the proton-count "
"and neutron-count root layer."
),
assignments=_root_assignments(
_source_quark_assignments(protons=1, neutrons=0)
_source_nucleon_assignments(protons=1, neutrons=0)
),
source=_provenance(
(
f"{_NUCLIDE_PROVENANCE} For hydrogen-1: Z=1, A=1, N=0. "
f"{_VALENCE_QUARK_PROVENANCE}"
),
references=(_IUPAC_NUCLIDE, _PARTICLE_DATA_GROUP_QUARK_MODEL),
f"{_NUCLIDE_PROVENANCE} For hydrogen-1: Z=1, A=1, N=0.",
references=(_IUPAC_NUCLIDE,),
),
notes=(
"Composition only; does not assign source binding calibration, "
"screening, plasma, or optical drive roots.",
"Valence quark counts U=2 and D=1 are derived from Z=1, N=0 by "
"the scope equations.",
),
)

Expand All @@ -172,22 +163,21 @@ def _medium_component_quark_assignments(
name="source_oxygen_16",
description=(
"Composition-only lithography source isotope preset for oxygen-16: "
"eight protons and eight neutrons, encoded at the valence up/down "
"quark root layer."
"eight protons and eight neutrons, encoded at the proton-count and "
"neutron-count root layer."
),
assignments=_root_assignments(
_source_quark_assignments(protons=8, neutrons=8)
_source_nucleon_assignments(protons=8, neutrons=8)
),
source=_provenance(
(
f"{_NUCLIDE_PROVENANCE} For oxygen-16: Z=8, A=16, N=8. "
f"{_VALENCE_QUARK_PROVENANCE}"
),
references=(_IUPAC_NUCLIDE, _PARTICLE_DATA_GROUP_QUARK_MODEL),
f"{_NUCLIDE_PROVENANCE} For oxygen-16: Z=8, A=16, N=8.",
references=(_IUPAC_NUCLIDE,),
),
notes=(
"Composition only; does not assign source binding calibration, "
"screening, plasma, or optical drive roots.",
"Valence quark counts U=24 and D=24 are derived from Z=8, N=8 by "
"the scope equations.",
),
)

Expand All @@ -196,31 +186,31 @@ def _medium_component_quark_assignments(
name="source_tin_120",
description=(
"Composition-only EUV lithography source isotope preset for "
"tin-120: fifty protons and seventy neutrons, encoded only at the "
"source valence up/down quark root layer."
"tin-120: fifty protons and seventy neutrons, encoded at the "
"proton-count and neutron-count root layer."
),
assignments=_root_assignments(
_source_quark_assignments(protons=50, neutrons=70)
_source_nucleon_assignments(protons=50, neutrons=70)
),
source=_provenance(
(
"ASML establishes molten tin droplets as the laser-produced "
"plasma source material for EUV lithography. CIAAW identifies "
"tin as Z=50 and lists tin-120 as a standard isotope with "
"abundance 0.3258(9), so for tin-120 A=120 and N=70. "
f"{_VALENCE_QUARK_PROVENANCE}"
"abundance 0.3258(9), so for tin-120 A=120 and N=70."
),
references=(
_ASML_EUV_TIN_LPP,
_CIAAW_TIN_ISOTOPIC_COMPOSITION,
_PARTICLE_DATA_GROUP_QUARK_MODEL,
),
),
notes=(
"Composition only; does not assign source binding calibration, "
"density, screening, plasma, drive, or optical-response roots.",
"Tin-120 is used as a sourced isotope-level stand-in for the EUV "
"tin source context, not as a natural-abundance mixture preset.",
"Valence quark counts U=170 and D=190 are derived from Z=50, N=70 "
"by the scope equations.",
),
)

Expand All @@ -234,22 +224,20 @@ def _medium_component_quark_assignments(
assignments=_root_assignments(
{
"physical.lithography.medium_component_a_stoichiometric_count": 2,
**_medium_component_quark_assignments("a", protons=1, neutrons=0),
**_medium_component_nucleon_assignments("a", protons=1, neutrons=0),
"physical.lithography.medium_component_b_stoichiometric_count": 1,
**_medium_component_quark_assignments("b", protons=8, neutrons=8),
**_medium_component_nucleon_assignments("b", protons=8, neutrons=8),
}
),
source=_provenance(
(
f"{_WATER_FORMULA_PROVENANCE} {_NUCLIDE_PROVENANCE} "
"Preset maps H2O to component A=hydrogen-1 and component "
"B=oxygen-16 with stoichiometric counts 2:1; "
f"{_VALENCE_QUARK_PROVENANCE}"
"Preset maps H2O to component A=hydrogen-1 (Z=1, N=0) and "
"component B=oxygen-16 (Z=8, N=8) with stoichiometric counts 2:1."
),
references=(
_NIST_WEBBOOK_WATER,
_IUPAC_NUCLIDE,
_PARTICLE_DATA_GROUP_QUARK_MODEL,
),
),
notes=(
Expand All @@ -259,6 +247,8 @@ def _medium_component_quark_assignments(
"Formula-unit proton, neutron, electron, mass, density, and optical "
"response values remain derived resolver outputs or explicit "
"scenario roots outside this composition preset.",
"Valence quark counts for each component are derived from Z and N "
"by the scope equations.",
),
)

Expand Down
92 changes: 92 additions & 0 deletions gpu_stack/presets/nuclear.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,103 @@ def semf_calibration_preset(
).require_source()


_KRANE_SOURCE = (
"K. S. Krane, Introductory Nuclear Physics, John Wiley & Sons, 1988, "
"Table 3.2: semi-empirical mass formula coefficients. "
"aV = 15.5 MeV, aS = 16.8 MeV, aC = 0.72 MeV, aA = 23 MeV, "
"aP = 34 MeV (pairing coefficient, A^(-1/2) convention)."
)

_KRANE_PAIRING_SEMANTICS = (
"Krane's pairing term is delta = +/-aP/sqrt(A) for even-even/odd-odd "
"nuclei; the graph root nuclear_pairing_gap_reference_energy is "
"Delta_pair_ref = aP / sqrt(A_ref) where A_ref is the specific isotope "
"mass number. The caller must supply A_ref to convert aP."
)

KRANE_SEMF_COEFFICIENTS_MEV = {
"a_vol_mev": 15.5,
"a_surf_mev": 16.8,
"a_coul_mev": 0.72,
"a_asym_mev": 23.0,
"a_pairing_mev": 34.0,
}

_KRANE_PAIRING_EXPONENT_NOTE = (
"Krane uses the A^(-1/2) pairing exponent convention. "
"The graph root nuclear_pairing_gap_reference_energy is not directly "
"equal to Krane's aP; it equals aP / sqrt(A_ref) for the reference "
"mass number A_ref of the specific isotope being calibrated."
)


def krane_semf_calibration_preset(*, reference_mass_number: float) -> Preset:
"""
Build a sourced SEMF calibration Preset from Krane's Table 3.2 coefficients.

The four universal coefficients (volume, surface, Coulomb, asymmetry) are
taken directly from Krane (1988). The pairing gap reference energy is
derived as Delta_pair_ref = aP / sqrt(A_ref) where aP = 34 MeV (Krane) and
A_ref is the caller-supplied reference mass number for the specific isotope
being calibrated.

Parameters
----------
reference_mass_number : float
The mass number A of the reference isotope. The pairing gap root will
be set to aP / sqrt(A_ref) in SI joules.

Returns
-------
Preset
A Preset with full source provenance, ready for use with the resolver.
"""
if not isinstance(reference_mass_number, (int, float)) or isinstance(reference_mass_number, bool):
raise ValueError("reference_mass_number must be a positive number")
a_ref = float(reference_mass_number)
if not math.isfinite(a_ref) or a_ref <= 0:
raise ValueError("reference_mass_number must be a finite positive number")

a_vol_j = KRANE_SEMF_COEFFICIENTS_MEV["a_vol_mev"] * MEV_TO_JOULE
a_surf_j = KRANE_SEMF_COEFFICIENTS_MEV["a_surf_mev"] * MEV_TO_JOULE
a_coul_j = KRANE_SEMF_COEFFICIENTS_MEV["a_coul_mev"] * MEV_TO_JOULE
a_asym_j = KRANE_SEMF_COEFFICIENTS_MEV["a_asym_mev"] * MEV_TO_JOULE
a_pair_mev = KRANE_SEMF_COEFFICIENTS_MEV["a_pairing_mev"]
delta_pair_ref_j = (a_pair_mev / math.sqrt(a_ref)) * MEV_TO_JOULE

return semf_calibration_preset(
name=f"krane_semf_a_ref_{int(a_ref):d}",
description=(
f"SEMF calibration from Krane (1988) Table 3.2, calibrated for "
f"reference mass number A = {int(a_ref)}. Four universal "
"coefficients (aV, aS, aC, aA) plus pairing gap reference energy "
"Delta_pair_ref = aP / sqrt(A_ref)."
),
assignments={
"physical.lithography.nuclear_binding_volume_coefficient": a_vol_j,
"physical.lithography.nuclear_binding_surface_coefficient": a_surf_j,
"physical.lithography.nuclear_binding_coulomb_coefficient": a_coul_j,
"physical.lithography.nuclear_binding_asymmetry_coefficient": a_asym_j,
"physical.lithography.nuclear_pairing_gap_reference_energy": delta_pair_ref_j,
},
source_text=_KRANE_SOURCE,
notes=(
_KRANE_PAIRING_EXPONENT_NOTE,
f"Reference mass number A_ref = {int(a_ref)} was supplied by the caller.",
f"Delta_pair_ref = {a_pair_mev:.1f} / sqrt({int(a_ref)}) "
f"= {a_pair_mev / math.sqrt(a_ref):.6f} MeV "
f"= {delta_pair_ref_j:.6e} J.",
),
)


__all__ = [
"KRANE_SEMF_COEFFICIENTS_MEV",
"MEV_TO_JOULE",
"MEV_TO_JOULE_SOURCE",
"NUCLEAR_PAIRING_GAP_REFERENCE_ENERGY_ROOT",
"SEMF_CALIBRATION_ROOTS",
"krane_semf_calibration_preset",
"mev_to_joule",
"semf_calibration_root_inventory",
"semf_calibration_preset",
Expand Down
26 changes: 10 additions & 16 deletions gpu_stack/scopes/physical_lithography_medium_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,32 +40,26 @@
"LITHOGRAPHY_MEDIUM_COMPOSITION_REF",
"lithography_medium_component_a_stoichiometric_count",
"lithography_medium_component_b_stoichiometric_count",
"lithography_medium_component_a_valence_up_quark_count",
"lithography_medium_component_a_valence_down_quark_count",
"lithography_medium_component_b_valence_up_quark_count",
"lithography_medium_component_b_valence_down_quark_count",
"lithography_medium_component_a_proton_count",
"lithography_medium_component_b_proton_count",
"lithography_medium_component_a_neutron_count",
"lithography_medium_component_b_neutron_count",
"lithography_medium_component_a_valence_up_quark_count",
"lithography_medium_component_a_valence_down_quark_count",
"lithography_medium_component_b_valence_up_quark_count",
"lithography_medium_component_b_valence_down_quark_count",
"lithography_medium_component_a_atomic_number",
"lithography_medium_component_b_atomic_number",
"lithography_medium_component_a_isotope_mass_number",
"lithography_medium_component_b_isotope_mass_number",
"ineq_lithography_medium_component_a_stoichiometric_count_at_least_one",
"ineq_lithography_medium_component_b_stoichiometric_count_at_least_one",
"eq_lithography_medium_component_a_proton_count_from_valence_quarks",
"eq_lithography_medium_component_a_neutron_count_from_valence_quarks",
"eq_lithography_medium_component_b_proton_count_from_valence_quarks",
"eq_lithography_medium_component_b_neutron_count_from_valence_quarks",
"ineq_lithography_medium_component_a_valence_quarks_imply_nonnegative_protons",
"ineq_lithography_medium_component_a_valence_quarks_imply_positive_protons",
"ineq_lithography_medium_component_a_valence_quarks_imply_nonnegative_neutrons",
"eq_lithography_medium_component_a_valence_quark_triplet_integrality",
"ineq_lithography_medium_component_b_valence_quarks_imply_nonnegative_protons",
"ineq_lithography_medium_component_b_valence_quarks_imply_positive_protons",
"ineq_lithography_medium_component_b_valence_quarks_imply_nonnegative_neutrons",
"eq_lithography_medium_component_b_valence_quark_triplet_integrality",
"eq_lithography_medium_component_a_valence_up_quark_count_from_zn",
"eq_lithography_medium_component_a_valence_down_quark_count_from_zn",
"eq_lithography_medium_component_b_valence_up_quark_count_from_zn",
"eq_lithography_medium_component_b_valence_down_quark_count_from_zn",
"ineq_lithography_medium_component_a_proton_count_positive",
"ineq_lithography_medium_component_b_proton_count_positive",
"eq_lithography_medium_component_a_atomic_number",
"eq_lithography_medium_component_b_atomic_number",
"eq_lithography_medium_component_a_isotope_mass_number",
Expand Down
Loading
Loading