Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
coag_functions_GQ.py
1import sys
2
3import numpy as np
4
5# from numba import njit
6from scipy.special import legendre
7
8from ..kernel_collision import *
9from ..utils_polynomials import *
10
11
12def func_coag_flux(kernel, K0, ai, aip, u, v, xilp, xil):
13 """
14 Function to evaluate the integrand of the coagulation flux, i.e. integrand of the double integral
15
16 Parameters
17 ----------
18 kernel : scalar, type -> integer
19 select the collisional kernel function
20 K0 : scalar, type -> float
21 constant value of the kernel function (used to adapt to code unit)
22 ai : 1D array (dim = i+1), type -> float
23 coefficients of polynomial of degree i
24 aip : 1D array (dim = ip+1), type - > float
25 coefficients of polynomial of degree ip
26 u : scalar, type -> float
27 mass variable (colliding grain of mass u)
28 v : scalar, type -> float
29 mass variable (colliding grain of mass v)
30 xilp : scalar, type -> float
31 variable mapping the mass bin lp in [-1,1], needed for Legendre polynomials
32 xil : scalar, type -> float
33 variable mapping the mass bin l in [-1,1], need for Legendre polynomials
34
35 Returns
36 -------
37 func_coag_flux : scalar, type -> float
38 integrand of cogulation flux evaluated at u,v,xilp,xil
39
40 """
41
42 return func_kernel(kernel, K0, u, v) * phi_pol(aip, xilp) * phi_pol(ai, xil) / v
43
44
45def coagfluxfunction(
46 kernel, K0, Q, vecnodes, vecweights, nbins, massgrid, mat_coeffs_leg, j, lp, l, ip, i
47):
48 """
49 Function to evaluate the double integral depending only masses with Gauss-Legendre quadrature method.
50 This function is used to calculate the array for the coagulation flux as precomputation.
51
52 Parameters
53 ----------
54 kernel : scalar, type -> integer
55 select the collisional kernel function
56 K0 : scalar, type -> float
57 constant value of the kernel function (used to adapt to code unit)
58 Q : scalar, type -> integer
59 number of points for Gauss-Legendre quadrature
60 vecnodes : 1D array (dim = Q), type -> float
61 nodes of the Legendre polynomials
62 vecweights : 1D array (dim = Q), type -> float
63 weights coefficients for the Gauss-Legendre polynomials
64 nbins : scalar, type -> integer
65 number of dust bins
66 massgrid : 1D array (dim = nbins+1), type -> float
67 grid of masses given borders value of mass bins
68 mat_coeffs_leg : 2D array (dmin = (kpol+1,kpol+1)), type -> float
69 array containing on each line Legendre polynomial coefficients from degree 0 to kpol inclusive
70 on each line coefficients are ordered from low to high orders
71 j : scalar, type -> integer
72 index corresponding to the mass of the new formed grain
73 lp : scarlar, type -> integer
74 index corresponding to the mass of one colliding grain
75 l : scarlar, type -> integer
76 index corresponding to the mass of the second colliding grain
77 ip : scalar, type -> integer
78 degree of polynomials for approximation in bin lp
79 i : scalar, type -> integer
80 degree of polynomials for approximation in bin l
81
82
83 Returns
84 -------
85 coagfluxfunction : scalar, type -> float
86 double integral for the coagulation flux evaluated at j,lp,l,ip,i
87
88 """
89
90 # borders, size and mean values of mass bins of indices j,lp,l
91 xlgridr = massgrid[l + 1]
92 xlgridl = massgrid[l]
93 xlpgridl = massgrid[lp]
94 xlpgridr = massgrid[lp + 1]
95
96 hlp = xlpgridr - xlpgridl
97 xlp = 0.5 * (xlpgridr + xlpgridl)
98
99 hl = xlgridr - xlgridl
100 xl = 0.5 * (xlgridr + xlgridl)
101
102 xjgridr = massgrid[j + 1]
103
104 # minimum and maximum value of mass range
105 xmin = massgrid[0]
106 xmax = massgrid[-1]
107
108 # polynomials coefficients (low to high order)
109 aip = mat_coeffs_leg[ip, : ip + 1]
110 ai = mat_coeffs_leg[i, : i + 1]
111
112 # initialisation double integral
113 res = 0.0
114
115 # gauss-legendre quadrature on integral on u
116 for alpha_u in range(Q):
117 ulp_alpha = xlp + 0.5 * hlp * vecnodes[alpha_u]
118 xilp = vecnodes[alpha_u]
119
120 # gauss-legendre quadrature on integral on v
121 for alpha_v in range(Q):
122 a_vl = np.max([xjgridr - ulp_alpha + xmin, xlgridl])
123 b_vl = np.min([xmax - ulp_alpha + xmin, xlgridr])
124 vl_alpha = 0.5 * (b_vl + a_vl) + 0.5 * (b_vl - a_vl) * vecnodes[alpha_v]
125 xil = 2.0 * (vl_alpha - xl) / hl
126
127 if xmax - ulp_alpha + xmin > xlgridl and xlgridr > xjgridr - ulp_alpha + xmin:
128 res += (
129 0.25
130 * hlp
131 * (b_vl - a_vl)
132 * vecweights[alpha_u]
133 * vecweights[alpha_v]
134 * func_coag_flux(kernel, K0, ai, aip, ulp_alpha, vl_alpha, xilp, xil)
135 )
136
137 return res
138
139
140# @njit
141def func_coag_flux_numba(kernel, K0, ai, aip, u, v, xilp, xil):
142 """
143 Function to evaluate the integrand of the coagulation flux, i.e. integrand of the double integral
144 Numba formalism
145
146 Parameters
147 ----------
148 kernel : scalar, type -> integer
149 select the collisional kernel function
150 K0 : scalar, type -> float
151 constant value of the kernel function (used to adapt to code unit)
152 ai : 1D array (dim = i+1), type -> float
153 coefficients of polynomial of degree i
154 aip : 1D array (dim = ip+1), type - > float
155 coefficients of polynomial of degree ip
156 u : scalar, type -> float
157 mass variable (colliding grain of mass u)
158 v : scalar, type -> float
159 mass variable (colliding grain of mass v)
160 xilp : scalar, type -> float
161 variable mapping the mass bin lp in [-1,1], needed for Legendre polynomials
162 xil : scalar, type -> float
163 variable mapping the mass bin l in [-1,1], need for Legendre polynomials
164
165 Returns
166 -------
167 func_coag_flux : scalar, type -> float
168 integrand of cogulation flux evaluated at u,v,xilp,xil
169
170 """
171
172 return func_kernel_numba(kernel, K0, u, v) * phi_pol(aip, xilp) * phi_pol(ai, xil) / v
173
174
175# @njit
176def coagfluxfunction_numba(
177 kernel, K0, Q, vecnodes, vecweights, nbins, massgrid, mat_coeffs_leg, j, lp, l, ip, i
178):
179 """
180 Function to evaluate the double integral depending only masses with Gauss-Legendre quadrature method.
181 This function is used to calculate the array for the coagulation flux as precomputation.
182 Numba formalism
183
184 Parameters
185 ----------
186 kernel : scalar, type -> integer
187 select the collisional kernel function
188 K0 : scalar, type -> float
189 constant value of the kernel function (used to adapt to code unit)
190 Q : scalar, type -> integer
191 number of points for Gauss-Legendre quadrature
192 vecnodes : 1D array (dim = Q), type -> float
193 nodes of the Legendre polynomials
194 vecweights : 1D array (dim = Q), type -> float
195 weights coefficients for the Gauss-Legendre polynomials
196 nbins : scalar, type -> integer
197 number of dust bins
198 massgrid : 1D array (dim = nbins+1), type -> float
199 grid of masses given borders value of mass bins
200 mat_coeffs_leg : 2D array (dmin = (kpol+1,kpol+1)), type -> float
201 array containing on each line Legendre polynomial coefficients from degree 0 to kpol inclusive
202 on each line coefficients are ordered from low to high orders
203 j : scalar, type -> integer
204 index corresponding to the mass of the new formed grain
205 lp : scarlar, type -> integer
206 index corresponding to the mass of one colliding grain
207 l : scarlar, type -> integer
208 index corresponding to the mass of the second colliding grain
209 ip : scalar, type -> integer
210 degree of polynomials for approximation in bin lp
211 i : scalar, type -> integer
212 degree of polynomials for approximation in bin l
213
214
215 Returns
216 -------
217 coagfluxfunction : scalar, type -> float
218 double integral for the coagulation flux evaluated at j,lp,l,ip,i
219
220 """
221
222 # borders, size and mean values of mass bins of indices j,lp,l
223 xlgridr = massgrid[l + 1]
224 xlgridl = massgrid[l]
225 xlpgridl = massgrid[lp]
226 xlpgridr = massgrid[lp + 1]
227
228 hlp = xlpgridr - xlpgridl
229 xlp = 0.5 * (xlpgridr + xlpgridl)
230
231 hl = xlgridr - xlgridl
232 xl = 0.5 * (xlgridr + xlgridl)
233
234 xjgridr = massgrid[j + 1]
235
236 # minimum and maximum value of mass range
237 xmin = massgrid[0]
238 xmax = massgrid[-1]
239
240 # polynomials coefficients (low to high order)
241 aip = mat_coeffs_leg[ip, : ip + 1]
242 ai = mat_coeffs_leg[i, : i + 1]
243
244 # initialisation double integral
245 res = 0.0
246
247 # gauss-legendre quadrature on integral on u
248 for alpha_u in range(Q):
249 ulp_alpha = xlp + 0.5 * hlp * vecnodes[alpha_u]
250 xilp = vecnodes[alpha_u]
251
252 # gauss-legendre quadrature on integral on v
253 for alpha_v in range(Q):
254 a_vl = max(xjgridr - ulp_alpha + xmin, xlgridl)
255 b_vl = min(xmax - ulp_alpha + xmin, xlgridr)
256 vl_alpha = 0.5 * (b_vl + a_vl) + 0.5 * (b_vl - a_vl) * vecnodes[alpha_v]
257 xil = 2.0 * (vl_alpha - xl) / hl
258
259 if xmax - ulp_alpha + xmin > xlgridl and xlgridr > xjgridr - ulp_alpha + xmin:
260 res += (
261 0.25
262 * hlp
263 * (b_vl - a_vl)
264 * vecweights[alpha_u]
265 * vecweights[alpha_v]
266 * func_coag_flux_numba(kernel, K0, ai, aip, ulp_alpha, vl_alpha, xilp, xil)
267 )
268
269 return res
270
271
272def func_coag_intflux(kernel, K0, ak, ai, aip, hj, u, v, xij, xilp, xil):
273 """
274 Function to evaluate the integrand of the term including the integral of the coagulation flux, i.e. integrand of the triple integral.
275 See discontinuous galerkin scheme.
276
277 Parameters
278 ----------
279 kernel : scalar, type -> integer
280 select the collisional kernel function
281 K0 : scalar, type -> float
282 constant value of the kernel function (used to adapt to code unit)
283 ak : 1D array (dim = kpol+1), type -> float
284 coefficients of polynomial of degree k
285 ai : 1D array (dim = kpol+1), type -> float
286 coefficients of polynomial of degree i
287 aip : 1D array (dim = kpol+1), type -> float
288 coefficients of polynomial of degree ip
289 hj : scalar, type -> float
290 size of mass bin j
291 u : scalar, type -> float
292 mass variable (colliding grain of mass u)
293 v : scalar, type -> float
294 mass variable (colliding grain of mass v)
295 xij : scalar, type -> float
296 variable mapping the mass bin j in [-1,1], needed for Legendre polynomials
297 xilp : scalar, type -> float
298 variable mapping the mass bin lp in [-1,1], needed for Legendre polynomials
299 xil : scalar, type -> float
300 variable mapping the mass bin l in [-1,1], need for Legendre polynomials
301
302 Returns
303 -------
304 func_coag_intflux : scalar, type -> float
305 integrand of the triple integral evaluated at u,v,xij,xilp,xil
306
307 """
308
309 return (
310 dphik(ak, hj, xij)
311 * func_kernel(kernel, K0, u, v)
312 * phi_pol(aip, xilp)
313 * phi_pol(ai, xil)
314 / v
315 )
316
317
318def coagintfluxfunction(
319 kernel, K0, Q, vecnodes, vecweights, nbins, massgrid, mat_coeffs_leg, j, k, lp, l, ip, i
320):
321 """
322 Function to evaluate the triple integral for coagulation (term in DG scheme) depending only masses with Gauss-Legendre quadrature method.
323 This function is used to calculate the array for the term including the integral of the coagulation flux as precomputation.
324
325 Parameters
326 ----------
327 kernel : scalar, type -> integer
328 select the collisional kernel function
329 K0 : scalar, type -> float
330 constant value of the kernel function (used to adapt to code unit)
331 Q : scalar, type -> integer
332 number of points for Gauss-Legendre quadrature
333 vecnodes : 1D array (dim = Q), type -> float
334 nodes of the Legendre polynomials
335 vecweights : 1D array (dim = Q), type -> float
336 weights coefficients for the Gauss-Legendre polynomials
337 nbins : scalar, type -> integer
338 number of dust bins
339 massgrid : 1D array (dim = nbins+1), type -> float
340 grid of masses given borders value of mass bins
341 mat_coeffs_leg : 2D array (dmin = (kpol+1,kpol+1)), type -> float
342 array containing on each line Legendre polynomial coefficients from degree 0 to kpol inclusive
343 on each line coefficients are ordered from low to high orders
344 j : scalar, type -> integer
345 index corresponding to the mass of the new formed grain
346 k : scalar, type -> integer
347 degree of polynomials for approximation in bin j
348 lp : scarlar, type -> integer
349 index corresponding to the mass of one colliding grain
350 l : scarlar, type -> integer
351 index corresponding to the mass of the second colliding grain
352 ip : scalar, type -> integer
353 degree of polynomials for approximation in bin lp
354 i : scalar, type -> integer
355 degree of polynomials for approximation in bin l
356
357
358 Returns
359 -------
360 coagintfluxfunction : scalar, type -> float
361 triple integral for the term including the integral of coagulation flux evaluated at j,k,lp,l,ip,i
362
363 """
364
365 # borders, size and mean values of mass bins of indices j,lp,l
366 xlgridr = massgrid[l + 1]
367 xlgridl = massgrid[l]
368 xlpgridl = massgrid[lp]
369 xlpgridr = massgrid[lp + 1]
370
371 xjgridr = massgrid[j + 1]
372 xjgridl = massgrid[j]
373
374 hlp = xlpgridr - xlpgridl
375 xlp = 0.5 * (xlpgridr + xlpgridl)
376
377 hl = xlgridr - xlgridl
378 xl = 0.5 * (xlgridr + xlgridl)
379
380 hj = xjgridr - xjgridl
381 xj = 0.5 * (xjgridr + xjgridl)
382
383 # minimum and maximum value of mass range
384 xmin = massgrid[0]
385 xmax = massgrid[-1]
386
387 # polynomials coefficients (low to high order)
388 aip = mat_coeffs_leg[ip, : ip + 1]
389 ai = mat_coeffs_leg[i, : i + 1]
390 ak = mat_coeffs_leg[k, : k + 1]
391
392 res = 0.0
393
394 # gauss-legendre quadrature on integral on x
395 for alpha_x in range(Q):
396 xj_alpha = xj + 0.5 * hj * vecnodes[alpha_x]
397 xij = vecnodes[alpha_x]
398
399 # gauss-legendre quadrature on integral on u
400 for alpha_u in range(Q):
401 a_ulp = np.max([xmin, xlpgridl])
402 b_ulp = np.min([xj_alpha, xlpgridr])
403 ulp_alpha = 0.5 * (b_ulp + a_ulp) + 0.5 * (b_ulp - a_ulp) * vecnodes[alpha_u]
404 xilp = 2.0 * (ulp_alpha - xlp) / hlp
405
406 # gauss-legendre quadrature on integral on v
407 for alpha_v in range(Q):
408 a_vl = np.max([xj_alpha - ulp_alpha + xmin, xlgridl])
409 b_vl = np.min([xmax - ulp_alpha + xmin, xlgridr])
410 vl_alpha = 0.5 * (b_vl + a_vl) + 0.5 * (b_vl - a_vl) * vecnodes[alpha_v]
411 xil = 2.0 * (vl_alpha - xl) / hl
412
413 if xmax - ulp_alpha + xmin > xlgridl and xlgridr > xj_alpha - ulp_alpha + xmin:
414 res += (
415 0.125
416 * hj
417 * (b_ulp - a_ulp)
418 * (b_vl - a_vl)
419 * vecweights[alpha_x]
420 * vecweights[alpha_u]
421 * vecweights[alpha_v]
422 * func_coag_intflux(
423 kernel, K0, ak, ai, aip, hj, ulp_alpha, vl_alpha, xij, xilp, xil
424 )
425 )
426
427 return res
428
429
430# @njit
431def func_coag_intflux_numba(kernel, K0, ak, ai, aip, hj, u, v, xij, xilp, xil):
432 dphik_val = dphik(ak, hj, xij)
433 kernel_val = func_kernel_numba(kernel, K0, u, v)
434 phi_aip_val = phi_pol(aip, xilp)
435 phi_ai_val = phi_pol(ai, xil)
436
437 return dphik_val * kernel_val * phi_aip_val * phi_ai_val / v
438
439
440# @njit
441def coagintfluxfunction_numba(
442 kernel, K0, Q, vecnodes, vecweights, nbins, massgrid, mat_coeffs_leg, j, k, lp, l, ip, i
443):
444 """
445 Function to evaluate the triple integral for coagulation (term in DG scheme) depending only masses with Gauss-Legendre quadrature method.
446 This function is used to calculate the array for the term including the integral of the coagulation flux as precomputation.
447
448 Parameters
449 ----------
450 kernel : scalar, type -> integer
451 select the collisional kernel function
452 K0 : scalar, type -> float
453 constant value of the kernel function (used to adapt to code unit)
454 Q : scalar, type -> integer
455 number of points for Gauss-Legendre quadrature
456 vecnodes : 1D array (dim = Q), type -> float
457 nodes of the Legendre polynomials
458 vecweights : 1D array (dim = Q), type -> float
459 weights coefficients for the Gauss-Legendre polynomials
460 nbins : scalar, type -> integer
461 number of dust bins
462 massgrid : 1D array (dim = nbins+1), type -> float
463 grid of masses given borders value of mass bins
464 mat_coeffs_leg : 2D array (dmin = (kpol+1,kpol+1)), type -> float
465 array containing on each line Legendre polynomial coefficients from degree 0 to kpol inclusive
466 on each line coefficients are ordered from low to high orders
467 j : scalar, type -> integer
468 index corresponding to the mass of the new formed grain
469 k : scalar, type -> integer
470 degree of polynomials for approximation in bin j
471 lp : scarlar, type -> integer
472 index corresponding to the mass of one colliding grain
473 l : scarlar, type -> integer
474 index corresponding to the mass of the second colliding grain
475 ip : scalar, type -> integer
476 degree of polynomials for approximation in bin lp
477 i : scalar, type -> integer
478 degree of polynomials for approximation in bin l
479
480
481 Returns
482 -------
483 coagintfluxfunction : scalar, type -> float
484 triple integral for the term including the integral of coagulation flux evaluated at j,k,lp,l,ip,i
485
486 """
487
488 # borders, size and mean values of mass bins of indices j,lp,l
489 xlgridr = massgrid[l + 1]
490 xlgridl = massgrid[l]
491 xlpgridl = massgrid[lp]
492 xlpgridr = massgrid[lp + 1]
493
494 xjgridr = massgrid[j + 1]
495 xjgridl = massgrid[j]
496
497 hlp = xlpgridr - xlpgridl
498 xlp = 0.5 * (xlpgridr + xlpgridl)
499
500 hl = xlgridr - xlgridl
501 xl = 0.5 * (xlgridr + xlgridl)
502
503 hj = xjgridr - xjgridl
504 xj = 0.5 * (xjgridr + xjgridl)
505
506 # minimum and maximum value of mass range
507 xmin = massgrid[0]
508 xmax = massgrid[-1]
509
510 # polynomials coefficients (low to high order)
511 aip = mat_coeffs_leg[ip, : ip + 1]
512 ai = mat_coeffs_leg[i, : i + 1]
513 ak = mat_coeffs_leg[k, : k + 1]
514
515 res = 0.0
516
517 # gauss-legendre quadrature on integral on x
518 for alpha_x in range(Q):
519 xj_alpha = xj + 0.5 * hj * vecnodes[alpha_x]
520 xij = vecnodes[alpha_x]
521
522 # gauss-legendre quadrature on integral on u
523 for alpha_u in range(Q):
524 a_ulp = max(xmin, xlpgridl)
525 b_ulp = min(xj_alpha, xlpgridr)
526 ulp_alpha = 0.5 * (b_ulp + a_ulp) + 0.5 * (b_ulp - a_ulp) * vecnodes[alpha_u]
527 xilp = 2.0 * (ulp_alpha - xlp) / hlp
528
529 # gauss-legendre quadrature on integral on v
530 for alpha_v in range(Q):
531 a_vl = max(xj_alpha - ulp_alpha + xmin, xlgridl)
532 b_vl = min(xmax - ulp_alpha + xmin, xlgridr)
533 vl_alpha = 0.5 * (b_vl + a_vl) + 0.5 * (b_vl - a_vl) * vecnodes[alpha_v]
534 xil = 2.0 * (vl_alpha - xl) / hl
535
536 if xmax - ulp_alpha + xmin > xlgridl and xlgridr > xj_alpha - ulp_alpha + xmin:
537 res += (
538 0.125
539 * hj
540 * (b_ulp - a_ulp)
541 * (b_vl - a_vl)
542 * vecweights[alpha_x]
543 * vecweights[alpha_u]
544 * vecweights[alpha_v]
545 * func_coag_intflux_numba(
546 kernel, K0, ak, ai, aip, hj, ulp_alpha, vl_alpha, xij, xilp, xil
547 )
548 )
549
550 return res