Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
L2_proj.py
1import sys
2
3import numpy as np
4from scipy.special import eval_legendre
5
6from .utils_polynomials import *
7
8
9# generate gij components for k=0 from g(x)=x*exp(-x)
10def L2proj_k0(eps, nbins, N0, m0, massgrid, massbins, Q, vecnodes, vecweights):
11 """
12 Function to compute the initial gij coefficient from the initial function g(m) = m*N0/m0*exp(-m/m0)
13
14 DG scheme k=0, piecewise constant approximation
15
16 Parameters
17 ----------
18 eps : scalar, type -> float
19 minimum value for mass distribution approximation gij
20 nbins : scalar, type -> integer
21 number of dust bins
22 N0 : scalar, type -> float
23 initial total number density of grains
24 m0 : scalar, type -> float
25 initial mean mass of grains
26 massgrid : 1D array (dim = nbins+1), type -> float
27 grid of masses given borders value of mass bins
28 massbins : 1D array (dim = nbins), type -> float
29 arithmetic mean value of massgrid for each mass bins
30 Q : scalar, type -> integer
31 number of points for Gauss-Legendre quadrature
32 vecnodes : 1D array (dim = Q), type -> float
33 nodes of the Legendre polynomials
34 vecweights : 1D array (dim = Q), type -> float
35 weights coefficients for the Gauss-Legendre polynomials
36
37
38 Returns
39 -------
40 gij : 1D array (dim = nbins), type -> float
41 initial components of g on the polynomial basis
42
43 """
44
45 mat_vecweights = np.outer(np.ones(nbins), vecweights)
46 mat_xjalpha = np.outer(massbins, np.ones(Q)) + np.outer(
47 (massgrid[1:] - massgrid[0:nbins]) / 2.0, vecnodes
48 )
49
50 term_sum = np.sum(mat_vecweights * N0 * mat_xjalpha / m0 * np.exp(-mat_xjalpha / m0), axis=1)
51
52 gij = term_sum / coeff_norm_leg(0)
53 gij[gij < eps] = eps
54
55 return gij
56
57
58def L2projDL_k0(eps, nbins, massgrid, massbins, Q, vecnodes, vecweights):
59 """
60 Function to compute the initial gij coefficient from the dimensionless initial function g(x)=x*exp(-x)
61
62 DG scheme k=0, piecewise constant approximation
63
64 Parameters
65 ----------
66 eps : scalar, type -> float
67 minimum value for mass distribution approximation gij
68 nbins : scalar, type -> integer
69 number of dust bins
70 massgrid : 1D array (dim = nbins+1), type -> float
71 grid of masses given borders value of mass bins
72 massbins : 1D array (dim = nbins), type -> float
73 arithmetic mean value of massgrid for each mass bins
74 Q : scalar, type -> integer
75 number of points for Gauss-Legendre quadrature
76 vecnodes : 1D array (dim = Q), type -> float
77 nodes of the Legendre polynomials
78 vecweights : 1D array (dim = Q), type -> float
79 weights coefficients for the Gauss-Legendre polynomials
80
81
82 Returns
83 -------
84 gij : 1D array (dim = nbins), type -> float
85 initial components of g on the polynomial basis
86
87 """
88 mat_vecweights = np.outer(np.ones(nbins), vecweights)
89 mat_xjalpha = np.outer(massbins, np.ones(Q)) + np.outer(
90 (massgrid[1:] - massgrid[0:nbins]) / 2.0, vecnodes
91 )
92
93 term_sum = np.sum(mat_vecweights * mat_xjalpha * np.exp(-mat_xjalpha), axis=1)
94
95 gij = term_sum / coeff_norm_leg(0)
96 gij[gij < eps] = eps
97
98 return gij
99
100
101# genreate gij components for k>0 from g(x)=x*exp(-x)
102def L2proj(eps, nbins, kpol, N0, m0, massgrid, massbins, Q, vecnodes, vecweights):
103 """
104 Function to compute the initial gij coefficient from the initial function g(m) = m*N0/m0*exp(-m/m0)
105
106 DG scheme k>0, piecewise polynomial approximation
107
108 Parameters
109 ----------
110 eps : scalar, type -> float
111 minimum value for mass distribution approximation gij
112 nbins : scalar, type -> integer
113 number of dust bins
114 kpol : scalar, type -> integer
115 degree of polynomials for approximation
116 N0 : scalar, type -> float
117 initial total number density of grains
118 m0 : scalar, type -> float
119 initial mean mass of grains
120 massgrid : 1D array (dim = nbins+1), type -> float
121 grid of masses given borders value of mass bins
122 massbins : 1D array (dim = nbins), type -> float
123 arithmetic mean value of massgrid for each mass bins
124 Q : scalar, type -> integer
125 number of points for Gauss-Legendre quadrature
126 vecnodes : 1D array (dim = Q), type -> float
127 nodes of the Legendre polynomials
128 vecweights : 1D array (dim = Q), type -> float
129 weights coefficients for the Gauss-Legendre polynomials
130
131
132 Returns
133 -------
134 gij : 2D array (dim = (nbins,kpol+1)), type -> float
135 initial components of g on the polynomial basis
136
137 """
138
139 gij = np.zeros((nbins, kpol + 1))
140 for j in range(nbins):
141 xj = massbins[j]
142 hj = massgrid[j + 1] - massgrid[j]
143
144 for k in range(kpol + 1):
145 term_sum = 0.0
146 for alpha in range(Q):
147 xjalpha = xj + hj * vecnodes[alpha] / 2.0
148
149 term_sum += (
150 vecweights[alpha]
151 * N0
152 * xjalpha
153 / m0
154 * np.exp(-xjalpha / m0)
155 * eval_legendre(k, vecnodes[alpha])
156 )
157
158 gij[j, k] = term_sum / coeff_norm_leg(k)
159
160 if gij[:, 0][gij[:, 0] < 0.0].any():
161 print("gij", gij)
162 raise ValueError(f"gij has negative values: {gij}")
163 else:
164 gij[:, 1:][gij[:, 0] < eps] = 0.0
165 gij[:, 0][gij[:, 0] < eps] = eps
166
167 return gij
168
169
170def L2projDL(eps, nbins, kpol, massgrid, massbins, Q, vecnodes, vecweights):
171 """
172 Function to compute the initial gij coefficient from the dimensionless initial function g(x)=x*exp(-x)
173
174 DG scheme k>0, piecewise polynomial approximation
175
176 Parameters
177 ----------
178 eps : scalar, type -> float
179 minimum value for mass distribution approximation gij
180 nbins : scalar, type -> integer
181 number of dust bins
182 kpol : scalar, type -> integer
183 degree of polynomials for approximation
184 massgrid : 1D array (dim = nbins+1), type -> float
185 grid of masses given borders value of mass bins
186 massbins : 1D array (dim = nbins), type -> float
187 arithmetic mean value of massgrid for each mass bins
188 Q : scalar, type -> integer
189 number of points for Gauss-Legendre quadrature
190 vecnodes : 1D array (dim = Q), type -> float
191 nodes of the Legendre polynomials
192 vecweights : 1D array (dim = Q), type -> float
193 weights coefficients for the Gauss-Legendre polynomials
194
195
196 Returns
197 -------
198 gij : 2D array (dim = (nbins,kpol+1)), type -> float
199 initial components of g on the polynomial basis
200
201 """
202
203 gij = np.zeros((nbins, kpol + 1))
204 for j in range(nbins):
205 xj = massbins[j]
206 hj = massgrid[j + 1] - massgrid[j]
207
208 for k in range(kpol + 1):
209 term_sum = 0.0
210 for alpha in range(Q):
211 xjalpha = xj + hj * vecnodes[alpha] / 2.0
212
213 term_sum += (
214 vecweights[alpha]
215 * xjalpha
216 * np.exp(-xjalpha)
217 * eval_legendre(k, vecnodes[alpha])
218 )
219
220 gij[j, k] = term_sum / coeff_norm_leg(k)
221
222 if gij[:, 0][gij[:, 0] < 0.0].any():
223 print("gij", gij)
224 sys.exit()
225 else:
226 gij[:, 1:][gij[:, 0] < eps] = 0.0
227 gij[:, 0][gij[:, 0] < eps] = eps
228
229 return gij