def _calculate_media(self, check_start=40, check_interval_growth=5): check_interval = check_interval_growth limiting = max(self.spec.uptake_rate, self.spec.diffusion_constant) dt = 1.0/(4*limiting) cells = self._narrow_cells() boundary = self._make_boundary_layer(cells) media = np.ones_like(cells, np.float32)*self.spec.media_concentration # guess a linear solution for faster convergence heights = utils.compute_heights(np.logical_not(boundary)) for col, height in enumerate(heights): if height == 0: continue media[:height, col] = np.linspace(0, self.spec.media_concentration, height) media_next = np.empty_like(media) # def error_handler(type, flag): # if type == "underflow": return # np.seterr(all='warn') # print "Floating point error (%s), with flag %s" % (type, flag) # print dt, self.spec.diffusion_constant, self.spec.uptake_rate # print self.spec.media_concentration # from matplotlib import pyplot as plt # plt.figure(); plt.imshow(media); plt.colorbar() # plt.figure(); plt.imshow(media_next); plt.colorbar() # plt.figure(); plt.imshow(boundary); plt.colorbar() # plt.figure(); plt.imshow(cells); plt.colorbar() # plt.show() # print step # raise Exception() # np.seterrcall(error_handler) # np.seterr(all='call') for step in range(self.spec.max_diffusion_iterations): laplace(media, output=media_next) media_next *= self.spec.diffusion_constant*dt media_next += media media_next[cells] *= 1 - self.spec.uptake_rate*dt media_next[boundary] = self.spec.media_concentration media, media_next = media_next, media if step >= check_start and step%check_interval == 0: media_next -= media np.abs(media_next, out=media_next) error = media_next.sum()/(dt*media_next.size) if error <= self.spec.diffusion_tol: break check_interval += check_interval_growth self.media = media
def _compute_heights(result): return utils.compute_heights(result.image)