@@ -449,7 +449,7 @@ def calc_mean_grain_size(p, s):
449449 D_mean [yi , xi ] = np .sum (diameters * weights )
450450 return D_mean
451451
452- @njit (cache = True )
452+ # @njit(cache=True) this function is an orchestrator njit will not be faster
453453def sweep (Ct , Cu , mass , dt , Ts , ds , dn , us , un , w ):
454454
455455
@@ -506,7 +506,7 @@ def sweep(Ct, Cu, mass, dt, Ts, ds, dn, us, un, w):
506506 ufn [0 ,:,:] = (ufn [0 ,:,:]+ ufn [- 1 ,:,:])/ 2
507507 ufn [- 1 ,:,:] = ufn [0 ,:,:]
508508
509- # now make sure that there is no gradients at the bondares
509+ # now make sure that there is no gradients at the bondaries
510510 ufs [:,1 ,:] = ufs [:,0 ,:]
511511 ufs [:,- 2 ,:] = ufs [:,- 1 ,:]
512512 ufs [1 ,:,:] = ufs [0 ,:,:]
@@ -544,148 +544,52 @@ def sweep(Ct, Cu, mass, dt, Ts, ds, dn, us, un, w):
544544 Ct [:,0 ,0 ],Ct [:,- 1 ,0 ] = Ct [:,- 1 ,0 ].copy (),Ct [:,0 ,0 ].copy ()
545545
546546 if recirc_offshore :
547- # print(Ct[:,1,0])
548- # print(Ct[:,-2,0])
549- Ct [:,0 ,0 ],Ct [:,- 1 ,0 ] = np .average (Ct [:,- 2 ,0 ]),np .average (Ct [:,1 ,0 ])
550- # print(Ct[:,0,0])
551- # print(Ct[:,-1,0])
547+ Ct [:,0 ,0 ],Ct [:,- 1 ,0 ] = np .mean (Ct [:,- 2 ,0 ]), np .mean (Ct [:,1 ,0 ])
552548
553- # make an array with a bolean operator. This keeps track of considerd cells. We start with all False (not considered)
554- q = np .zeros (Cu .shape [:2 ])
549+ # Track visited cells and quadrant classification
550+ visited = np .zeros (Cu .shape [:2 ], dtype = np .bool_ )
551+ quad = np .zeros (Cu .shape [:2 ], dtype = np .uint8 )
555552
556553 ########################################################################################
557554 # in this sweeping algorithm we sweep over the 4 quadrants
558555 # assuming that most cells have no converging/divering charactersitics.
559556 # In the last quadrant we take converging and diverging cells into account.
560557
561- # The First quadrant
562- for n in range (1 ,Ct .shape [0 ]):
563- for s in range (1 ,Ct .shape [1 ]):
564- if (not q [n ,s ]) and (ufn [n ,s ,0 ]>= 0 ) and (ufs [n ,s ,0 ]>= 0 ) and (ufn [n + 1 ,s ,0 ]>= 0 ) and (ufs [n ,s + 1 ,0 ]>= 0 ):
565- Ct [n ,s ,:] = (+ (Ct [n - 1 ,s ,:] * ufn [n ,s ,:] * ds [n ,s ]) \
566- + (Ct [n ,s - 1 ,:] * ufs [n ,s ,:] * dn [n ,s ]) \
567- + w [n ,s ,:] * Cu [n ,s ,:] * ds [n ,s ] * dn [n ,s ] / Ts ) \
568- / ( + (ufn [n + 1 ,s ,:] * ds [n ,s ]) \
569- + (ufs [n ,s + 1 ,:] * dn [n ,s ]) \
570- + (ds [n ,s ] * dn [n ,s ] / Ts ) )
571- #calculate pickup
572- pickup [n ,s ,:] = (w [n ,s ,:] * Cu [n ,s ,:] - Ct [n ,s ,:]) * dt / Ts
573- #check for supply limitations and re-iterate concentration to account for supply limitations
574- for nfs in range (0 ,nf ):
575- if pickup [n ,s ,nfs ]> mass [n ,s ,0 ,nfs ]:
576- pickup [n ,s ,nfs ] = mass [n ,s ,0 ,nfs ]
577- Ct [n ,s ,nfs ] = (+ (Ct [n - 1 ,s ,nfs ] * ufn [n ,s ,nfs ] * ds [n ,s ]) \
578- + (Ct [n ,s - 1 ,nfs ] * ufs [n ,s ,nfs ] * dn [n ,s ]) \
579- + pickup [n ,s ,nfs ] * ds [n ,s ] * dn [n ,s ] / dt ) \
580- / (+ (ufn [n + 1 ,s ,nfs ] * ds [n ,s ]) \
581- + (ufs [n ,s + 1 ,nfs ] * dn [n ,s ]))
582- q [n ,s ]= 1
583- # The second quadrant
584- for n in range (1 ,Ct .shape [0 ]):
585- for s in range (Ct .shape [1 ]- 2 ,- 1 ,- 1 ):
586- if (not q [n ,s ]) and (ufn [n ,s ,0 ]>= 0 ) and (ufs [n ,s ,0 ]<= 0 ) and (ufn [n + 1 ,s ,0 ]>= 0 ) and (ufs [n ,s + 1 ,0 ]<= 0 ):
587- Ct [n ,s ,:] = (+ (Ct [n - 1 ,s ,:] * ufn [n ,s ,:] * ds [n ,s ]) \
588- + ( - Ct [n ,s + 1 ,:] * ufs [n ,s + 1 ,:] * dn [n ,s ]) \
589- + w [n ,s ,:] * Cu [n ,s ,:] * ds [n ,s ] * dn [n ,s ] / Ts ) \
590- / ( + (ufn [n + 1 ,s ,:] * ds [n ,s ]) \
591- + (- ufs [n ,s ,:] * dn [n ,s ]) \
592- + (ds [n ,s ] * dn [n ,s ] / Ts ) )
593- #calculate pickup
594- pickup [n ,s ,:] = (w [n ,s ,:] * Cu [n ,s ,:]- Ct [n ,s ,:]) * dt / Ts
595- #check for supply limitations and re-iterate concentration to account for supply limitations
596- for nfs in range (0 ,nf ):
597- if pickup [n ,s ,nfs ]> mass [n ,s ,0 ,nfs ]:
598- pickup [n ,s ,nfs ] = mass [n ,s ,0 ,nfs ]
599- Ct [n ,s ,nfs ] = (+ (Ct [n - 1 ,s ,nfs ] * ufn [n ,s ,nfs ] * ds [n ,s ]) \
600- + ( - Ct [n ,s + 1 ,nfs ] * ufs [n ,s + 1 ,nfs ] * dn [n ,s ]) \
601- + pickup [n ,s ,nfs ] * ds [n ,s ] * dn [n ,s ] / dt ) \
602- / ( + (ufn [n + 1 ,s ,nfs ] * ds [n ,s ]) \
603- + (- ufs [n ,s ,nfs ] * dn [n ,s ]))
604- q [n ,s ]= 2
605- # The third quadrant
606- for n in range (Ct .shape [0 ]- 2 ,- 1 ,- 1 ):
607- for s in range (Ct .shape [1 ]- 2 ,- 1 ,- 1 ):
608- if (not q [n ,s ]) and (ufn [n ,s ,0 ]<= 0 ) and (ufs [n ,s ,0 ]<= 0 ) and (ufn [n + 1 ,s ,0 ]<= 0 ) and (ufs [n ,s + 1 ,0 ]<= 0 ):
609- Ct [n ,s ,:] = (+ ( - Ct [n + 1 ,s ,:] * ufn [n + 1 ,s ,:] * dn [n ,s ]) \
610- + ( - Ct [n ,s + 1 ,:] * ufs [n ,s + 1 ,:] * dn [n ,s ]) \
611- + w [n ,s ,:] * Cu [n ,s ,:] * ds [n ,s ] * dn [n ,s ] / Ts ) \
612- / ( + (- ufn [n ,s ,:] * dn [n ,s ]) \
613- + (- ufs [n ,s ,:] * dn [n ,s ]) \
614- + (ds [n ,s ] * dn [n ,s ] / Ts ) )
615- #calculate pickup
616- pickup [n ,s ,:] = (w [n ,s ,:] * Cu [n ,s ,:]- Ct [n ,s ,:]) * dt / Ts
617- #check for supply limitations and re-iterate concentration to account for supply limitations
618- for nfs in range (0 ,nf ):
619- if pickup [n ,s ,nfs ]> mass [n ,s ,0 ,nfs ]:
620- pickup [n ,s ,nfs ] = mass [n ,s ,0 ,nfs ]
621- Ct [n ,s ,nfs ] = (+ ( - Ct [n + 1 ,s ,nfs ] * ufn [n + 1 ,s ,nfs ] * dn [n ,s ]) \
622- + ( - Ct [n ,s + 1 ,nfs ] * ufs [n ,s + 1 ,nfs ] * dn [n ,s ]) \
623- + pickup [n ,s ,nfs ] * ds [n ,s ] * dn [n ,s ] / dt ) \
624- / ( + (- ufn [n ,s ,nfs ] * dn [n ,s ]) \
625- + (- ufs [n ,s ,nfs ] * dn [n ,s ]))
626- q [n ,s ]= 3
627- # The fourth guadrant including all remainnig unadressed cells
628- for n in range (Ct .shape [0 ]- 2 ,- 1 ,- 1 ):
629- for s in range (1 ,Ct .shape [1 ]):
630- if (not q [n ,s ]):
631- if (ufn [n ,s ,0 ]<= 0 ) and (ufs [n ,s ,0 ]>= 0 ) and (ufn [n + 1 ,s ,0 ]<= 0 ) and (ufs [n ,s + 1 ,0 ]>= 0 ):
632- # this is the fourth quadrant
633- Ct [n ,s ,:] = (+ (Ct [n ,s - 1 ,:] * ufs [n ,s ,:] * dn [n ,s ]) \
634- + ( - Ct [n + 1 ,s ,:] * ufn [n + 1 ,s ,:] * dn [n ,s ]) \
635- + w [n ,s ,:] * Cu [n ,s ,:] * ds [n ,s ] * dn [n ,s ] / Ts ) \
636- / ( + (ufs [n ,s + 1 ,:] * dn [n ,s ]) \
637- + (- ufn [n ,s ,:] * dn [n ,s ]) \
638- + (ds [n ,s ] * dn [n ,s ] / Ts ) )
639- #calculate pickup
640- pickup [n ,s ,:] = (w [n ,s ,:] * Cu [n ,s ,:]- Ct [n ,s ,:]) * dt / Ts
641- #check for supply limitations and re-iterate concentration to account for supply limitations
642- for nfs in range (0 ,nf ):
643- if pickup [n ,s ,nfs ]> mass [n ,s ,0 ,nfs ]:
644- pickup [n ,s ,nfs ] = mass [n ,s ,0 ,nfs ]
645- Ct [n ,s ,nfs ] = (+ (Ct [n ,s - 1 ,nfs ] * ufs [n ,s ,nfs ] * dn [n ,s ]) \
646- + ( - Ct [n + 1 ,s ,nfs ] * ufn [n + 1 ,s ,nfs ] * dn [n ,s ]) \
647- + pickup [n ,s ,nfs ] * ds [n ,s ] * dn [n ,s ] / dt ) \
648- / ( + (ufs [n ,s + 1 ,nfs ] * dn [n ,s ]) \
649- + (- ufn [n ,s ,nfs ] * dn [n ,s ]))
650- q [n ,s ]= 4
651- else :
652- if (not n == 0 ) and (not s == Ct .shape [1 ]- 1 ):
653- # This is where we apply a generic stencil where all posible directions on the cell boundaries are solved for.
654- # all remaining cells will be calculated for and q=5 is assigned.
655- # this stencil is nested in the q4 loop which is the final quadrant.
656- # grid boundaries are filtered in both if statements.
657- Ct [n ,s ,:] = (+ (ufn [n ,s ,0 ]> 0 ) * (Ct [n - 1 ,s ,:] * ufn [n ,s ,:] * ds [n ,s ]) \
658- + (ufs [n ,s ,0 ]> 0 ) * (Ct [n ,s - 1 ,:] * ufs [n ,s ,:] * dn [n ,s ]) \
659- + (ufn [n + 1 ,s ,0 ]< 0 ) * ( - Ct [n + 1 ,s ,:] * ufn [n + 1 ,s ,:] * dn [n ,s ]) \
660- + (ufs [n ,s + 1 ,0 ]< 0 ) * ( - Ct [n ,s + 1 ,:] * ufs [n ,s + 1 ,:] * dn [n ,s ]) \
661- + w [n ,s ,:] * Cu [n ,s ,:] * ds [n ,s ] * dn [n ,s ] / Ts ) \
662- / ( + (ufn [n + 1 ,s ,0 ]> 0 ) * (ufn [n + 1 ,s ,:] * ds [n ,s ]) \
663- + (ufs [n ,s + 1 ,0 ]> 0 ) * (ufs [n ,s + 1 ,:] * dn [n ,s ]) \
664- + (ufn [n ,s ,0 ]< 0 ) * (- ufn [n ,s ,:] * dn [n ,s ]) \
665- + (ufs [n ,s ,0 ]< 0 ) * (- ufs [n ,s ,:] * dn [n ,s ]) \
666- + (ds [n ,s ] * dn [n ,s ] / Ts ) )
667- #calculate pickup
668- pickup [n ,s ,:] = (w [n ,s ,:] * Cu [n ,s ,:]- Ct [n ,s ,:]) * dt / Ts
669- #check for supply limitations and re-iterate concentration to account for supply limitations
670- for nfs in range (0 ,nf ):
671- if pickup [n ,s ,nfs ]> mass [n ,s ,0 ,nfs ]:
672- pickup [n ,s ,nfs ] = mass [n ,s ,0 ,nfs ]
673- Ct [n ,s ,nfs ] = (+ (ufn [n ,s ,0 ]> 0 ) * (Ct [n - 1 ,s ,nfs ] * ufn [n ,s ,nfs ] * ds [n ,s ]) \
674- + (ufs [n ,s ,0 ]> 0 ) * (Ct [n ,s - 1 ,nfs ] * ufs [n ,s ,nfs ] * dn [n ,s ]) \
675- + (ufn [n + 1 ,s ,0 ]< 0 ) * ( - Ct [n + 1 ,s ,nfs ] * ufn [n + 1 ,s ,nfs ] * dn [n ,s ]) \
676- + (ufs [n ,s + 1 ,0 ]< 0 ) * ( - Ct [n ,s + 1 ,nfs ] * ufs [n ,s + 1 ,nfs ] * dn [n ,s ]) \
677- + pickup [n ,s ,nfs ] * ds [n ,s ] * dn [n ,s ] / dt ) \
678- / ( + (ufn [n + 1 ,s ,0 ]> 0 ) * (ufn [n + 1 ,s ,nfs ] * ds [n ,s ]) \
679- + (ufs [n ,s + 1 ,0 ]> 0 ) * (ufs [n ,s + 1 ,nfs ] * dn [n ,s ]) \
680- + (ufn [n ,s ,0 ]< 0 ) * (- ufn [n ,s ,nfs ] * dn [n ,s ]) \
681- + (ufs [n ,s ,0 ]< 0 ) * (- ufs [n ,s ,nfs ] * dn [n ,s ]))
682- q [n ,s ]= 5
558+ # The First quadrant (Numba-optimized)
559+ _solve_quadrant1 (Ct , Cu , mass , pickup , dt , Ts , ds , dn , ufs , ufn , w , visited , quad , nf )
560+
561+ # The second quadrant (Numba-optimized)
562+ _solve_quadrant2 (Ct , Cu , mass , pickup , dt , Ts , ds , dn , ufs , ufn , w , visited , quad , nf )
563+
564+ # The third quadrant (Numba-optimized)
565+ _solve_quadrant3 (Ct , Cu , mass , pickup , dt , Ts , ds , dn , ufs , ufn , w , visited , quad , nf )
566+
567+ # The fourth quadrant (Numba-optimized)
568+ _solve_quadrant4 (Ct , Cu , mass , pickup , dt , Ts , ds , dn , ufs , ufn , w , visited , quad , nf )
569+
570+ # Generic stencil for remaining cells including boundaries (Numba-optimized)
571+ _solve_generic_stencil (Ct , Cu , mass , pickup , dt , Ts , ds , dn , ufs , ufn , w , visited , quad , nf )
683572
684573
685574 k += 1
686-
687- # print(k)
688575
576+ # # plot Ct
577+ # import matplotlib.pyplot as plt
578+ # plt.imshow(quad[:10,:10], origin='lower')
579+ # # plt.colorbar()
580+ # plt.title('Concentration after %d sweeps' % k)
581+ # plt.show()
582+ # plt.imshow(Ct[:50,:50], origin='lower')
583+ # # plt.colorbar()
584+ # plt.title('Concentration after %d sweeps' % k)
585+ # plt.show()
586+ # plt.plot(pickup[0,:,0])
587+ # plt.plot(pickup[-1,:,0])
588+ # plt.show()
589+
590+ # print(k)
591+
592+
689593 # print("q1 = " + str(np.sum(q==1)) + " q2 = " + str(np.sum(q==2)) \
690594 # + " q3 = " + str(np.sum(q==3)) + " q4 = " + str(np.sum(q==4)) \
691595 # + " q5 = " + str(np.sum(q==5)))
0 commit comments