def pv(self): if self.__pv is None and self.__upv is not None: self.__pv = fe.Function(V_pv) fe.assign(self.__pv.sub(0), self.upv.sub(1)) fe.assign(self.__pv.sub(1), self.upv.sub(2)) return self.__pv
def restart(self): logPERIODIC('restart') self.t = self.t0 U0comps = evenodd_functions( omesh=self.omesh, degree=self.degree, func=self.U0, evenodd=self.symmetries, width=self.xmax ) rho0comps = evenodd_functions( omesh=self.omesh, degree=self.degree, func=self.rho0, evenodd=self.symmetries, width=self.xmax ) coords = gather_dof_coords(rho0comps[0].function_space()) for i in range(2**self.dim): fe.assign(self.sol.sub(i), function_interpolate(rho0comps[i], self.SS, coords=coords)) fe.assign(self.sol.sub(i + 2**self.dim), function_interpolate(U0comps[i], self.SS, coords=coords))
def restart(self): logVARIABLE('restart') self.set_time(self.t0) CE = FiniteElement('CG', cellShapes[self.dim - 1], self.degree) CS = FunctionSpace(self.mesh, CE) # scalar space coords = gather_dof_coords(CS) fe.assign(self.sol.sub(0), function_interpolate(self.rho0, self.SS, coords=coords)) for i, U0i in enumerate(self.U0s): fe.assign(self.sol.sub(i + 1), function_interpolate(U0i, self.SS, coords=coords))
def restart(self): logSOLVER('restart') self.t = self.t0 CE = FiniteElement('CG', cellShapes[self.dim - 1], self.degree) CS = FunctionSpace(self.mesh, CE) # scalar space coords = gather_dof_coords(CS) logSOLVER('function_interpolate(self.U0, self.SS, coords=coords)', function_interpolate(self.U0, self.SS, coords=coords)) fe.assign(self.sol.sub(1), function_interpolate(self.U0, self.SS, coords=coords)) logSOLVER('U0 assign returned') fe.assign(self.sol.sub(0), function_interpolate(self.rho0, self.SS, coords=coords))
def restart(self): logPERIODIC('restart') self.t = self.t0 U0comps = [None] * self.nligands * 2**self.dim for i, U0i in enumerate(self.U0s): eofuncs = evenodd_functions(omesh=self.omesh, degree=self.degree, func=U0i, evenodd=self.symmetries, width=self.xmax) U0comps[i * 2**self.dim:(i + 1) * 2**self.dim] = eofuncs rho0comps = evenodd_functions(omesh=self.omesh, degree=self.degree, func=self.rho0, evenodd=self.symmetries, width=self.xmax) coords = gather_dof_coords(rho0comps[0].function_space()) for i in range(2**self.dim): fe.assign( self.sol.sub(i), function_interpolate(rho0comps[i], self.SS, coords=coords)) for i in range(self.nligands * 2**self.dim): fe.assign(self.sol.sub(i + 2**self.dim), function_interpolate(U0comps[i], self.SS, coords=coords))
def discretize(self): """Builds function space, call again after introducing constraints""" # FEniCS interface self.mesh = fn.IntervalMesh(self.N, self.x0_scaled, self.x1_scaled) # http://www.femtable.org/ # Argyris* ARG # Arnold-Winther* AW # Brezzi-Douglas-Fortin-Marini* BDFM # Brezzi-Douglas-Marini BDM # Bubble B # Crouzeix-Raviart CR # Discontinuous Lagrange DG # Discontinuous Raviart-Thomas DRT # Hermite* HER # Lagrange CG # Mardal-Tai-Winther* MTW # Morley* MOR # Nedelec 1st kind H(curl) N1curl # Nedelec 2nd kind H(curl) N2curl # Quadrature Q # Raviart-Thomas RT # Real R # construct test and trial function space from elements # spanned by Lagrange polynomials for the pyhsical variables of # potential and concentration and global elements with a single degree # of freedom ('Real') for constraints. # For an example of this approach, refer to # https://fenicsproject.org/docs/dolfin/latest/python/demos/neumann-poisson/demo_neumann-poisson.py.html # For another example on how to construct and split function spaces # for solving coupled equations, refer to # https://fenicsproject.org/docs/dolfin/latest/python/demos/mixed-poisson/demo_mixed-poisson.py.html P = fn.FiniteElement('Lagrange', fn.interval, 3) R = fn.FiniteElement('Real', fn.interval, 0) elements = [P] * (1 + self.M) + [R] * self.K H = fn.MixedElement(elements) self.W = fn.FunctionSpace(self.mesh, H) # solution functions self.w = fn.Function(self.W) # set initial values if available P = fn.FunctionSpace(self.mesh, 'P', 1) dof2vtx = fn.vertex_to_dof_map(P) if self.ui0 is not None: x = np.linspace(self.x0_scaled, self.x1_scaled, self.ui0.shape[0]) ui0 = scipy.interpolate.interp1d(x, self.ui0) # use linear interpolation on mesh self.u0_func = fn.Function(P) self.u0_func.vector()[:] = ui0(self.X)[dof2vtx] fn.assign(self.w.sub(0), fn.interpolate(self.u0_func, self.W.sub(0).collapse())) if self.ni0 is not None: x = np.linspace(self.x0_scaled, self.x1_scaled, self.ni0.shape[1]) ni0 = scipy.interpolate.interp1d(x, self.ni0) self.p0_func = [fn.Function(P)] * self.ni0.shape[0] for k in range(self.ni0.shape[0]): self.p0_func[k].vector()[:] = ni0(self.X)[k, :][dof2vtx] fn.assign( self.w.sub(1 + k), fn.interpolate(self.p0_func[k], self.W.sub(k + 1).collapse())) # u represents voltage , p concentrations uplam = fn.split(self.w) self.u, self.p, self.lam = (uplam[0], [*uplam[1:(self.M + 1)]], [*uplam[(self.M + 1):]]) # v, q and mu represent respective test functions vqmu = fn.TestFunctions(self.W) self.v, self.q, self.mu = (vqmu[0], [*vqmu[1:(self.M + 1)]], [*vqmu[(self.M + 1):]])
AA = fn.assemble(Left) solver = fn.LUSolver(AA) solver.parameters["reuse_factorization"] = True # time loop inc = 0 while (t <= T): print "t =", t # solve BB = fn.assemble(Right) solver.solve(Sol.vector(), BB) # output to file u, v = Sol.split() if (inc % frequencySave == 0): u.rename("u", "u") fileu << (u, t) v.rename("v", "v") filev << (v, t) # update old values fn.assign(uold, u) fn.assign(vold, v) # increment t += dt inc += 1
def up(self): if self.__up is None and self.__upv is not None: self.__up = fe.Function(V_up) fe.assign(self.__up.sub(0), self.__upv.sub(0)) fe.assign(self.__up.sub(1), self.__upv.sub(1)) return self.__up
def xest_implement_1d_myosin(self): #Parameters total_time = 10.0 number_of_time_steps = 1000 # delta_t = fenics.Constant(total_time/number_of_time_steps) delta_t = total_time / number_of_time_steps nx = 1000 domain_size = 1.0 b = fenics.Constant(6.0) k = fenics.Constant(0.5) z_1 = fenics.Constant(-10.5) #always negative # z_1 = fenics.Constant(0.0) #always negative z_2 = 0.1 # always positive xi_0 = fenics.Constant(1.0) #always positive xi_1 = fenics.Constant(1.0) #always positive xi_2 = 0.001 #always positive xi_3 = 0.0001 #always negative d = fenics.Constant(0.15) alpha = fenics.Constant(1.0) c = fenics.Constant(0.1) # Sub domain for Periodic boundary condition class PeriodicBoundary(fenics.SubDomain): # Left boundary is "target domain" G def inside(self, x, on_boundary): return bool(-fenics.DOLFIN_EPS < x[0] < fenics.DOLFIN_EPS and on_boundary) def map(self, x, y): y[0] = x[0] - 1 periodic_boundary_condition = PeriodicBoundary() #Set up finite elements mesh = fenics.IntervalMesh(nx, 0.0, 1.0) vector_element = fenics.FiniteElement('P', fenics.interval, 1) single_element = fenics.FiniteElement('P', fenics.interval, 1) mixed_element = fenics.MixedElement(vector_element, single_element) V = fenics.FunctionSpace( mesh, mixed_element, constrained_domain=periodic_boundary_condition) # V = fenics.FunctionSpace(mesh, mixed_element) v, r = fenics.TestFunctions(V) full_trial_function = fenics.Function(V) u, rho = fenics.split(full_trial_function) full_trial_function_n = fenics.Function(V) u_n, rho_n = fenics.split(full_trial_function_n) u_initial = fenics.Constant(0.0) # rho_initial = fenics.Expression('1.0*sin(pi*x[0])*sin(pi*x[0])+1.0/k0', degree=2,k0 = k) rho_initial = fenics.Expression('1/k0', degree=2, k0=k) u_n = fenics.interpolate(u_initial, V.sub(0).collapse()) rho_n = fenics.interpolate(rho_initial, V.sub(1).collapse()) # perturbation = np.zeros(rho_n.vector().size()) # perturbation[:int(perturbation.shape[0]/2)] = 1.0 rho_n.vector().set_local( np.array(rho_n.vector()) + 1.0 * (0.5 - np.random.random(rho_n.vector().size()))) # u_n.vector().set_local(np.array(u_n.vector())+4.0*(0.5-np.random.random(u_n.vector().size()))) fenics.assign(full_trial_function_n, [u_n, rho_n]) u_n, rho_n = fenics.split(full_trial_function_n) F = (u * v * fenics.dx - u_n * v * fenics.dx + delta_t * (b + (z_1 * rho) / (1 + z_2 * rho) * c * xi_1) * u.dx(0) * v.dx(0) * fenics.dx - delta_t * (z_1 * rho) / (1 + z_2 * rho) * c * c * xi_2 / 2.0 * u.dx(0) * u.dx(0) * v.dx(0) * fenics.dx + delta_t * (z_1 * rho) / (1 + z_2 * rho) * c * c * c * xi_3 / 6.0 * u.dx(0) * u.dx(0) * u.dx(0) * v.dx(0) * fenics.dx - delta_t * z_1 * rho / (1 + z_2 * rho) * xi_0 * v.dx(0) * fenics.dx + u.dx(0) * v.dx(0) * fenics.dx - u_n.dx(0) * v.dx(0) * fenics.dx + rho * r * fenics.dx - rho_n * r * fenics.dx - rho * u * r.dx(0) * fenics.dx + rho * u_n * r.dx(0) * fenics.dx + delta_t * d * rho.dx(0) * r.dx(0) * fenics.dx + delta_t * k * fenics.exp(alpha * u.dx(0)) * rho * r * fenics.dx - delta_t * r * fenics.dx + delta_t * c * u.dx(0) * r * fenics.dx) vtkfile_rho = fenics.File( os.path.join(os.path.dirname(__file__), 'output', 'myosin_2d', 'solution_rho.pvd')) vtkfile_u = fenics.File( os.path.join(os.path.dirname(__file__), 'output', 'myosin_2d', 'solution_u.pvd')) # rho_0 = fenics.Expression(((('0.0'),('0.0'),('0.0')),('sin(x[0])')), degree=1 ) # full_trial_function_n = fenics.project(rho_0, V) # print('initial u and rho') # print(u_n.vector()) # print(rho_n.vector()) time = 0.0 not_initialised = True plt.figure() for time_index in range(number_of_time_steps): # Update current time time += delta_t # Compute solution fenics.solve(F == 0, full_trial_function) # Save to file and plot solution vis_u, vis_rho = full_trial_function.split() plt.subplot(311) fenics.plot(vis_u, color='blue') plt.ylim(-0.5, 0.5) plt.subplot(312) fenics.plot(-vis_u.dx(0), color='blue') plt.ylim(-2, 2) plt.title('actin density change') plt.subplot(313) fenics.plot(vis_rho, color='blue') plt.title('myosin density') plt.ylim(0, 7) plt.tight_layout() if not_initialised: animation_camera = celluloid.Camera(plt.gcf()) not_initialised = False animation_camera.snap() print('time is') print(time) # plt.savefig(os.path.join(os.path.dirname(__file__),'output','this_output_at_time_' + '{:04d}'.format(time_index) + '.png')) # print('this u and rho') # print(np.array(vis_u.vector())) # print(np.array(vis_rho.vector())) # vtkfile_rho << (vis_rho, time) # vtkfile_u << (vis_u, time) full_trial_function_n.assign(full_trial_function) animation = animation_camera.animate() animation.save( os.path.join(os.path.dirname(__file__), 'output', 'myosin_1D.mp4'))
def navierStokes(projectId, mesh, faceSets, boundarySets, config): log("Navier Stokes Analysis has started") # this is the default directory, when user request for download all files in this directory is being compressed and sent to the user resultDir = "./Results/" if len(config["steps"]) > 1: return "more than 1 step is not supported yet" # config is a dictionary containing all the user inputs for solver configurations t_init = 0.0 t_final = float(config['steps'][0]["finalTime"]) t_num = int(config['steps'][0]["iterationNo"]) dt = ((t_final - t_init) / t_num) t = t_init # # Viscosity coefficient. # nu = float(config['materials'][0]["viscosity"]) rho = float(config['materials'][0]["density"]) # # Declare Finite Element Spaces # do not use triangle directly P2 = fn.VectorElement("P", mesh.ufl_cell(), 2) P1 = fn.FiniteElement("P", mesh.ufl_cell(), 1) TH = fn.MixedElement([P2, P1]) V = fn.VectorFunctionSpace(mesh, "P", 2) Q = fn.FunctionSpace(mesh, "P", 1) W = fn.FunctionSpace(mesh, TH) # # Declare Finite Element Functions # (u, p) = fn.TrialFunctions(W) (v, q) = fn.TestFunctions(W) w = fn.Function(W) u0 = fn.Function(V) p0 = fn.Function(Q) # # Macros needed for weak formulation. # def contract(u, v): return fn.inner(fn.nabla_grad(u), fn.nabla_grad(v)) def b(u, v, w): return 0.5 * (fn.inner(fn.dot(u, fn.nabla_grad(v)), w) - fn.inner(fn.dot(u, fn.nabla_grad(w)), v)) # Define boundaries bcs = [] for BC in config['BCs']: if BC["boundaryType"] == "wall": for edge in json.loads(BC["edges"]): bcs.append( fn.DirichletBC(W.sub(0), fn.Constant((0.0, 0.0, 0.0)), boundarySets, int(edge), method='topological')) if BC["boundaryType"] == "inlet": vel = json.loads(BC['value']) for edge in json.loads(BC["edges"]): bcs.append( fn.DirichletBC(W.sub(0), fn.Expression( (str(vel[0]), str(vel[1]), str(vel[2])), degree=2), boundarySets, int(edge), method='topological')) if BC["boundaryType"] == "outlet": for edge in json.loads(BC["edges"]): bcs.append( fn.DirichletBC(W.sub(1), fn.Constant(float(BC['value'])), boundarySets, int(edge), method='topological')) f = fn.Constant((0.0, 0.0, 0.0)) # weak form NSE NSE = (1.0/dt)*fn.inner(u, v)*fn.dx + b(u0, u, v)*fn.dx + nu * \ contract(u, v)*fn.dx - fn.div(v)*p*fn.dx + q*fn.div(u)*fn.dx LNSE = fn.inner(f, v) * fn.dx + (1. / dt) * fn.inner(u0, v) * fn.dx velocity_file = fn.XDMFFile(resultDir + "/vel.xdmf") pressure_file = fn.XDMFFile(resultDir + "/pressure.xdmf") velocity_file.parameters["flush_output"] = True velocity_file.parameters["functions_share_mesh"] = True pressure_file.parameters["flush_output"] = True pressure_file.parameters["functions_share_mesh"] = True # # code for projecting a boundary condition into a file for visualization # # for bc in bcs: # bc.apply(w.vector()) # fn.File("para_plotting/bc.pvd") << w.sub(0) for jj in range(0, t_num): t = t + dt # print('t = ' + str(t)) A, b = fn.assemble_system(NSE, LNSE, bcs) fn.solve(A, w.vector(), b) # fn.solve(NSE==LNSE,w,bcs) fn.assign(u0, w.sub(0)) fn.assign(p0, w.sub(1)) # Save Solutions to Paraview File if (jj % 20 == 0): velocity_file.write(u0, t) pressure_file.write(p0, t) sendFile(projectId, resultDir + "vel.xdmf") sendFile(projectId, resultDir + "vel.h5") sendFile(projectId, resultDir + "pressure.xdmf") sendFile(projectId, resultDir + "pressure.h5") statusUpdate(projectId, "STARTED", {"progress": jj / t_num * 100})
Reactions = vold/dt * w * fn.dx + f(vold, nold) * w * fn.dx \ + nold/dt * m * dx + g(vold, nold) * m * fn.dx # ************* Time loop ******** start = time.clock(); inc = 0 while (t <= Tfinal): print "t =", t # solve KR = Reactions + Istim(t)*w*dx fn.solve(WeakKarma == KR, Ksol, solver_parameters={'linear_solver':'bicgstab'}) v, n = Ksol.split() # save solution if (inc % frequency == 0): v.rename("v","v"); filev << (v,t) n.rename("n","n"); filen << (n,t) # update fn.assign(vold, v); fn.assign(nold, n) # increment t += dt; inc += 1 # time elapsed print "Time elapsed: ", time.clock()-start
def v(self, val): self.__v = None self.__uv = None self.__pv = None fe.assign(self.__upv.sub(2), val)
def p(self, val): self.__p = None self.__up = None self.__pv = None fe.assign(self.__upv.sub(1), val)
def u(self, val): self.__u = None self.__up = None self.__uv = None fe.assign(self.__upv.sub(0), val)
def upv(self, val): self.reset() fe.assign(self.__upv, val)
h_g.t = t # solution solution = fn.Function(Hh) # solve fn.solve(left_hand_side == right_hand_side, solution, boundary_conditions) # split u, phi, p = solution.split() # save if divisible by frequency if iteration % frequency == 0: u.rename("u", "u") phi.rename("phi", "phi") p.rename("p", "p") pvdU << (u, t) pvdPHI << (phi, t) pvdP << (p, t) # update solutions #fn.assign(u_old, u) fn.assign(phi_old, phi) fn.assign(p_old, p) # update time t += dt iteration += 1
def u(self): if self.__u is None and self.__upv is not None: self.__u = fe.Function(V_u) fe.assign(self.__u, self.__upv.sub(0)) return self.__u
def p(self): if self.__p is None and self.__upv is not None: self.__p = fe.Function(V_p) fe.assign(self.__p, self.__upv.sub(1)) return self.__p
# solve reaction-diffusion fn.solve(rd_left_hand_side == rd_rhs_2, rd_solution) # split E, n = rd_solution.split() # save if divisible by frequency if iteration % frequency == 0: u.rename("u", "u") phi.rename("phi", "phi") p.rename("p", "p") E.rename("E", "E") n.rename("n", "n") pvdU << (u, t) pvdPHI << (phi, t) pvdP << (p, t) pvdE << (E, t) pvdN << (n, t) # update solutions fn.assign(u_old, u) fn.assign(phi_old, phi) fn.assign(p_old, p) fn.assign(E_old, E) fn.assign(n_old, n) # update time t += dt iteration += 1
def v(self): if self.__v is None and self.__upv is not None: self.__v = fe.Function(V_v) fe.assign(self.__v, self.__upv.sub(2)) return self.__v
def solve(self): """Solves the state system. Returns ------- states : list[dolfin.function.function.Function] The solution of the state system. """ if not self.has_solution: if self.initial_guess is not None: for j in range(self.form_handler.state_dim): fenics.assign(self.states[j], self.initial_guess[j]) if not self.form_handler.state_is_picard or self.form_handler.state_dim == 1: if self.form_handler.state_is_linear: for i in range(self.form_handler.state_dim): A, b = _assemble_petsc_system( self.form_handler.state_eq_forms_lhs[i], self.form_handler.state_eq_forms_rhs[i], self.bcs_list[i]) _solve_linear_problem( self.ksps[i], A, b, self.states[i].vector().vec(), self.form_handler.state_ksp_options[i]) self.states[i].vector().apply('') else: for i in range(self.form_handler.state_dim): if self.initial_guess is not None: fenics.assign(self.states[i], self.initial_guess[i]) self.states[i] = damped_newton_solve( self.form_handler.state_eq_forms[i], self.states[i], self.bcs_list[i], rtol=self.newton_rtol, atol=self.newton_atol, max_iter=self.newton_iter, damped=self.newton_damped, verbose=self.newton_verbose, ksp=self.ksps[i], ksp_options=self.form_handler.state_ksp_options[i]) else: for i in range(self.maxiter + 1): res = 0.0 for j in range(self.form_handler.state_dim): res_j = fenics.assemble( self.form_handler.state_picard_forms[j]) [ bc.apply(res_j) for bc in self.form_handler.bcs_list_ad[j] ] if self.number_of_solves == 0 and i == 0: self.newton_atols[j] = res_j.norm( 'l2') * self.newton_atol if res_j.norm('l2') == 0.0: self.newton_atols[j] = self.newton_atol res += pow(res_j.norm('l2'), 2) if res == 0: break res = np.sqrt(res) if i == 0: res_0 = res if self.picard_verbose: print('Iteration ' + str(i) + ': ||res|| (abs): ' + format(res, '.3e') + ' ||res|| (rel): ' + format(res / res_0, '.3e')) if res / res_0 < self.rtol or res < self.atol: break if i == self.maxiter: raise NotConvergedError( 'Picard iteration for the state system') for j in range(self.form_handler.state_dim): if self.initial_guess is not None: fenics.assign(self.states[j], self.initial_guess[j]) # adapt tolerances so that a solution is possible if not self.form_handler.state_is_linear: self.ksps[j].setTolerances( rtol=np.minimum(0.9 * res, 0.9) / 100, atol=self.newton_atols[j] / 100) self.states[j] = damped_newton_solve( self.form_handler.state_eq_forms[j], self.states[j], self.bcs_list[j], rtol=np.minimum(0.9 * res, 0.9), atol=self.newton_atols[j], max_iter=self.newton_iter, damped=self.newton_damped, verbose=self.newton_verbose, ksp=self.ksps[j], ksp_options=self.form_handler. state_ksp_options[j]) else: A, b = _assemble_petsc_system( self.form_handler.state_eq_forms_lhs[j], self.form_handler.state_eq_forms_rhs[j], self.bcs_list[j]) _solve_linear_problem( self.ksps[j], A, b, self.states[j].vector().vec(), self.form_handler.state_ksp_options[j]) self.states[j].vector().apply('') if self.picard_verbose and self.form_handler.state_is_picard: print('') self.has_solution = True self.number_of_solves += 1 return self.states
plt.figure() plt.scatter(qq[:, 0], qq[:, 1], c=zz) plt.title('zz') #### Test vector function space #### V_vec = fenics.VectorFunctionSpace(V.mesh(), V.ufl_element().family(), V.ufl_element().degree()) f = fenics.Function(V_vec) f0 = fenics.interpolate( fenics.Expression('sin(x[0]) + cos(x[1])', element=V.ufl_element()), V) f1 = fenics.interpolate( fenics.Expression('cos(x[0]) + sin(x[1])', element=V.ufl_element()), V) fenics.assign(f.sub(0), f0) fenics.assign(f.sub(1), f1) f.set_allow_extrapolation(True) t = time() eval_f = FenicsFunctionFastGridEvaluator(f) dt_construct_grid_evaluator = time() - t print('dt_construct_grid_evaluator=', dt_construct_grid_evaluator) n_test = int(1e4) qq = np.random.rand(n_test, d) qq = qq[np.linalg.norm(qq - 0.5, axis=1) < 0.5] n_test = qq.shape[0] t = time() zz = eval_f(qq) dt_interpn_vec = time() - t