aboutsummaryrefslogtreecommitdiffstats
path: root/fg21sim/extragalactic/clusters/solver.py
diff options
context:
space:
mode:
authorAaron LI <aly@aaronly.me>2017-10-12 16:43:26 +0800
committerAaron LI <aly@aaronly.me>2017-10-12 16:43:26 +0800
commit9d719d212770d81b522e2a480fbc75f52a0891ee (patch)
treece68d723d2925f5cb8f5736e0557c0d141669161 /fg21sim/extragalactic/clusters/solver.py
parentc3d3d396dcf9cf86682089dd972f56643373f6b3 (diff)
downloadfg21sim-9d719d212770d81b522e2a480fbc75f52a0891ee.tar.bz2
clusters/solver.py: significantly improve fix_boundary()
Also suggest that ``buffer_np`` be specified to 5%-10% of ``x_np``.
Diffstat (limited to 'fg21sim/extragalactic/clusters/solver.py')
-rw-r--r--fg21sim/extragalactic/clusters/solver.py40
1 files changed, 30 insertions, 10 deletions
diff --git a/fg21sim/extragalactic/clusters/solver.py b/fg21sim/extragalactic/clusters/solver.py
index da6b4d4..f7724dd 100644
--- a/fg21sim/extragalactic/clusters/solver.py
+++ b/fg21sim/extragalactic/clusters/solver.py
@@ -104,6 +104,7 @@ class FokkerPlanckSolver:
boundary. The densities within this buffer region will be replaced
by extrapolating an power law to avoid unphysical accumulations.
This fix is ignored if this parameter is not specified.
+ (This parameter is suggested to be about 5%-10% of ``x_np``.)
NOTE
----
@@ -332,7 +333,11 @@ class FokkerPlanckSolver:
is determined by fitting to the data points of ``self.buffer_np``
cells on the upper side of the buffer region.
- TODO: also fix the upper boundary in the same way?
+ NOTE
+ ----
+ * Also fix the upper boundary in the same way.
+ * Fix the boundaries only when the particles are piling up at the
+ boundaries.
References: Ref.[donnert2014],Sec.(3.3)
"""
@@ -343,15 +348,30 @@ class FokkerPlanckSolver:
return uc
x = self.x
- # Calculate the power-law index for ``self.buffer_np`` from data
- # points just right of the buffer region.
- xp = x[self.buffer_np:(self.buffer_np*2)]
- yp = uc[self.buffer_np:(self.buffer_np*2)]
- # Power-law fit
- pfit = np.polyfit(np.log10(xp), np.log10(yp), deg=1)
- xbuf = x[:self.buffer_np]
- ybuf = 10 ** np.polyval(pfit, np.log10(xbuf))
- uc[:self.buffer_np] = ybuf
+ # Lower boundary
+ ybuf = uc[:self.buffer_np]
+ if ybuf[0] > ybuf[1]:
+ # Particles are piling up at the lower boundary, to fix it...
+ #
+ # Power-law fit
+ xp = x[self.buffer_np:(self.buffer_np*2)]
+ yp = uc[self.buffer_np:(self.buffer_np*2)]
+ pfit = np.polyfit(np.log(xp), np.log(yp), deg=1)
+ xbuf = x[:self.buffer_np]
+ ybuf = np.exp(np.polyval(pfit, np.log(xbuf)))
+ uc[:self.buffer_np] = ybuf
+
+ # Upper boundary
+ ybuf = uc[(-self.buffer_np):]
+ if ybuf[-1] > ybuf[-2]:
+ # Particles are piling up at the upper boundary, to fix it...
+ xp = x[(-self.buffer_np*2):(-self.buffer_np)]
+ yp = uc[(-self.buffer_np*2):(-self.buffer_np)]
+ pfit = np.polyfit(np.log(xp), np.log(yp), deg=1)
+ xbuf = x[(-self.buffer_np):]
+ ybuf = np.exp(np.polyval(pfit, np.log(xbuf)))
+ uc[(-self.buffer_np):] = ybuf
+
return uc
def time_step(self):