From 271681cb4d824c223b4ba33cd0410c9365a85bed Mon Sep 17 00:00:00 2001 From: Martin Bies Date: Mon, 18 Nov 2024 20:07:03 +0100 Subject: [PATCH] [FTheoryTools] Compute all vertical and well-quantized G4-flux ambient space candidates --- experimental/FTheoryTools/docs/src/g4.md | 4 + .../FTheoryTools/src/G4Fluxes/auxiliary.jl | 64 +++++ .../src/G4Fluxes/special_attributes.jl | 272 ++++++++++++++++++ .../src/Serialization/hypersurface_models.jl | 21 ++ .../src/Serialization/tate_models.jl | 21 ++ .../src/Serialization/weierstrass_models.jl | 21 ++ experimental/FTheoryTools/src/exports.jl | 1 + 7 files changed, 404 insertions(+) diff --git a/experimental/FTheoryTools/docs/src/g4.md b/experimental/FTheoryTools/docs/src/g4.md index 06c691c5d1db..fc3fa12e0e52 100644 --- a/experimental/FTheoryTools/docs/src/g4.md +++ b/experimental/FTheoryTools/docs/src/g4.md @@ -87,3 +87,7 @@ Please note that this method may take a long time to execute for involved geomet ```@docs well_quantized_ambient_space_models_of_g4_fluxes(m::AbstractFTheoryModel; check::Bool = true) ``` +Similarly, we have a method for all vertical and well-quantized ambient space $G_4$-flux candidates: +```@docs +well_quantized_and_vertical_ambient_space_models_of_g4_fluxes(m::AbstractFTheoryModel; check::Bool = true) +``` diff --git a/experimental/FTheoryTools/src/G4Fluxes/auxiliary.jl b/experimental/FTheoryTools/src/G4Fluxes/auxiliary.jl index ab90b88c26e9..b6e23108f49d 100644 --- a/experimental/FTheoryTools/src/G4Fluxes/auxiliary.jl +++ b/experimental/FTheoryTools/src/G4Fluxes/auxiliary.jl @@ -225,3 +225,67 @@ function _ambient_space_divisor_pairs_to_be_considered(m::AbstractFTheoryModel): return list_of_elements end + + +# The following is an internal function, that is being used to identify all well-quantized and +# vertical G4-flux ambient candidates. For this, we look for pairs of (pushforwards of) base divisors, +# s.t. their common zero locus does not intersect the CY hypersurface trivially. +# This method makes a pre-selection of such base divisor pairs. "Pre" means that we execute a sufficient, +# but not necessary, check to tell if a pair of base divisors restricts trivially. + +function _ambient_space_base_divisor_pairs_to_be_considered(m::AbstractFTheoryModel)::Vector{Tuple{Int64, Int64}} + + if has_attribute(m, :_ambient_space_base_divisor_pairs_to_be_considered) + return get_attribute(m, :_ambient_space_base_divisor_pairs_to_be_considered) + end + + gS = gens(cox_ring(ambient_space(m))) + mnf = Oscar._minimal_nonfaces(ambient_space(m)) + ignored_sets = Set([Tuple(sort(Vector{Int}(Polymake.row(mnf, i)))) for i in 1:Polymake.nrows(mnf)]) + + list_of_elements = Vector{Tuple{Int64, Int64}}() + for k in 1:n_rays(base_space(m)) + for l in k:n_rays(base_space(m)) + + # V(x_k, x_l) = emptyset? + (k,l) in ignored_sets && continue + + # Simplify the hypersurface polynomial by setting relevant variables to zero. + # If all coefficients of this new polynomial add to sum, then we keep this generator. + new_p_hyper = divrem(hypersurface_equation(m), gS[k])[2] + if k != l + new_p_hyper = divrem(new_p_hyper, gS[l])[2] + end + if sum(coefficients(new_p_hyper)) == 0 + push!(list_of_elements, (k,l)) + continue + end + + # Determine remaining variables, after scaling "away" others. + remaining_vars_list = Set(1:length(gS)) + for my_exps in ignored_sets + len_my_exps = length(my_exps) + inter_len = count(idx -> idx in [k,l], my_exps) + if (len_my_exps == 2 && inter_len == 1) || (len_my_exps == 3 && inter_len == 2) + delete!(remaining_vars_list, my_exps[findfirst(idx -> !(idx in [k,l]), my_exps)]) + end + end + remaining_vars_list = collect(remaining_vars_list) + + # If one monomial of `new_p_hyper` has unset positions (a.k.a. new_p_hyper is not constant upon + # scaling the remaining variables), then keep this generator. + for exps in exponents(new_p_hyper) + if any(x -> x != 0, exps[remaining_vars_list]) + push!(list_of_elements, (k,l)) + break + end + end + + end + end + + # Remember this result as attribute and return the findings. + set_attribute!(m, :_ambient_space_base_divisor_pairs_to_be_considered, list_of_elements) + return list_of_elements + +end diff --git a/experimental/FTheoryTools/src/G4Fluxes/special_attributes.jl b/experimental/FTheoryTools/src/G4Fluxes/special_attributes.jl index 9b9750e2fba1..6c99c847a4ef 100644 --- a/experimental/FTheoryTools/src/G4Fluxes/special_attributes.jl +++ b/experimental/FTheoryTools/src/G4Fluxes/special_attributes.jl @@ -293,3 +293,275 @@ function well_quantized_ambient_space_models_of_g4_fluxes(m::AbstractFTheoryMode return res end + + +@doc raw""" + well_quantized_and_vertical_ambient_space_models_of_g4_fluxes(m::AbstractFTheoryModel; check::Bool = true)::Tuple{QQMatrix, QQMatrix} + +Given an F-theory model $m$ defined as hypersurface in a simplicial and +complete toric base, this method computes a basis of all well-quantized +and vertical ambient space $G_4$-fluxes. The result of this operation is a +tuple of two matrices. The columns of the first matrix specify those (rational) +combinations of ambient space $G_4$-fluxes, of which one may only take +$\mathbb{Z}$-linear combinations without violating flux quantization. The columns +of the second matrix specify those (rational) combinations of ambient space +$G_4$-fluxes, for which any rational linear combination satisfies the flux +quantization condition. + +It can be computationally very demanding to check if a toric variety +$X$ is complete (and simplicial). The optional argument `check` can be set +to `false` to skip these tests. + +# Examples +```jldoctest; setup = :(Oscar.LazyArtifacts.ensure_artifact_installed("QSMDB", Oscar.LazyArtifacts.find_artifacts_toml(Oscar.oscardir))) +julia> B3 = projective_space(NormalToricVariety, 3) +Normal toric variety + +julia> Kbar = anticanonical_divisor_class(B3) +Divisor class on a normal toric variety + +julia> t = literature_model(arxiv_id = "1109.3454", equation = "3.1", base_space = B3, defining_classes = Dict("w"=>Kbar)) +Construction over concrete base may lead to singularity enhancement. Consider computing singular_loci. However, this may take time! + +Global Tate model over a concrete base -- SU(5)xU(1) restricted Tate model based on arXiv paper 1109.3454 Eq. (3.1) + +julia> res = well_quantized_and_vertical_ambient_space_models_of_g4_fluxes(t, check = false); + +julia> res[1] +2 by 0 empty matrix + +julia> res[2] +2 by 0 empty matrix +``` +""" +function well_quantized_and_vertical_ambient_space_models_of_g4_fluxes(m::AbstractFTheoryModel; check::Bool = true)::Tuple{QQMatrix, QQMatrix} + + # (1) Entry checks + @req base_space(m) isa NormalToricVariety "Computation of well-quantized G4-fluxes only supported for toric base and ambient spaces" + @req dim(ambient_space(m)) == 5 "Computation of well-quantized G4-fluxes only supported for 5-dimensional toric ambient spaces" + if check + @req is_complete(ambient_space(m)) "Computation of well-quantized G4-fluxes only supported for complete toric ambient spaces" + @req is_simplicial(ambient_space(m)) "Computation of well-quantized G4-fluxes only supported for simplicial toric ambient space" + end + if has_attribute(m, :well_quantized_and_vertical_ambient_space_models_of_g4_fluxes) + return get_attribute(m, :well_quantized_and_vertical_ambient_space_models_of_g4_fluxes) + end + + + # (2) Compute data, that is frequently used by the sophisticated intersection product below + S = cox_ring(ambient_space(m)) + gS = gens(cox_ring(ambient_space(m))) + linear_relations = matrix(QQ, matrix(ZZ, rays(ambient_space(m)))) + scalings = [c.coeff for c in S.d] + mnf = Oscar._minimal_nonfaces(ambient_space(m)) + sr_ideal_pos = [Vector{Int}(Polymake.row(mnf, i)) for i in 1:Polymake.nrows(mnf)] + data = ( + S = S, + gS = gS, + linear_relations = linear_relations, + scalings = scalings, + sr_ideal_pos = sr_ideal_pos + ) + + + # (3) Are intersection numbers known? + inter_dict = Dict{NTuple{4, Int64}, QQFieldElem}() + s_inter_dict = Dict{String, QQFieldElem}() + if has_attribute(m, :inter_dict) + inter_dict = get_attribute(m, :inter_dict) + end + if has_attribute(m, :s_inter_dict) + s_inter_dict = get_attribute(m, :s_inter_dict) + end + + + # (4) Obtain critical information - this may take significant time! + ambient_space_flux_candidates_basis = ambient_space_models_of_g4_fluxes(m, check = check) + list_of_base_divisor_pairs_to_be_considered = Oscar._ambient_space_base_divisor_pairs_to_be_considered(m) + list_of_divisor_pairs_to_be_considered = Oscar._ambient_space_divisor_pairs_to_be_considered(m) + + + # (5) Work out the relevant intersection numbers to tell if a flux is vertical + vertical_constraint_matrix = Vector{Vector{QQFieldElem}}() + if arxiv_doi(m) == "10.48550/arXiv.1511.03209" + + # Use special intersection theory for special F-theory model. This technology could be extended beyond this one use-case in the future. + for i in 1:length(ambient_space_flux_candidates_basis) + + condition = Vector{ZZRingElem}() + idxs = findall(x -> x != 0, collect(exponents(polynomial(ambient_space_flux_candidates_basis[i]).f))[1]) + if length(idxs) == 1 + idxs = [idxs[1], idxs[1]] + end + + # Compute against pairs of base divisors + for j in 1:length(list_of_base_divisor_pairs_to_be_considered) + + my_tuple = Tuple(sort([idxs..., list_of_base_divisor_pairs_to_be_considered[j]...])) + push!(condition, sophisticated_intersection_product(ambient_space(m), my_tuple, hypersurface_equation(m), inter_dict, s_inter_dict, data)) + + end + + # Compute against zero section and base divisor + pos_zero_section = findfirst(x -> x == "z", string.(gS)) + for j in 1:n_rays(base_space(m)) + + my_tuple = Tuple(sort([idxs..., [j, pos_zero_section]...])) + push!(condition, sophisticated_intersection_product(ambient_space(m), my_tuple, hypersurface_equation(m), inter_dict, s_inter_dict, data)) + + end + + push!(vertical_constraint_matrix, condition) + + end + + else + + # Cover all other case with generic, but potentially painfully slow methodology. + tds = torusinvariant_prime_divisors(ambient_space(m)) + cds = [cohomology_class(tds[i]) for i in 1:length(tds)] + pt_class = cohomology_class(anticanonical_divisor_class(ambient_space(m))) + for i in 1:length(ambient_space_flux_candidates_basis) + + condition = Vector{QQFieldElem}() + + idxs = findall(x -> x != 0, collect(exponents(polynomial(ambient_space_flux_candidates_basis[i]).f))[1]) + if length(idxs) == 1 + idxs = [idxs[1], idxs[1]] + end + + # Compute against pairs of base divisors + for j in 1:length(list_of_divisor_pairs_to_be_considered) + + my_tuple = Tuple(sort([idxs..., list_of_divisor_pairs_to_be_considered[j]...])) + if !haskey(inter_dict, my_tuple) + class = ambient_space_flux_candidates_basis[i] * cds[list_of_divisor_pairs_to_be_considered[j][1]] * cds[list_of_divisor_pairs_to_be_considered[j][2]] * pt_class + inter_dict[my_tuple] = integrate(class) + end + push!(condition, inter_dict[my_tuple]) + + end + + # Compute against zero section and base divisor + zsc = zero_section_class(m) + pos_zero_section = findfirst(x -> x == string(polynomial(zsc).f), string.(gS)) + @req pos_zero_section !== nothing && pos_zero_section >= 1 "Could not establish position of the zero section" + for j in 1:n_rays(base_space(m)) + my_tuple = Tuple(sort([idxs..., [j, pos_zero_section]...])) + if !haskey(inter_dict, my_tuple) + class = ambient_space_flux_candidates_basis[i] * cds[j] * zsc * pt_class + inter_dict[my_tuple] = integrate(class) + end + push!(condition, inter_dict[my_tuple]) + + end + + push!(vertical_constraint_matrix, condition) + + end + + end + + + # (6) Compute the vertical fluxes as the kernel of the vertical_constraint_matrix. + # (6) To later tell if those fluxes are properly quantized, we want to parametrize them with integer coefficient only. + denom = lcm(unique(vcat([denominator.(k) for k in vertical_constraint_matrix]...))) + if denom != 1 + vertical_constraint_matrix = denom * vertical_constraint_matrix + end + C_vertical = transpose(matrix(ZZ, vertical_constraint_matrix)) + vertical_fluxes = nullspace(C_vertical)[2] + + + # (7) Work out the relevant intersection numbers to tell if a flux is well quantized + quant_constraint_matrix = Vector{Vector{QQFieldElem}}() + if arxiv_doi(m) == "10.48550/arXiv.1511.03209" + + # Use special intersection theory for special F-theory model. This technology could be extended beyond this one use-case in the future. + for i in 1:length(ambient_space_flux_candidates_basis) + condition = Vector{ZZRingElem}() + idxs = findall(x -> x != 0, collect(exponents(polynomial(ambient_space_flux_candidates_basis[i]).f))[1]) + if length(idxs) == 1 + idxs = [idxs[1], idxs[1]] + end + + for j in 1:length(list_of_divisor_pairs_to_be_considered) + + my_tuple = Tuple(sort([idxs..., list_of_divisor_pairs_to_be_considered[j]...])) + push!(condition, sophisticated_intersection_product(ambient_space(m), my_tuple, hypersurface_equation(m), inter_dict, s_inter_dict, data)) + + end + push!(quant_constraint_matrix, condition) + end + + else + + # Cover all other case with generic, but potentially painfully slow methodology. + tds = torusinvariant_prime_divisors(ambient_space(m)) + cds = [cohomology_class(tds[i]) for i in 1:length(tds)] + pt_class = cohomology_class(anticanonical_divisor_class(ambient_space(m))) + for i in 1:length(ambient_space_flux_candidates_basis) + + condition = Vector{QQFieldElem}() + + idxs = findall(x -> x != 0, collect(exponents(polynomial(ambient_space_flux_candidates_basis[i]).f))[1]) + if length(idxs) == 1 + idxs = [idxs[1], idxs[1]] + end + + for j in 1:length(list_of_divisor_pairs_to_be_considered) + + my_tuple = Tuple(sort([idxs..., list_of_divisor_pairs_to_be_considered[j]...])) + if !haskey(inter_dict, my_tuple) + class = ambient_space_flux_candidates_basis[i] * cds[list_of_divisor_pairs_to_be_considered[j][1]] * cds[list_of_divisor_pairs_to_be_considered[j][2]] * pt_class + inter_dict[my_tuple] = integrate(class) + end + push!(condition, inter_dict[my_tuple]) + + end + push!(quant_constraint_matrix, condition) + end + + end + + # (8) Convert the quant_constraint_matrix to a ZZ matrix. If necessary, multiply it by a suitable integer. + denom = lcm(unique(vcat([denominator.(k) for k in quant_constraint_matrix]...))) + if denom != 1 + quant_constraint_matrix = denom * quant_constraint_matrix + end + C = transpose(matrix(ZZ, quant_constraint_matrix)) + + + # (9) Work out the well-quantized fluxes as linear combinations of the parametrization of the vertical fluxes + C2 = C * vertical_fluxes # This is a ZZ-matrix, since we parametrize vertical fluxes with integer coefficients! + S, T, U = snf_with_transform(C2) + r = rank(S) + @req all(k -> !is_zero(S[k,k]), 1:r) "Inconsistency in Smith normal form detected. Please inform the authors." + @req all(k -> is_zero(S[k,k]), r+1:min(nrows(S), ncols(S))) "Inconsistency in Smith normal form detected. Please inform the authors." + S_prime = zero_matrix(QQ, ncols(S), ncols(S)) + for k in 1:min(nrows(S), ncols(S)) + if k <= r + S_prime[k,k] = denom//S[k,k] + else + S_prime[k,k] = 1 + end + end + solution_matrix = U * S_prime + + + # (10) Finally, we need to re-express those in terms of the original bases. + # (10) Rather, we have res now expressed in terms of the basis of vertical fluxes... + sol_mat = vertical_fluxes * solution_matrix + res = (sol_mat[:,1:r], sol_mat[:,r+1:ncols(solution_matrix)]) + + + # (11) Remember computed data + set_attribute!(m, :well_quantized_and_vertical_ambient_space_models_of_g4_fluxes, res) + set_attribute!(m, :inter_dict, inter_dict) + set_attribute!(m, :s_inter_dict, s_inter_dict) + + + # (12) Finally, return the result + return res + +end diff --git a/experimental/FTheoryTools/src/Serialization/hypersurface_models.jl b/experimental/FTheoryTools/src/Serialization/hypersurface_models.jl index 8debd6dfba85..ea3a2cd8b5bf 100644 --- a/experimental/FTheoryTools/src/Serialization/hypersurface_models.jl +++ b/experimental/FTheoryTools/src/Serialization/hypersurface_models.jl @@ -82,6 +82,11 @@ function save_object(s::SerializerState, h::HypersurfaceModel) attrs_dict[:_ambient_space_divisor_pairs_to_be_considered] = _ambient_space_divisor_pairs_to_be_considered(h) end + # Do we know which pairs of ambient space base divisors intersect non-trivially with the hypersurface? + if has_attribute(h, :_ambient_space_base_divisor_pairs_to_be_considered) + attrs_dict[:_ambient_space_base_divisor_pairs_to_be_considered] = _ambient_space_base_divisor_pairs_to_be_considered(h) + end + # Do we know ambient space models for g4-fluxes? if has_attribute(h, :ambient_space_models_of_g4_fluxes) ambient_space_flux_candidates_basis = ambient_space_models_of_g4_fluxes(h) @@ -103,6 +108,13 @@ function save_object(s::SerializerState, h::HypersurfaceModel) attrs_dict[:well_quantized_rational] = res[2] end + # Do we know the well-quantized and vertical G4-fluxes + if has_attribute(h, :well_quantized_and_vertical_ambient_space_models_of_g4_fluxes) + res = well_quantized_and_vertical_ambient_space_models_of_g4_fluxes(h, check = false) + attrs_dict[:well_quantized_and_vertical_integral] = res[1] + attrs_dict[:well_quantized_and_vertical_rational] = res[2] + end + # Save all of the above data... !isempty(attrs_dict) && save_typed_object(s, attrs_dict, :__attrs) end @@ -170,6 +182,9 @@ function load_object(s::DeserializerState, ::Type{<:HypersurfaceModel}, params:: if haskey(attrs_data, :_ambient_space_divisor_pairs_to_be_considered) set_attribute!(model, :_ambient_space_divisor_pairs_to_be_considered, attrs_data[:_ambient_space_divisor_pairs_to_be_considered]) end + if haskey(attrs_data, :_ambient_space_base_divisor_pairs_to_be_considered) + set_attribute!(model, :_ambient_space_base_divisor_pairs_to_be_considered, attrs_data[:_ambient_space_base_divisor_pairs_to_be_considered]) + end # Likewise, there are only so many ambient space G4-flux candidates. If those are known, set them. # In the serialization, we remember only the integer tuples that tell us which toric divisors to consider, @@ -189,5 +204,11 @@ function load_object(s::DeserializerState, ::Type{<:HypersurfaceModel}, params:: set_attribute!(model, :well_quantized_ambient_space_models_of_g4_fluxes, quant_tuple) end + # Are the well-quantized and vertical G4-fluxes known? + if haskey(attrs_data, :well_quantized_and_vertical_integral) && haskey(attrs_data, :well_quantized_and_vertical_integral) + quant_tuple = (attrs_data[:well_quantized_and_vertical_integral], attrs_data[:well_quantized_and_vertical_integral]) + set_attribute!(model, :well_quantized_and_vertical_ambient_space_models_of_g4_fluxes, quant_tuple) + end + return model end diff --git a/experimental/FTheoryTools/src/Serialization/tate_models.jl b/experimental/FTheoryTools/src/Serialization/tate_models.jl index be3f827e86b1..7fc11daa84ee 100644 --- a/experimental/FTheoryTools/src/Serialization/tate_models.jl +++ b/experimental/FTheoryTools/src/Serialization/tate_models.jl @@ -83,6 +83,11 @@ function save_object(s::SerializerState, gtm::GlobalTateModel) attrs_dict[:_ambient_space_divisor_pairs_to_be_considered] = _ambient_space_divisor_pairs_to_be_considered(gtm) end + # Do we know which pairs of ambient space base divisors intersect non-trivially with the hypersurface? + if has_attribute(gtm, :_ambient_space_base_divisor_pairs_to_be_considered) + attrs_dict[:_ambient_space_base_divisor_pairs_to_be_considered] = _ambient_space_base_divisor_pairs_to_be_considered(gtm) + end + # Do we know ambient space models for g4-fluxes? if has_attribute(gtm, :ambient_space_models_of_g4_fluxes) ambient_space_flux_candidates_basis = ambient_space_models_of_g4_fluxes(gtm) @@ -104,6 +109,13 @@ function save_object(s::SerializerState, gtm::GlobalTateModel) attrs_dict[:well_quantized_rational] = res[2] end + # Do we know the well-quantized and vertical G4-fluxes + if has_attribute(gtm, :well_quantized_and_vertical_ambient_space_models_of_g4_fluxes) + res = well_quantized_and_vertical_ambient_space_models_of_g4_fluxes(gtm, check = false) + attrs_dict[:well_quantized_and_vertical_integral] = res[1] + attrs_dict[:well_quantized_and_vertical_rational] = res[2] + end + # Save all of the above data... !isempty(attrs_dict) && save_typed_object(s, attrs_dict, :__attrs) end @@ -172,6 +184,9 @@ function load_object(s::DeserializerState, ::Type{<: GlobalTateModel}, params::T if haskey(attrs_data, :_ambient_space_divisor_pairs_to_be_considered) set_attribute!(model, :_ambient_space_divisor_pairs_to_be_considered, attrs_data[:_ambient_space_divisor_pairs_to_be_considered]) end + if haskey(attrs_data, :_ambient_space_base_divisor_pairs_to_be_considered) + set_attribute!(model, :_ambient_space_base_divisor_pairs_to_be_considered, attrs_data[:_ambient_space_base_divisor_pairs_to_be_considered]) + end # Likewise, there are only so many ambient space G4-flux candidates. If those are known, set them. # In the serialization, we remember only the integer tuples that tell us which toric divisors to consider, @@ -190,5 +205,11 @@ function load_object(s::DeserializerState, ::Type{<: GlobalTateModel}, params::T set_attribute!(model, :well_quantized_ambient_space_models_of_g4_fluxes, quant_tuple) end + # Are the well-quantized and vertical G4-fluxes known? + if haskey(attrs_data, :well_quantized_and_vertical_integral) && haskey(attrs_data, :well_quantized_and_vertical_integral) + quant_tuple = (attrs_data[:well_quantized_and_vertical_integral], attrs_data[:well_quantized_and_vertical_integral]) + set_attribute!(model, :well_quantized_and_vertical_ambient_space_models_of_g4_fluxes, quant_tuple) + end + return model end diff --git a/experimental/FTheoryTools/src/Serialization/weierstrass_models.jl b/experimental/FTheoryTools/src/Serialization/weierstrass_models.jl index fc3dbdf06515..b3ae14b33daf 100644 --- a/experimental/FTheoryTools/src/Serialization/weierstrass_models.jl +++ b/experimental/FTheoryTools/src/Serialization/weierstrass_models.jl @@ -82,6 +82,11 @@ function save_object(s::SerializerState, w::WeierstrassModel) attrs_dict[:_ambient_space_divisor_pairs_to_be_considered] = _ambient_space_divisor_pairs_to_be_considered(w) end + # Do we know which pairs of ambient space base divisors intersect non-trivially with the hypersurface? + if has_attribute(w, :_ambient_space_base_divisor_pairs_to_be_considered) + attrs_dict[:_ambient_space_base_divisor_pairs_to_be_considered] = _ambient_space_base_divisor_pairs_to_be_considered(w) + end + # Do we know ambient space models for g4-fluxes? if has_attribute(w, :ambient_space_models_of_g4_fluxes) ambient_space_flux_candidates_basis = ambient_space_models_of_g4_fluxes(w) @@ -103,6 +108,13 @@ function save_object(s::SerializerState, w::WeierstrassModel) attrs_dict[:well_quantized_rational] = res[2] end + # Do we know the well-quantized and vertical G4-fluxes + if has_attribute(w, :well_quantized_and_vertical_ambient_space_models_of_g4_fluxes) + res = well_quantized_and_vertical_ambient_space_models_of_g4_fluxes(w, check = false) + attrs_dict[:well_quantized_and_vertical_integral] = res[1] + attrs_dict[:well_quantized_and_vertical_rational] = res[2] + end + # Save all of the above data... !isempty(attrs_dict) && save_typed_object(s, attrs_dict, :__attrs) end @@ -170,6 +182,9 @@ function load_object(s::DeserializerState, ::Type{<: WeierstrassModel}, params:: if haskey(attrs_data, :_ambient_space_divisor_pairs_to_be_considered) set_attribute!(model, :_ambient_space_divisor_pairs_to_be_considered, attrs_data[:_ambient_space_divisor_pairs_to_be_considered]) end + if haskey(attrs_data, :_ambient_space_base_divisor_pairs_to_be_considered) + set_attribute!(model, :_ambient_space_base_divisor_pairs_to_be_considered, attrs_data[:_ambient_space_base_divisor_pairs_to_be_considered]) + end # Likewise, there are only so many ambient space G4-flux candidates. If those are known, set them. # In the serialization, we remember only the integer tuples that tell us which toric divisors to consider, @@ -189,5 +204,11 @@ function load_object(s::DeserializerState, ::Type{<: WeierstrassModel}, params:: set_attribute!(model, :well_quantized_ambient_space_models_of_g4_fluxes, quant_tuple) end + # Are the well-quantized and vertical G4-fluxes known? + if haskey(attrs_data, :well_quantized_and_vertical_integral) && haskey(attrs_data, :well_quantized_and_vertical_integral) + quant_tuple = (attrs_data[:well_quantized_and_vertical_integral], attrs_data[:well_quantized_and_vertical_integral]) + set_attribute!(model, :well_quantized_and_vertical_ambient_space_models_of_g4_fluxes, quant_tuple) + end + return model end diff --git a/experimental/FTheoryTools/src/exports.jl b/experimental/FTheoryTools/src/exports.jl index 53ce0b2e9622..e57829e4a0ae 100644 --- a/experimental/FTheoryTools/src/exports.jl +++ b/experimental/FTheoryTools/src/exports.jl @@ -218,5 +218,6 @@ export weighted_resolution_zero_sections export weighted_resolutions export weights export well_quantized_ambient_space_models_of_g4_fluxes +export well_quantized_and_vertical_ambient_space_models_of_g4_fluxes export zero_section export zero_section_class