def compute_steady_state(self): names = {'Cl', 'Na', 'K'} P1 = FiniteElement('P', fe.triangle, 1) element = MixedElement([P1, P1, P1]) V = FunctionSpace(self.mesh, element) self.V_conc = V (u_cl, u_na, u_k) = TrialFunction(V) (v_cl, v_na, v_k) = TestFunction(V) assert (self.flow is not None) n = fe.FacetNormal(self.mesh) # F = ( self.F_diff_conv(u_cl, v_cl, n, grad(self.phi), 1. ,1., 0.) # + self.F_diff_conv(u_na, v_na, n, grad(self.phi), 1. ,1., 0.) # + self.F_diff_conv(u_k , v_k , n, grad(self.phi), 1. ,1., 0.) ) dx, ds = self.dx, self.ds flow = self.flow F = inner(grad(u_cl), grad(v_cl)) * dx \ + inner(flow, grad(u_cl)) * v_cl * dx \ + inner(grad(u_na), grad(v_na)) * dx \ + inner(flow, grad(u_na)) * v_na * dx \ + inner(grad(u_k), grad(v_k)) * dx \ + inner(flow, grad(u_k)) * v_k * dx a, L = fe.lhs(F), fe.rhs(F) a_mat = fe.assemble(a) L_vec = fe.assemble(L) # solve u = Function(V) fe.solve(a_mat, u.vector(), L_vec) u_cl, u_na, u_k = u.split() output1 = fe.File('/tmp/steady_state_cl.pvd') output1 << u_cl output2 = fe.File('/tmp/steady_state_na.pvd') output2 << u_na output3 = fe.File('/tmp/steady_state_k.pvd') output3 << u_k self.u_cl = u_cl self.u_na = u_na self.u_k = u_k
def set_data_dirs(self): if not os.path.exists(self.postprocessing_dir): os.makedirs(self.postprocessing_dir) if not os.path.exists(self.fem_solution_storage_dir): os.makedirs(self.fem_solution_storage_dir) if not os.path.exists(self.movie_dir): os.makedirs(self.movie_dir) if not os.path.exists(self.vtk_dir): os.makedirs(self.vtk_dir) if not os.path.exists(self.slope_field_dir): os.makedirs(self.slope_field_dir) if not os.path.exists(self.slope_field_movie_dir): os.makedirs(self.slope_field_movie_dir) if not os.path.exists(self.potential_dir): os.makedirs(self.potential_dir) if not os.path.exists(self.potential_movie_dir): os.makedirs(self.potential_movie_dir) txt = 'solution.pvd' fname = os.path.join(self.vtk_dir, txt) self.vtkfile = fe.File(fname)
def set_data_dirs(self): with_hg = 'HG-NPs_tumor-bearing' no_hg = 'NPS_TUMOR-BEARING' if self.use_hg: hg_state = with_hg else: hg_state = no_hg lambda_label = str(self.lam != 0) self.fem_opt_data_source_dir = os.path.join(os.getcwd(),\ 'raw_data/Tumor-bearing',\ hg_state) self.fem_opt_exp_data_vec_dir = os.path.join(\ self.fem_opt_data_source_dir,\ 'fem_m_' + str(self.experimental_z_n)) if not os.path.exists(self.fem_opt_exp_data_vec_dir): os.makedirs(self.fem_opt_exp_data_vec_dir) txt = 'diffusion_' + 'lambda_' + lambda_label self.fem_opt_img_storage_dir = os.path.join(\ self.fem_opt_data_source_dir,\ txt) if not os.path.exists(self.fem_opt_img_storage_dir): os.makedirs(self.fem_opt_img_storage_dir) txt = 'solution.pvd' fname = os.path.join(self.fem_opt_img_storage_dir, txt) self.vtkfile = fe.File(fname)
def create_cocontinuous_mesh(self): if self.use_previously_stored_mesh: self.mesh = fe.Mesh(self.mesh_fname) print('Mesh has been loaded from file') return p = self.L * np.ones(3) geo = mesher.Box(fe.Point(0,0,0), fe.Point(p)) net = self.extrude_base_net() columns = self.create_cylindrical_columns() net += columns if self.keep_only_network: geo = net else: geo -= net print('Finished creating the geometry') self.mesh = mesher.generate_mesh(geo, self.mesh_density); print('Writing mesh to file') mesh_file = fe.File(self.mesh_fname) mesh_file << self.mesh print('Finished writing mesh to file')
def mfem(): files = glob.glob('data/pvd/mfem/*') for f in files: try: os.remove(f) except Exception as e: print('Failed to delete {}, reason: {}' % (f, e)) plate = mshr.Rectangle(fe.Point(0, 0), fe.Point(100, 100)) mesh = mshr.generate_mesh(plate, 50) # mesh = fe.RectangleMesh(fe.Point(-2, -2), fe.Point(2, 2), 50, 50) x_hat = fe.SpatialCoordinate(mesh) U = fe.VectorFunctionSpace(mesh, 'CG', 2) V = fe.FunctionSpace(mesh, "CG", 1) W = fe.FunctionSpace(mesh, "DG", 0) # n = 21 # control_points = np.stack((np.linspace(0, 1, n), np.linspace(0, 1, n)), axis=1) # impact_radii = np.linspace(0., 0.5, n) rho_default = 25. / np.sqrt(5) * 2 control_points = np.array([[50., 50.], [62.5, 25.]]) impact_radii = np.array([rho_default, rho_default]) mid_point = np.array([75., 0.]) mid_point1 = np.array([100., 0.]) mid_point2 = np.array([50., 0.]) points = [mid_point, mid_point1, mid_point2] direct_vec = np.array([1., -2]) rotated_vec = np.array([2., 1.]) direct_vec /= np.linalg.norm(direct_vec) rotated_vec /= np.linalg.norm(rotated_vec) directions = [direct_vec, rotated_vec] boundary_info = [points, directions, rho_default] # df, xi = distance_function_segments_ufl(x_hat, control_points, impact_radii) # d = fe.project(df, V) delta_x = map_function_ufl(x_hat, control_points, impact_radii, boundary_info) - x_hat u = fe.project(delta_x, U) # e = fe.Function(U) # int_exp = InterpolateExpression(u, control_points, impact_radii) # e = fe.interpolate(int_exp, U) # int_exp = InterpolateExpression(e, control_points, impact_radii) # e = fe.project(int_exp, U) vtkfile_u = fe.File('data/pvd/mfem/u.pvd') u.rename("u", "u") vtkfile_u << u
def preprocess(fname): """Loads mesh, defines system of equations and prepares system matrix.""" mesh = fe.Mesh(fname + ".xml") if INPUTS['saving']['mesh']: fe.File(fname + "_mesh.pvd") << mesh boundaries = fe.MeshFunction('size_t', mesh, fname + '_facet_region.xml') if INPUTS['saving']['boundaries']: fe.File(fname + "_subdomains.pvd") << boundaries subdomains = fe.MeshFunction('size_t', mesh, fname + '_physical_region.xml') if INPUTS['saving']['subdomains']: fe.File(fname + "_subdomains.pvd") << subdomains if INPUTS['plotting']['mesh']: fe.plot(mesh, title='Mesh') if INPUTS['plotting']['boundaries']: fe.plot(boundaries, title='Boundaries') if INPUTS['plotting']['subdomains']: fe.plot(subdomains, title='Subdomains') fun_space = fe.FunctionSpace(mesh, INPUTS['element_type'], INPUTS['element_degree'], constrained_domain=PeriodicDomain()) if ARGS['--verbose']: dofmap = fun_space.dofmap() print('Number of DOFs:', len(dofmap.dofs())) field = fe.TrialFunction(fun_space) test_func = fe.TestFunction(fun_space) cond = Conductivity(subdomains, fe.Constant(INPUTS['conductivity']['gas']), fe.Constant(INPUTS['conductivity']['solid']), degree=0) system_matrix = -cond * fe.inner(fe.grad(field), fe.grad(test_func)) * fe.dx bctop = fe.Constant(INPUTS['boundary_conditions']['top']) bcbot = fe.Constant(INPUTS['boundary_conditions']['bottom']) bcs = [ fe.DirichletBC(fun_space, bctop, boundaries, 1), fe.DirichletBC(fun_space, bcbot, boundaries, 2) ] field = fe.Function(fun_space) return system_matrix, field, bcs, cond
def xest_second_tutorial(self): T = 2.0 # final time num_steps = 50 # number of time steps dt = T / num_steps # time step size # Create mesh and define function space nx = ny = 30 mesh = fenics.RectangleMesh(fenics.Point(-2, -2), fenics.Point(2, 2), nx, ny) V = fenics.FunctionSpace(mesh, 'P', 1) # Define boundary condition def boundary(x, on_boundary): return on_boundary bc = fenics.DirichletBC(V, fenics.Constant(0), boundary) # Define initial value u_0 = fenics.Expression('exp(-a*pow(x[0], 2) - a*pow(x[1], 2))', degree=2, a=5) u_n = fenics.interpolate(u_0, V) # Define variational problem u = fenics.TrialFunction(V) v = fenics.TestFunction(V) f = fenics.Constant(0) F = u * v * fenics.dx + dt * fenics.dot(fenics.grad(u), fenics.grad( v)) * fenics.dx - (u_n + dt * f) * v * fenics.dx a, L = fenics.lhs(F), fenics.rhs(F) # Create VTK file for saving solution vtkfile = fenics.File( os.path.join(os.path.dirname(__file__), 'output', 'heat_gaussian', 'solution.pvd')) # Time-stepping u = fenics.Function(V) t = 0 not_initialised = True for n in range(num_steps): # Update current time t += dt # Compute solution fenics.solve(a == L, u, bc) # Save to file and plot solution vtkfile << (u, t) # Here we'll need to call tripcolor ourselves to get access to the color range fenics.plot(u) animation_camera.snap() u_n.assign(u) animation = animation_camera.animate() animation.save( os.path.join(os.path.dirname(__file__), 'output', 'heat_gaussian.mp4'))
def setup_fe(self): # Define the relevant function spaces V = d.FunctionSpace(self.mesh, "Lagrange", 1) self.V = V # DG0 is useful for defining piecewise constant functions DV = d.FunctionSpace(self.mesh, "Discontinuous Lagrange", 0) self.DV = DV # Define test and trial functions for FE self.z = d.TrialFunction(self.V) self.w = d.TestFunction(self.V) regions = self.per_tissue_constant(lambda l: l) region_file = d.File("../%s-regions.pvd" % input_mesh) region_file << regions
def __init__(self): self.h = .4 # Cell properties self.obs_length = 0.9 self.obs_height = 0.001 self.obs_ratio = self.obs_height / self.obs_length if self.h < self.eta: raise ValueError("Eta must be smaller than h") self.ref_T = 0.1 self.eps = 2 * self.eta / MembraneSimulator.length self.mesh = fe.RectangleMesh( fe.Point(-1, 0), fe.Point(1, 2 * self.h / MembraneSimulator.length), 50, 50) self.cell_mesh = None self.D = np.matrix(((4 * self.ref_T * MembraneSimulator.d1 / MembraneSimulator.length**2, -0.05), (+0.05, 4 * self.ref_T * MembraneSimulator.d2 / MembraneSimulator.length**2))) # Dirichlet boundary conditions self.u_l = 6E-5 self.u_r = 0 self.u_boundary = fe.Expression( '(u_l*(x[0] < - par) + u_r*(x[0] >= par))', u_l=self.u_l, u_r=self.u_r, par=MembraneSimulator.w / MembraneSimulator.length, degree=2) self.u_0 = self.u_boundary / 2 # self.rhs = fe.Expression('(x[1]>par)*u',u=self.u_l*4,par=MembraneSimulator.eta/MembraneSimulator.length, degree=2) self.rhs = fe.Constant(0) self.time = 0 self.T = 1 self.dt = 0.01 self.tol = 1E-4 self.function_space = fe.FunctionSpace(self.mesh, 'P', 2) self.solution = fe.Function(self.function_space) self.cell_solutions = self.cell_fs = None self.unit_vectors = [fe.Constant((1., 0.)), fe.Constant((0., 1.))] self.eff_diff = np.zeros((2, 2)) self.file = fe.File('results/solution.pvd')
def run_solver_c( ndim, length, units, bcs, u0, powers, nx, F, coordinates=False, is_plot=False, vtk=False, ): ny = nx nz = nx if ndim == 3 else None u_D = fs.Constant(u0) if len(bcs) > 0 and bcs[0] != []: if ndim == 2: bc_funs = [LineBoundary(line).get_boundary() for line in bcs] else: bc_funs = [RecBoundary(rec).get_boundary() for rec in bcs] else: bc_funs = [lambda x, on_boundary: on_boundary] # 边界都为 Dirichlet f = SourceF(F, length) u = solver(f, u_D, bc_funs, ndim, length, nx, ny, nz) if is_plot: import matplotlib.pyplot as plt plt.plot(u) if vtk: vtkfile = fs.File("solution.pvd") vtkfile << u if ndim == 2: U = u.compute_vertex_values().reshape(nx + 1, nx + 1) else: U = u.compute_vertex_values().reshape(nx + 1, nx + 1, nx + 1) if coordinates: xs, ys, zs = get_mesh_grid(length, nx, ny, nz) else: xs, ys, zs = None, None, None return U, xs, ys, zs
def calculate_efield_fenics(si): numerical_vars = si.numerical_variables u = numerical_vars["ef_phi"] assert u is not None, "Please calculate the potential first!" print("Calculating the electric field... ", end="", flush=True) fenics_field = fn.project(-fn.grad(u), solver_type='cg', preconditioner_type='ilu') electric_field = FenicsField(fenics_field) numerical_vars["ef_itp"] = electric_field si.numerical_variables = numerical_vars fieldfile = fn.File(TEMP_DIR + '/e_field.pvd') fieldfile << fenics_field print("Done!", flush=True) return 0
def postprocess(fname, field, cond): """Postprocessing of the simulation.""" func_space = field.function_space() mesh = func_space.mesh() degree = func_space.ufl_element().degree() vec_func_space = fe.VectorFunctionSpace(mesh, INPUTS['element_type'], degree) flux = fe.project(-cond * fe.grad(field), vec_func_space) divergence = fe.project(-fe.div(cond * fe.grad(field)), func_space) flux_x, flux_y, flux_z = flux.split() av_flux = fe.assemble(flux_z * fe.dx) / ((XMAX - XMIN) * (YMAX - YMIN)) keff = av_flux * (ZMAX - ZMIN) / (INPUTS['boundary_conditions']['top'] - INPUTS['boundary_conditions']['bottom']) print('Effective conductivity: {0}'.format(keff)) with open(fname + "_keff.csv", 'w') as textfile: textfile.write('keff\n') textfile.write('{0}\n'.format(keff)) fe.File(fname + "_solution.pvd") << field if INPUTS['saving']['flux']: fe.File(fname + "_flux.pvd") << flux if INPUTS['saving']['flux_divergence']: fe.File(fname + "_flux_divergence.pvd") << divergence if INPUTS['saving']['flux_components']: fe.File(fname + "_flux_x.pvd") << flux_x fe.File(fname + "_flux_y.pvd") << flux_y fe.File(fname + "_flux_z.pvd") << flux_z if INPUTS['plotting']['solution']: fe.plot(field, title="Solution") if INPUTS['plotting']['flux']: fe.plot(flux, title="Flux") if INPUTS['plotting']['flux_divergence']: fe.plot(divergence, title="Divergence") if INPUTS['plotting']['flux_components']: fe.plot(flux_x, title='x-component of flux (-kappa*grad(u))') fe.plot(flux_y, title='y-component of flux (-kappa*grad(u))') fe.plot(flux_z, title='z-component of flux (-kappa*grad(u))') if True in INPUTS['plotting'].values(): fe.interactive()
def _write_fenics_file(data, path): fn.File(path) << data
def write_vtk(self): """ write the output """ vtkfile = FEN.File(self._vtk_filename) vtkfile << self._u
alpha / 2 * f**2 * fa.dx) control = da.Control(f) rf = da.ReducedFunctional(J, control) # set the initial value to be zero for optimization f.vector()[:] = 0 # N = len(f.vector()[:]) # f.vector()[:] = np.random.rand(N)*2 -1 problem = da.MoolaOptimizationProblem(rf) f_moola = moola.DolfinPrimalVector(f) solver = moola.BFGS(problem, f_moola, options={ 'jtol': 0, 'gtol': 1e-9, 'Hinit': "default", 'maxiter': 100, 'mem_lim': 10 }) sol = solver.solve() f_opt = sol['control'].data file = fa.File('f.pvd') f_opt.rename('f', 'f') file << f_opt file = fa.File('g.pvd') g.rename('g', 'g') file << g
def _load_fct(path): assert mesh, 'Need to specify a mesh on which to generate the region marker function' data = fn.MeshFunction('size_t', mesh, mesh.topology().dim()) fn.File(path) >> data return data
if MODEL: bcSet = [ bc_1, bc_2, bc_3, bc_inflow, bc_p, bc_v_x0, bc_v_x1, bc_v_y1, bc_v_in, bc_v_top ] else: bcSet = [bc_1, bc_2, bc_3, bc_inflow, bc_p] problem = fe.NonlinearVariationalProblem(weakForm, W0, bcSet, J=dFdW) solver = fe.NonlinearVariationalSolver(problem) prm = solver.parameters t = 0.0 t_end = 5.0 pFile = fe.File('Pressure.pvd') uFile = fe.File('Velocity.pvd') vFile = fe.File('Vorticity.pvd') wFile = fe.File('W.pvd') T = fe.FunctionSpace(mesh, 'CG', 1) #solver.solve() while t < t_end: print("t =", t) solver.solve() u1, p1 = W0.split() uFile << u1 pFile << p1 We.assign(W0) wFile << W0 omega = fe.curl(u) vFile << fe.project(fe.inner(omega, omega), T)
def __init__(self, optimization_problem): """Parent class for the optimization methods implemented in cashocs.optimization.methods Parameters ---------- optimization_problem : cashocs.ShapeOptimizationProblem the optimization problem """ self.line_search_broken = False self.has_curvature_info = False self.optimization_problem = optimization_problem self.form_handler = self.optimization_problem.form_handler self.state_problem = self.optimization_problem.state_problem self.config = self.state_problem.config self.adjoint_problem = self.optimization_problem.adjoint_problem self.shape_gradient_problem = self.optimization_problem.shape_gradient_problem self.gradient = self.shape_gradient_problem.gradient self.cost_functional = self.optimization_problem.reduced_cost_functional self.search_direction = fenics.Function( self.form_handler.deformation_space) if self.config.getboolean('Mesh', 'remesh', fallback=False): self.iteration = self.optimization_problem.temp_dict[ 'OptimizationRoutine'].get('iteration_counter', 0) else: self.iteration = 0 self.objective_value = 1.0 self.gradient_norm_initial = 1.0 self.relative_norm = 1.0 self.stepsize = 1.0 self.converged = False self.converged_reason = 0 self.output_dict = dict() try: self.output_dict[ 'cost_function_value'] = self.optimization_problem.temp_dict[ 'output_dict']['cost_function_value'] self.output_dict[ 'gradient_norm'] = self.optimization_problem.temp_dict[ 'output_dict']['gradient_norm'] self.output_dict['stepsize'] = self.optimization_problem.temp_dict[ 'output_dict']['stepsize'] self.output_dict[ 'MeshQuality'] = self.optimization_problem.temp_dict[ 'output_dict']['MeshQuality'] except (TypeError, KeyError): self.output_dict['cost_function_value'] = [] self.output_dict['gradient_norm'] = [] self.output_dict['stepsize'] = [] self.output_dict['MeshQuality'] = [] self.verbose = self.config.getboolean('Output', 'verbose', fallback=True) self.save_results = self.config.getboolean('Output', 'save_results', fallback=True) self.rtol = self.config.getfloat('OptimizationRoutine', 'rtol', fallback=1e-3) self.atol = self.config.getfloat('OptimizationRoutine', 'atol', fallback=0.0) self.maximum_iterations = self.config.getint('OptimizationRoutine', 'maximum_iterations', fallback=100) self.soft_exit = self.config.getboolean('OptimizationRoutine', 'soft_exit', fallback=False) self.save_pvd = self.config.getboolean('Output', 'save_pvd', fallback=False) self.result_dir = self.config.get('Output', 'result_dir', fallback='./') if self.save_pvd: self.state_pvd_list = [] for i in range(self.form_handler.state_dim): if self.form_handler.state_spaces[i].num_sub_spaces() > 0: self.state_pvd_list.append([]) for j in range(self.form_handler.state_spaces[i]. num_sub_spaces()): if self.optimization_problem.mesh_handler.do_remesh: self.state_pvd_list[i].append( fenics. File(self.result_dir + '/pvd/remesh_' + format( self.optimization_problem.temp_dict.get( 'remesh_counter', 0), 'd') + '_state_' + str(i) + '_' + str(j) + '.pvd')) else: self.state_pvd_list[i].append( fenics.File(self.result_dir + '/pvd/state_' + str(i) + '_' + str(j) + '.pvd')) else: if self.optimization_problem.mesh_handler.do_remesh: self.state_pvd_list.append( fenics.File(self.result_dir + '/pvd/remesh_' + format( self.optimization_problem.temp_dict .get('remesh_counter', 0), 'd') + '_state_' + str(i) + '.pvd')) else: self.state_pvd_list.append( fenics.File(self.result_dir + '/pvd/state_' + str(i) + '.pvd'))
def forward(lmin, pml, steps, Folder): """ Algorithm to solve the forward problem *Input arguments minl: Minimum lenght of element pml: Size of the absorbing layer in km steps: Number of timesteps Folder: Folder name for results *Output arguments c: Field of propagation speed in domain eta: Field of damping in domain histrec: Historical data receivers """ histrec = '' # Create and define function space V = fn.FunctionSpace(mesh, "CG", 1) w = fn.TrialFunction(V) v = fn.TestFunction(V) # Boundary conditions u0 = 0.0 bc = fn.DirichletBC(V, 0.0, fn.DomainBoundary()) # State variable and source space functions w = fn.Function(V, name="Veloc") w_ant1 = fn.Function(V) w_ant2 = fn.Function(V) q = fn.Function(V, name="Sourc") # Velocity mapping c_func = vel_c() c = fn.interpolate(c_func, V) velp_file = fn.File(Folder + "/Velp.pvd") velp_file << c # Damping mapping damping_func = damping(c.vector().get_local().min()) eta = fn.interpolate(damping_func, V) damp_file = fn.File(Folder + "/Damp.pvd") damp_file << eta # Current time we are solving for t = 0. # Number of timesteps solved ntimestep = int(0) # dt computation dt = critical_dt(lmin, c.vector().get_local().max(), steps) # Final time T = steps*dt print("Time step:", dt, "s") # "Bilinear term" def aterm(u, v, dt, c, eta): termgrad = dt**2*fn.inner(c, c)*fn.inner(fn.grad(u), fn.grad(v))*fn.dx termvare = (1.0 + dt*eta*fn.inner(c, c))*fn.inner(u, v)*fn.dx termboun = (dt**2*c*c)*fn.inner(fn.grad(u), n)*v*fn.ds return termgrad + termvare - termboun # Source term def lsourc(u_ant1, u_ant2, v, dt, c, q, eta): termua1 = (-2. + dt*eta*fn.inner(c, c))*fn.inner(u_ant1, v)*fn.dx termua2 = fn.inner(u_ant2, v)*fn.dx termsou = (dt**2*fn.inner(c, c))*fn.inner(q, v)*fn.dx return termua1 + termua2 - termsou # Output file names Exct = fn.File(Folder+"/Exct.pvd") Wave = fn.File(Folder+"/Wave.pvd") while True: # Update the time it is solving for print("Step: {0:1d} - Time: {1:1.4f}".format(ntimestep, t), "s") # Ricker source for time t ExcSource = RickerSource(t, tol=lmin/2) q.assign(fn.interpolate(ExcSource, V)) # Time integration loop if ntimestep < 1: g = fn.interpolate(fn.Expression('0.0', degree=2), V) w.assign(g) # assign initial guess for solver w_ant1.assign(g) # assign initial guess for solver w_ant2.assign(g) # assign initial guess for solver else: a = aterm(w, v, dt, c, eta) L = lsourc(w_ant1, w_ant2, v, dt, c, q, eta) #solve equation fn.solve(a + L == 0, w, bcs=bc, solver_parameters={"newton_solver": {"maximum_iterations": forward_max_it, "absolute_tolerance": forward_tol, "relative_tolerance": relativ_tol}}) # Cycling the variables w_ant2.assign(w_ant1) w_ant1.assign(w) #Output files # histrec += Receiver(t, posrec, pml, w) Exct << (q, t) Wave << (w, t) t += dt ntimestep += 1 if t >= T: break return c, eta, histrec
def _save_fct(data, path): fn.File(path) << data
prm['newton_solver']['krylov_solver']['relative_tolerance'] = 1E-5 prm['newton_solver']['krylov_solver']['maximum_iterations'] = 1000 prm['newton_solver']['krylov_solver']['nonzero_initial_guess'] = True if prm['newton_solver']['linear_solver'] == 'gmres': prm['newton_solver']['preconditioner'] = 'ilu' # Invoke the solver #cprint("\nSOLUTION OF THE NONLINEAR PROBLEM", 'blue', attrs=['bold']) #cprint("The solution of the nonlinear system is in progress...", 'red') solver.solve() ############################# POST-PROCESSING ################################ #cprint("\nSOLUTION POST-PROCESSING", 'blue', attrs=['bold']) # Save solution to file in VTK format #cprint("Saving displacement solution to file...", 'green') uViewer = fe.File('paraview/displacement.pvd') uViewer << u # Maximum and minimum displacement u_magnitude = fe.sqrt(fe.dot(u, u)) u_magnitude = fe.project(u_magnitude, W) print('Min/Max displacement:', u_magnitude.vector().array().min(), u_magnitude.vector().array().max()) # Computation of the large deformation strains #cprint("Computing the deformation tensor and saving to file...", 'green') epsilon_u = largeKinematics(u) epsilon_u_project = fe.project(epsilon_u, Z) epsilonViewer = fe.File('paraview/strain.pvd') epsilonViewer << epsilon_u_project
def staggered_solve(self): self.U = fe.VectorFunctionSpace(self.mesh, 'CG', 1) self.W = fe.FunctionSpace(self.mesh, 'CG', 1) self.WW = fe.FunctionSpace(self.mesh, 'DG', 0) self.EE = fe.TensorFunctionSpace(self.mesh, 'DG', 0) self.MM = fe.VectorFunctionSpace(self.mesh, 'CG', 1) self.eta = fe.TestFunction(self.U) self.zeta = fe.TestFunction(self.W) q = fe.TestFunction(self.WW) del_x = fe.TrialFunction(self.U) del_d = fe.TrialFunction(self.W) p = fe.TrialFunction(self.WW) self.x_new = fe.Function(self.U, name="u") self.d_new = fe.Function(self.W, name="d") self.d_pre = fe.Function(self.W) self.x_pre = fe.Function(self.U) x_old = fe.Function(self.U) d_old = fe.Function(self.W) self.H_old = fe.Function(self.WW) self.map_plot = fe.Function(self.MM, name="m") e = fe.Function(self.EE, name="e") self.create_custom_xdmf_files() self.file_results = fe.XDMFFile('data/xdmf/{}/u.xdmf'.format( self.case_name)) self.file_results.parameters["functions_share_mesh"] = True vtkfile_e = fe.File('data/pvd/simulation/{}/e.pvd'.format( self.case_name)) vtkfile_u = fe.File('data/pvd/simulation/{}/u.pvd'.format( self.case_name)) vtkfile_d = fe.File('data/pvd/simulation/{}/d.pvd'.format( self.case_name)) for i, (disp, rp) in enumerate( zip(self.displacements, self.relaxation_parameters)): print('\n') print( '=================================================================================' ) print('>> Step {}, disp boundary condition = {} [mm]'.format( i, disp)) print( '=================================================================================' ) self.i = i self.update_weak_form_due_to_Model_C_bug() if self.update_weak_form: self.set_bcs_staggered() print("Update weak form...") self.build_weak_form_staggered() print("Taking derivatives of weak form...") J_u = fe.derivative(self.G_u, self.x_new, del_x) J_d = fe.derivative(self.G_d, self.d_new, del_d) print("Define nonlinear problems...") p_u = fe.NonlinearVariationalProblem(self.G_u, self.x_new, self.BC_u, J_u) p_d = fe.NonlinearVariationalProblem(self.G_d, self.d_new, self.BC_d, J_d) print("Define solvers...") solver_u = fe.NonlinearVariationalSolver(p_u) solver_d = fe.NonlinearVariationalSolver(p_d) self.update_weak_form = False print("Update history weak form") a = p * q * fe.dx L = history(self.H_old, self.update_history(), self.psi_cr) * q * fe.dx if self.map_flag: self.interpolate_map() # delta_x = self.x - self.x_hat # self.map_plot.assign(fe.project(delta_x, self.MM)) self.presLoad.t = disp newton_prm = solver_u.parameters['newton_solver'] newton_prm['maximum_iterations'] = 100 # newton_prm['absolute_tolerance'] = 1e-8 newton_prm['relaxation_parameter'] = rp newton_prm = solver_d.parameters['newton_solver'] newton_prm['maximum_iterations'] = 100 # newton_prm['absolute_tolerance'] = 1e-8 newton_prm['relaxation_parameter'] = rp vtkfile_e_staggered = fe.File( 'data/pvd/simulation/{}/step{}/e.pvd'.format( self.case_name, i)) vtkfile_u_staggered = fe.File( 'data/pvd/simulation/{}/step{}/u.pvd'.format( self.case_name, i)) vtkfile_d_staggered = fe.File( 'data/pvd/simulation/{}/step{}/d.pvd'.format( self.case_name, i)) iteration = 0 err = 1. while err > self.staggered_tol: iteration += 1 solver_d.solve() solver_u.solve() if self.solution_scheme == 'explicit': break # # Remarks(Tianju): self.x_new.vector() does not behave as expected: producing nan values # The following lines of codes cause issues # We use an error measure similar in https://doi.org/10.1007/s10704-019-00372-y # np_x_new = np.asarray(self.x_new.vector()) # np_d_new = np.asarray(self.d_new.vector()) # np_x_old = np.asarray(x_old.vector()) # np_d_old = np.asarray(d_old.vector()) # err_x = np.linalg.norm(np_x_new - np_x_old) / np.sqrt(len(np_x_new)) # err_d = np.linalg.norm(np_d_new - np_d_old) / np.sqrt(len(np_d_new)) # err = max(err_x, err_d) # # Remarks(Tianju): dolfin (2019.1.0) errornorm function has severe bugs not behave as expected # The bug seems to be fixed in later versions # The following sometimes produces nonzero results in dolfin (2019.1.0) # print(fe.errornorm(self.d_new, self.d_new, norm_type='l2')) err_x = fe.errornorm(self.x_new, x_old, norm_type='l2') err_d = fe.errornorm(self.d_new, d_old, norm_type='l2') err = max(err_x, err_d) x_old.assign(self.x_new) d_old.assign(self.d_new) e.assign( fe.project(strain(self.mfem_grad(self.x_new)), self.EE)) print( '---------------------------------------------------------------------------------' ) print( '>> iteration. {}, err_u = {:.5}, err_d = {:.5}, error = {:.5}' .format(iteration, err_x, err_d, err)) print( '---------------------------------------------------------------------------------' ) # vtkfile_e_staggered << e # vtkfile_u_staggered << self.x_new # vtkfile_d_staggered << self.d_new if err < self.staggered_tol or iteration >= self.staggered_maxiter: print( '=================================================================================' ) print('\n') break print("L2 projection to update the history function...") fe.solve(a == L, self.H_old, []) # self.d_pre.assign(self.d_new) # self.H_old.assign(fe.project(history(self.H_old, self.update_history(), self.psi_cr), self.WW)) if self.map_flag and not self.finish_flag: self.update_map() if self.compute_and_save_intermediate_results: print("Save files...") self.file_results.write(e, i) self.file_results.write(self.x_new, i) self.file_results.write(self.d_new, i) self.file_results.write(self.map_plot, i) vtkfile_e << e vtkfile_u << self.x_new vtkfile_d << self.d_new # Assume boundary is not affected by the map. # There's no need to use the mfem_grad wrapper so that fe.grad is used for speed-up print("Define forces...") sigma = cauchy_stress_plus(strain(fe.grad(self.x_new)), self.psi) sigma_minus = cauchy_stress_minus(strain(fe.grad(self.x_new)), self.psi_minus) sigma_plus = cauchy_stress_plus(strain(fe.grad(self.x_new)), self.psi_plus) sigma_degraded = g_d(self.d_new) * sigma_plus + sigma_minus print("Compute forces...") if self.case_name == 'pure_shear': f_full = float(fe.assemble(sigma[0, 1] * self.ds(1))) f_degraded = float( fe.assemble(sigma_degraded[0, 1] * self.ds(1))) else: f_full = float(fe.assemble(sigma[1, 1] * self.ds(1))) f_degraded = float( fe.assemble(sigma_degraded[1, 1] * self.ds(1))) print("Force full is {}".format(f_full)) print("Force degraded is {}".format(f_degraded)) self.delta_u_recorded.append(disp) self.force_full.append(f_full) self.force_degraded.append(f_degraded) # if force_upper < 0.5 and i > 10: # break if self.display_intermediate_results and i % 10 == 0: self.show_force_displacement() self.save_data_in_loop() if self.display_intermediate_results: plt.ioff() plt.show()
def run_solver( ndim, length, length_unit, bcs, layout_list, u0, powers, nx, coordinates=False, is_plot=False, F=None, vtk=False, ): """求解器主函数. Args: ndim (int): 2 or 3, 问题维数 length (float): board length length_unit (float): unit length bcs (list): bcs layout_list (list): unit 位置 u0 (float): Dirichlet bc 上的值 powers (list): 功率 list nx (int): x 方向上的单元数 coordinates (bool, optional): 是否返回坐标矩阵. Defaults to False. is_plot (bool, optional): 是否画图. Defaults to False. F (ndarray, optional): 热源布局矩阵 F. Defaults to None. vtk (bool): 是否输出 vtk 文件. Returns: tuple: U, xs, ys, zs """ ny = nx nz = nx if ndim == 3 else None u_D = fs.Constant(u0) if len(bcs) > 0 and bcs[0] != []: if ndim == 2: bc_funs = [LineBoundary(line).get_boundary() for line in bcs] else: bc_funs = [RecBoundary(rec).get_boundary() for rec in bcs] else: bc_funs = [lambda x, on_boundary: on_boundary] # 边界都为 Dirichlet if F is None: f = Source(layout_list, length, length_unit, powers) else: f = SourceF(F, length) u = solver(f, u_D, bc_funs, ndim, length, nx, ny, nz) if is_plot: import matplotlib.pyplot as plt plt.plot(u) if vtk: vtkfile = fs.File("solution.pvd") vtkfile << u if ndim == 2: U = u.compute_vertex_values().reshape(nx + 1, nx + 1) else: U = u.compute_vertex_values().reshape(nx + 1, nx + 1, nx + 1) if coordinates: xs, ys, zs = get_mesh_grid(length, nx, ny, nz) else: xs, ys, zs = None, None, None return U, xs, ys, zs
def store_solution(self): # Store the solution to file vtkfile = fe.File('results/solution.pvd') vtkfile << self.solution
L = f * v * fex.dx # Compute solution u = fex.Function(V) fex.solve(a == L, u, bc) print(u) # Plot solution and mesh plt.subplot(2, 1, 1) fex.plot(u) #define the boundary conditions plt.subplot(2, 1, 2) fex.plot(mesh) plt.savefig('possion_fex2.png') #define the boundary conditions # Save solution to file in VTK format vtkfile = fex.File('poisson/solution.pvd') vtkfile << u # Compute error in L2 norm error_L2 = fex.errornorm(u_D, u, 'L2') # Compute maximum error at vertices vertex_values_u_D = u_D.compute_vertex_values(mesh) vertex_values_u = u.compute_vertex_values(mesh) import numpy as np error_max = np.max(np.abs(vertex_values_u_D - vertex_values_u)) # Print errors print('error_L2 =', error_L2) print('error_max =', error_max)
boundaries[edge.index()] = idx idx += 1 else: interior[key] = nodes sections = fn.MeshFunction('size_t', mesh, dim=2) sections.set_all(0) for num, (key, value) in enumerate(Faces.items(), 1): for node in value: ver = fn.Vertex(mesh, node) for cell in fn.cells(ver): entity = cell.entities(0) if all(item in value for item in entity): sections[cell.index()] = num fn.File("./UserFiles/boundaries.pvd") << boundaries fn.File("./UserFiles/sections.pvd") << sections F = fn.Function(V) File = fn.File("./UserFiles/result.pvd") for i in range(10): t = 0 + (i + 1) / 10 F.interpolate(fn.Expression("x[0]+5*t*x[1]", t=t, degree=2)) File << (F, t) ''' changes made: element numbering starts from zero node numbering starts from zero group node numbering is reduced by one dimension remained at 3 '''
# currently simplifications p_act = 0. lmb_f = 2. W_iso = c_10 * (I_1 - 3) + c_01 * (I_2 - 3) + 0.5 * kappa * (J - 1)**2 dx = fe.dx ds = fe.ds P = fe.diff(W_iso, F) S = 2 * fe.diff(W_iso, C) F_static = inner(S, DE(v)) * dx - rho * inner(b, v) * dx - inner( t_bar, v) * ds + (p / kappa + J - 1) * q * dx #F_static = inner(P, grad(v))*dx - rho*inner(b, v)*dx - inner(t_bar, v)*ds + (p/kappa + J - 1)*q*dx file_u = fe.File("../results/displacement.pvd") file_p = fe.File("../results/pressure.pvd") bcul = fe.DirichletBC(V.sub(0), u_left, left) bcur = fe.DirichletBC(V.sub(0), u_right, right) #bcpl = fe.DirichletBC(V.sub(1), p_left, left) bcs = [bcul, bcur] # bcpl] J_static = fe.derivative(F_static, w, dw) #fe.solve(F_static==0, w, bcs) ffc_options = {"optimize": True} problem = fe.NonlinearVariationalProblem(F_static, w, bcs,
solver = fe.NonlinearVariationalSolver(problem) #usol = fe.Function(W) prm = solver.parameters #prm["newton_solver"]["absolute_tolerance"] = 5E-1 solver.solve() if MODEL: u, p, nu_t = W0.split() else: u, p = W0.split() #------------------------------------------------- # Save this solution to a file for post-processing #------------------------------------------------- vtkFile = fe.File('u.pvd') vtkFile << u vtkFile = fe.File('p.pvd') vtkFile << p if MODEL: vtkFile = fe.File('nut.pvd') vtkFile << nu_t if MODEL: T = fe.FunctionSpace(mesh, 'CG', 1) #T = fe.TensorFunctionSpace(mesh, 'CG', 1) vtkFile = fe.File('fw.pvd') vtkFile << fe.project(fw, T) vtkFile = fe.File('g.pvd') vtkFile << fe.project(g, T) vtkFile = fe.File('r.pvd')
import fenics import pde import rheology from settings import * import testcases fenics.set_log_level(fenics.ERROR) fluid = rheology.Sigmoid(rho, mu, ty, eps) problem = testcases.Poiseuille(nx, ny) u, u0 = problem.define_functions() algorithm = pde.Abali(problem, dt, fluid, u, u0) outdir = './output/' file_p = fenics.File(outdir + problem.name + '_' + fluid.name + '_' + 'pressure.pvd') file_v = fenics.File(outdir + problem.name + '_' + fluid.name + '_' + 'velocity.pvd') t = 0.0 step = 0 change = 1 print('step\t time\t vmax\t change') while t < t_end and change > sstol: step += 1 t += dt algorithm.advance(u) pressure, velocity = u.split(deepcopy=True)
nn = fn.FacetNormal(mesh) # Defintion of function spaces Vh = fn.VectorElement("CG", mesh.ufl_cell(), 2) Zh = fn.FiniteElement("CG", mesh.ufl_cell(), 1) Qh = fn.FiniteElement("CG", mesh.ufl_cell(), 2) # spaces for displacement and total pressure should be compatible # whereas the space for fluid pressure can be "anything". In particular the one for total pressure Hh = fn.FunctionSpace(mesh, fn.MixedElement([Vh, Zh, Qh])) (u, phi, p) = fn.TrialFunctions(Hh) (v, psi, q) = fn.TestFunctions(Hh) fileU = fn.File(mesh.mpi_comm(), "Output/2_5_1_Footing_wall_removed/u.pvd") filePHI = fn.File(mesh.mpi_comm(), "Output/2_5_1_Footing_wall_removed/phi.pvd") fileP = fn.File(mesh.mpi_comm(), "Output/2_5_1_Footing_wall_removed/p.pvd") # ******** Model constants ********** # E = 3.0e4 nu = 0.4995 lmbda = E * nu / ((1. + nu) * (1. - 2. * nu)) mu = E / (2. * (1. + nu)) c0 = 1.0e-3 kappa = 1.0e-6 alpha = 0.1 sigma0 = 1.5e4 eta = fn.Constant(1.0)