def space_from_string(space_string: str, mesh: df.Mesh, dim: int) -> df.FunctionSpace: """ Constructed a finite elements space from a string representation of the space Arguments --------- space_string : str A string on the form {familiy}_{degree} which determines the space. Example 'Lagrange_1'. mesh : dolfin.Mesh The mesh dim : int 1 for scalar space, 3 for vector space. """ family, degree = space_string.split("_") if dim == 3: V = df.FunctionSpace( mesh, df.VectorElement( family=family, cell=mesh.ufl_cell(), degree=int(degree), quad_scheme="default", ), ) elif dim == 1: V = df.FunctionSpace( mesh, df.FiniteElement( family=family, cell=mesh.ufl_cell(), degree=int(degree), quad_scheme="default", ), ) else: raise df.error("Cannot create function space of dimension {dim}") return V
def project_gradients( mesh: df.Mesh, scalar_solutions: Dict[str, df.Function], fiber_space: str = "CG_1", ) -> Dict[str, np.ndarray]: """ Calculate the gradients using projections Arguments --------- mesh : dolfin.Mesh The mesh fiber_space : str A string on the form {familiy}_{degree} which determines for what space the fibers should be calculated for. scalar_solutions: dict A dictionary with the scalar solutions that you want to compute the gradients of. """ Vv = utils.space_from_string(fiber_space, mesh, dim=3) V = utils.space_from_string(fiber_space, mesh, dim=1) data = {} V_cg = df.FunctionSpace(mesh, df.VectorElement("Lagrange", mesh.ufl_cell(), 1)) for case, scalar_solution in scalar_solutions.items(): scalar_solution_int = df.interpolate(scalar_solution, V) if case != "lv_rv": gradient_cg = df.project(df.grad(scalar_solution), V_cg, solver_type="cg") gradient = df.interpolate(gradient_cg, Vv) # Add gradient data data[case + "_gradient"] = gradient.vector().get_local() # Add scalar data if case != "apex": data[case + "_scalar"] = scalar_solution_int.vector().get_local() # Return data return data
height=1.0, degree=3) # Generate particles x = RandomCircle(Point(x0, y0), r).generate([pres, pres]) s = np.zeros((len(x), 1), dtype=np.float_) # Initialize particles with position x and scalar property s at the mesh p = particles(x, [s], mesh) property_idx = 1 # Scalar quantity is stored at slot 1 # Initialize advection class, use RK3 scheme ap = advect_rk3(p, V, uh, "open") # Define the variational (projection problem) W_e = FiniteElement("DG", mesh.ufl_cell(), k) T_e = FiniteElement("DG", mesh.ufl_cell(), 0) Wbar_e = FiniteElement("DGT", mesh.ufl_cell(), k) W = FunctionSpace(mesh, W_e) T = FunctionSpace(mesh, T_e) Wbar = FunctionSpace(mesh, Wbar_e) psi_h, psi0_h = Function(W), Function(W) lambda_h = Function(T) psibar_h = Function(Wbar) # Boundary conditions bc = DirichletBC(Wbar, Constant(0.0), "on_boundary") # Initialize forms
class Ball_in_tube(object): def __init__(self): # https://fenicsproject.org/qa/12891/initialize-mesh-from-vertices-connectivities-at-once points, cells, _, cell_data, _ = meshes.ball_in_tube_cyl.generate() # 2018.1 # self.mesh = Mesh( # dolfin.mpi_comm_world(), dolfin.cpp.mesh.CellType.Type_triangle, # points[:, :2], cells['triangle'] # ) with TemporaryDirectory() as temp_dir: tmp_filename = os.path.join(temp_dir, "test.xml") meshio.write_points_cells( tmp_filename, points, cells, cell_data=cell_data, file_format="dolfin-xml", ) self.mesh = Mesh(tmp_filename) V0_element = FiniteElement("CG", self.mesh.ufl_cell(), 2) V1_element = FiniteElement("B", self.mesh.ufl_cell(), 3) self.W = FunctionSpace(self.mesh, V0_element * V1_element) self.P = FunctionSpace(self.mesh, "CG", 1) # Define mesh and boundaries. class LeftBoundary(SubDomain): # pylint: disable=no-self-use def inside(self, x, on_boundary): return on_boundary and x[0] < GMSH_EPS left_boundary = LeftBoundary() class RightBoundary(SubDomain): # pylint: disable=no-self-use def inside(self, x, on_boundary): return on_boundary and x[0] > 1.0 - GMSH_EPS right_boundary = RightBoundary() class LowerBoundary(SubDomain): # pylint: disable=no-self-use def inside(self, x, on_boundary): return on_boundary and x[1] < GMSH_EPS lower_boundary = LowerBoundary() # class UpperBoundary(SubDomain): # # pylint: disable=no-self-use # def inside(self, x, on_boundary): # return on_boundary and x[1] > 5.0-GMSH_EPS class CoilBoundary(SubDomain): # pylint: disable=no-self-use def inside(self, x, on_boundary): # One has to pay a little bit of attention when defining the # coil boundary; it's easy to miss the edges closest to x[0]=0. return ( on_boundary and x[1] > 1.0 - GMSH_EPS and x[1] < 2.0 + GMSH_EPS and x[0] < 1.0 - GMSH_EPS ) coil_boundary = CoilBoundary() self.u_bcs = [ DirichletBC(self.W, (0.0, 0.0), right_boundary), DirichletBC(self.W.sub(0), 0.0, left_boundary), DirichletBC(self.W, (0.0, 0.0), lower_boundary), DirichletBC(self.W, (0.0, 0.0), coil_boundary), ] self.p_bcs = [] # self.p_bcs = [DirichletBC(Q, 0.0, upper_boundary)] return
def save_files_visualization(visualization_folder, dvp_, t, save_deg, mesh, **namespace): # Files for storing results if not "d_file" in namespace.keys(): d_file = XDMFFile( MPI.comm_world, str(visualization_folder.joinpath("displacement.xdmf"))) v_file = XDMFFile(MPI.comm_world, str(visualization_folder.joinpath("velocity.xdmf"))) p_file = XDMFFile(MPI.comm_world, str(visualization_folder.joinpath("pressure.xdmf"))) for tmp_t in [d_file, v_file, p_file]: tmp_t.parameters["flush_output"] = True tmp_t.parameters["rewrite_function_mesh"] = False if save_deg > 1: mesh_viz = Mesh(mesh) # copy the mesh for i in range(save_deg - 1): mesh_viz = refine(mesh_viz) # refine the mesh dve_viz = VectorElement('CG', mesh_viz.ufl_cell(), 1) pe_viz = FiniteElement('CG', mesh_viz.ufl_cell(), 1) FSdv_viz = FunctionSpace( mesh_viz, dve_viz) # Visualisation FunctionSpace for d and v FSp_viz = FunctionSpace( mesh_viz, pe_viz) # Visualisation FunctionSpace for p return_dict = dict(v_file=v_file, d_file=d_file, p_file=p_file, FSdv_viz=FSdv_viz, FSp_viz=FSp_viz) else: return_dict = dict(v_file=v_file, d_file=d_file, p_file=p_file) namespace.update(return_dict) else: return_dict = {} # Split function d = dvp_["n"].sub(0, deepcopy=True) v = dvp_["n"].sub(1, deepcopy=True) p = dvp_["n"].sub(2, deepcopy=True) if save_deg > 1: d = project(d, namespace["FSdv_viz"]) v = project(v, namespace["FSdv_viz"]) p = project(p, namespace["FSp_viz"]) # Name function d.rename("Displacement", "d") v.rename("Velocity", "v") p.rename("Pressure", "p") # Write results namespace["d_file"].write(d, t) namespace["v_file"].write(v, t) namespace["p_file"].write(p, t) return return_dict
if __name__ == "__main__": xlim = 0.0, 3.0 ylim = 0.0, 0.0127 WAid = 12 INid = 13 BND_ids = WAid, INid meszf = 0.001 # mesh element size factor Domain, Facets = Generate_PBRpygmsh(xlim, ylim, BND_ids, meszf, folder='pygmeshio_test') mesh_D = Mesh() with XDMFFile(Domain) as infile: infile.read(mesh_D) mesh_F = Mesh() with XDMFFile(Facets) as infile: infile.read(mesh_F) print('num_cells :', mesh_D.num_cells()) print('num_vertices:', mesh_D.num_vertices()) print('cell_type :', mesh_D.ufl_cell()) #print('num_facets:', mesh_F.num_facets()) #print('num_edges:', mesh_F.num_edges())
class Ball_in_tube(object): def __init__(self): # https://fenicsproject.org/qa/12891/initialize-mesh-from-vertices-connectivities-at-once points, cells, _, cell_data, _ = meshes.ball_in_tube_cyl.generate() # 2018.1 # self.mesh = Mesh( # dolfin.mpi_comm_world(), dolfin.cpp.mesh.CellType.Type_triangle, # points[:, :2], cells['triangle'] # ) with TemporaryDirectory() as temp_dir: tmp_filename = os.path.join(temp_dir, "test.xml") meshio.write_points_cells( tmp_filename, points, cells, cell_data=cell_data, file_format="dolfin-xml", ) self.mesh = Mesh(tmp_filename) V0_element = FiniteElement("CG", self.mesh.ufl_cell(), 2) V1_element = FiniteElement("B", self.mesh.ufl_cell(), 3) self.W = FunctionSpace(self.mesh, V0_element * V1_element) self.P = FunctionSpace(self.mesh, "CG", 1) # Define mesh and boundaries. class LeftBoundary(SubDomain): # pylint: disable=no-self-use def inside(self, x, on_boundary): return on_boundary and x[0] < GMSH_EPS left_boundary = LeftBoundary() class RightBoundary(SubDomain): # pylint: disable=no-self-use def inside(self, x, on_boundary): return on_boundary and x[0] > 1.0 - GMSH_EPS right_boundary = RightBoundary() class LowerBoundary(SubDomain): # pylint: disable=no-self-use def inside(self, x, on_boundary): return on_boundary and x[1] < GMSH_EPS lower_boundary = LowerBoundary() # class UpperBoundary(SubDomain): # # pylint: disable=no-self-use # def inside(self, x, on_boundary): # return on_boundary and x[1] > 5.0-GMSH_EPS class CoilBoundary(SubDomain): # pylint: disable=no-self-use def inside(self, x, on_boundary): # One has to pay a little bit of attention when defining the # coil boundary; it's easy to miss the edges closest to x[0]=0. return (on_boundary and x[1] > 1.0 - GMSH_EPS and x[1] < 2.0 + GMSH_EPS and x[0] < 1.0 - GMSH_EPS) coil_boundary = CoilBoundary() self.u_bcs = [ DirichletBC(self.W, (0.0, 0.0), right_boundary), DirichletBC(self.W.sub(0), 0.0, left_boundary), DirichletBC(self.W, (0.0, 0.0), lower_boundary), DirichletBC(self.W, (0.0, 0.0), coil_boundary), ] self.p_bcs = [] # self.p_bcs = [DirichletBC(Q, 0.0, upper_boundary)] return
def save_files_visualization(visualization_folder, dvp_, t, save_deg, v_deg, p_deg, mesh, domains, **namespace): # Files for storing results if not "d_file" in namespace.keys(): d_file = XDMFFile(MPI.comm_world, str(visualization_folder.joinpath("displacement.xdmf"))) v_file = XDMFFile(MPI.comm_world, str(visualization_folder.joinpath("velocity.xdmf"))) p_file = XDMFFile(MPI.comm_world, str(visualization_folder.joinpath("pressure.xdmf"))) for tmp_t in [d_file, v_file, p_file]: tmp_t.parameters["flush_output"] = True tmp_t.parameters["rewrite_function_mesh"] = False if save_deg > 1: # Create function space for d, v and p dve = VectorElement('CG', mesh.ufl_cell(), v_deg) pe = FiniteElement('CG', mesh.ufl_cell(), p_deg) FSdv = FunctionSpace(mesh, dve) # Higher degree FunctionSpace for d and v FSp= FunctionSpace(mesh, pe) # Higher degree FunctionSpace for p # Copy mesh mesh_viz = Mesh(mesh) for i in range(save_deg-1): mesh_viz = refine(mesh_viz) # refine the mesh domains_viz = adapt(domains,mesh_viz) # refine the domains (so we can output domain IDs of refined mesh) # Create visualization function space for d, v and p dve_viz = VectorElement('CG', mesh_viz.ufl_cell(), 1) pe_viz = FiniteElement('CG', mesh_viz.ufl_cell(), 1) FSdv_viz = FunctionSpace(mesh_viz, dve_viz) # Visualisation FunctionSpace for d and v FSp_viz = FunctionSpace(mesh_viz, pe_viz) # Visualisation FunctionSpace for p # Create lower-order function for visualization on refined mesh d_viz = Function(FSdv_viz) v_viz = Function(FSdv_viz) p_viz = Function(FSp_viz) # Create a transfer matrix between higher degree and lower degree (visualization) function spaces dv_trans = PETScDMCollection.create_transfer_matrix(FSdv,FSdv_viz) p_trans = PETScDMCollection.create_transfer_matrix(FSp,FSp_viz) return_dict = dict(v_file=v_file, d_file=d_file, p_file=p_file, d_viz=d_viz,v_viz=v_viz, p_viz=p_viz, dv_trans=dv_trans, p_trans=p_trans, mesh_viz=mesh_viz, domains_viz=domains_viz) else: return_dict = dict(v_file=v_file, d_file=d_file, p_file=p_file) namespace.update(return_dict) else: return_dict = {} # Split function d = dvp_["n"].sub(0, deepcopy=True) v = dvp_["n"].sub(1, deepcopy=True) p = dvp_["n"].sub(2, deepcopy=True) if save_deg > 1: # To save higher-order nodes # Interpolate by using the transfer matrix between higher degree and lower degree (visualization) function spaces namespace["d_viz"].vector()[:] = namespace["dv_trans"]*d.vector() namespace["v_viz"].vector()[:] = namespace["dv_trans"]*v.vector() namespace["p_viz"].vector()[:] = namespace["p_trans"]*p.vector() write_solution(namespace["d_viz"], namespace["v_viz"], namespace["p_viz"], namespace["d_file"], namespace["v_file"], namespace["p_file"], t) # Write results else: # To save only the corner nodes write_solution(d, v, p, namespace["d_file"], namespace["v_file"], namespace["p_file"], t) # Write results return return_dict
meshio.write(os.path.join(Wri_path, "md_.xdmf"), triangle_mesh) meshio.xdmf.write(os.path.join(Wri_path, "mf_.xdmf"), line_mesh) # Reading mesh data stored in .xdmf files. mesh = Mesh() with XDMFFile(os.path.join(Wri_path, "md_.xdmf")) as infile: infile.read(mesh) mvc = MeshValueCollection("size_t", mesh, 1) with XDMFFile(os.path.join(Wri_path, "mf_.xdmf")) as infile: infile.read(mvc, "name_to_read") mf = cpp.mesh.MeshFunctionSizet(mesh, mvc) # Define function spaces for PDEs variational formulation. P1 = FiniteElement('P', mesh.ufl_cell(), 1) # Lagrange 1-order polynomials family element = MixedElement([P1, P1, P1, P1]) V = FunctionSpace(mesh, element) # Test functions function_space = FunctionSpace(mesh, P1) # Splitting test and trial functions v_A, v_B, v_C, v_T = TestFunctions(V) u = Function(V) u_n = Function(V) u_A, u_B, u_C, u_T = split(u) # Retrieve boundaries marks for Robin boundary conditions. ds_in = Measure("ds", domain=mesh, subdomain_data=mf, subdomain_id=1) ds_wall = Measure("ds", domain=mesh, subdomain_data=mf, subdomain_id=2) """Initial values (t == 0.0)"""
if 4 * i >= local_range[0] and 4 * i + 3 < local_range[1]: local_p[4 * i - local_range[0]] = math.pow(10, row[0]) local_p[4 * i + 1 - local_range[0]] = 0. local_p[4 * i + 2 - local_range[0]] = 0. local_p[4 * i + 3 - local_range[0]] = math.pow(10, row[0]) p.vector().set_local(local_p) p.vector().apply("insert") mesh = Mesh("data/biot_2mat.xml") subdomains = MeshFunction("size_t", mesh, "data/biot_2mat_physical_region.xml") boundaries = MeshFunction("size_t", mesh, "data/biot_2mat_facet_region.xml") for discretization in ("DG", "EG"): # Block function space V_element = VectorElement("CG", mesh.ufl_cell(), 2) if discretization == "DG": Q_element = FiniteElement("DG", mesh.ufl_cell(), 1) W_element = BlockElement(V_element, Q_element) elif discretization == "EG": Q_element = FiniteElement("CG", mesh.ufl_cell(), 1) D_element = FiniteElement("DG", mesh.ufl_cell(), 0) EG_element = Q_element + D_element W_element = BlockElement(V_element, EG_element) else: raise RuntimeError("Invalid discretization") W = BlockFunctionSpace(mesh, W_element) PM = FunctionSpace(mesh, "DG", 0) TM = TensorFunctionSpace(mesh, "DG", 0)
def save_files_visualization(visualization_folder, dvp_, t, save_deg, mesh, **namespace): # Files for storing results if not "d_file" in namespace.keys(): d_file = XDMFFile( MPI.comm_world, str(visualization_folder.joinpath("displacement.xdmf"))) v_file = XDMFFile(MPI.comm_world, str(visualization_folder.joinpath("velocity.xdmf"))) p_file = XDMFFile(MPI.comm_world, str(visualization_folder.joinpath("pressure.xdmf"))) for tmp_t in [d_file, v_file, p_file]: tmp_t.parameters["flush_output"] = True tmp_t.parameters["rewrite_function_mesh"] = False if save_deg > 1: # Import fenicstools import warnings try: with warnings.catch_warnings(record=True) as w: from fenicstools import interpolate_nonmatching_mesh_any except ModuleNotFoundError: raise ModuleNotFoundError("For save_deg > 1 to work please install fenics tools with:\n" + \ "pip install git+https://github.com/mikaem/fenicstools") # Copy mesh mesh_viz = Mesh(mesh) for i in range(save_deg - 1): mesh_viz = refine(mesh_viz) # refine the mesh dve_viz = VectorElement('CG', mesh_viz.ufl_cell(), 1) pe_viz = FiniteElement('CG', mesh_viz.ufl_cell(), 1) FSdv_viz = FunctionSpace( mesh_viz, dve_viz) # Visualisation FunctionSpace for d and v FSp_viz = FunctionSpace( mesh_viz, pe_viz) # Visualisation FunctionSpace for p return_dict = dict( v_file=v_file, d_file=d_file, p_file=p_file, FSdv_viz=FSdv_viz, FSp_viz=FSp_viz, save_deg_interpolator=interpolate_nonmatching_mesh_any) else: return_dict = dict(v_file=v_file, d_file=d_file, p_file=p_file) namespace.update(return_dict) else: return_dict = {} # Split function d = dvp_["n"].sub(0, deepcopy=True) v = dvp_["n"].sub(1, deepcopy=True) p = dvp_["n"].sub(2, deepcopy=True) # New functions mimicing higher-order visualization fies if save_deg > 1: d = namespace["save_deg_interpolator"](d, namespace["FSdv_viz"]) v = namespace["save_deg_interpolator"](v, namespace["FSdv_viz"]) p = namespace["save_deg_interpolator"](p, namespace["FSp_viz"]) # Name function d.rename("Displacement", "d") v.rename("Velocity", "v") p.rename("Pressure", "p") # Write results namespace["d_file"].write(d, t) namespace["v_file"].write(v, t) namespace["p_file"].write(p, t) return return_dict
class CavityProblemSetup(): def __init__(self, parameters, mesh_name, facet_name): """ Create the required function spaces, functions and boundary conditions for a channel flow problem """ self.mesh = Mesh() with XDMFFile(mesh_name) as infile: infile.read(self.mesh) mvc = MeshValueCollection("size_t", self.mesh, self.mesh.topology().dim() - 1) with XDMFFile(facet_name) as infile: infile.read(mvc, "name_to_read") mf = self.mf = cpp.mesh.MeshFunctionSizet(self.mesh, mvc) self.bc_dict = {"bottom": 1, "right": 2, "top": 3, "left": 4} T_init = Constant(parameters["initial temperature [°C]"]) self.t_amb = Constant(parameters["ambient temperature [°C]"]) self.t_feeder = Constant(parameters["temperature feeder [°C]"]) self.k_top = Constant(parameters["thermal conductivity top [W/(m K)]"]) self.k_lft = Constant( parameters["thermal conductivity left [W/(m K)]"]) self.k_btm = Constant( parameters["thermal conductivity bottom [W/(m K)]"]) self.k_rgt = Constant( parameters["thermal conductivity right [W/(m K)]"]) self.U_m = Constant(parameters["mean velocity lid [m/s]"]) g = parameters["gravity [m/s²]"] self.g = Constant((0.0, -g)) self.dt = Constant(parameters["dt [s]"]) self.D = Constant(parameters["Diffusivity [-]"]) self.V = V = VectorFunctionSpace(self.mesh, 'P', 2) self.Q = Q = FunctionSpace(self.mesh, 'P', 1) self.T = T = FunctionSpace(self.mesh, 'P', 1) self.ds_ = Measure("ds", domain=self.mesh, subdomain_data=mf) self.vu, self.vp, self.vt = (TestFunction(V), TestFunction(Q), TestFunction(T)) self.u_, self.p_, self.t_ = Function(V), Function(Q), Function(T) self.mu, self.rho = Function(T), Function(T) self.u_1, self.p_1, self.t_1, self.rho_1 = (Function(V), Function(Q), Function(T), Function(T)) self.u, self.p, self.t = (TrialFunction(V), TrialFunction(Q), TrialFunction(T)) # boundary conditions self.no_slip = Constant((0., 0)) self.topflow = Expression(("-x[0] * (x[0] - 1.0) * 6.0 * m", "0.0"), m=self.U_m, degree=2) bc0 = DirichletBC(V, self.topflow, mf, self.bc_dict["top"]) bc1 = DirichletBC(V, self.no_slip, mf, self.bc_dict["left"]) bc2 = DirichletBC(V, self.no_slip, mf, self.bc_dict["bottom"]) bc3 = DirichletBC(V, self.no_slip, mf, self.bc_dict["right"]) # bc4 = df.DirichletBC(Q, df.Constant(0), top) # bc3 = df.DirichletBC(T, df.Constant(800), top) self.bcu = [bc0, bc1, bc2, bc3] self.bcp = [DirichletBC(Q, Constant(0), mf, self.bc_dict["top"])] self.bcp = [] self.bct = [] # self.bct = [DirichletBC(T, Constant(self.t_feeder), mf, # self.bc_dict["top"])] self.robin_boundary_terms = ( self.k_btm * (self.t - self.t_amb) * self.vt * self.ds_(1) + self.k_rgt * (self.t - self.t_amb) * self.vt * self.ds_(2) # + self.k_top*(self.t - self.t_feeder)*self.vt*self.ds_(3) + self.k_lft * (self.t - self.t_amb) * self.vt * self.ds_(4)) print("k, T", self.k_btm.values(), self.t_feeder.values()) print("k, T", self.k_rgt.values(), self.t_amb.values()) # print("k, T", self.k_top.values(), self.t_amb.values()) print("k, T", self.k_lft.values(), self.t_amb.values()) # set initial values # TODO: find a better solution x, y = T.tabulate_dof_coordinates().T self.u_1.vector().vec().array[:] = 1e-6 # self.u_k.vector().vec().array[:] = 1e-6 self.p_.vector().vec( ).array[:] = -self.rho.vector().vec().array * g * y self.p_1.vector().vec( ).array[:] = -self.rho.vector().vec().array * g * y self.t_1.vector().vec().array = T_init self.t_.assign(self.t_1) return def stokes(self): P2 = VectorElement("CG", self.mesh.ufl_cell(), 2) P1 = FiniteElement("CG", self.mesh.ufl_cell(), 1) TH = P2 * P1 VQ = FunctionSpace(self.mesh, TH) mf = self.mf self.no_slip = Constant((0., 0)) self.topflow = Expression(("-x[0] * (x[0] - 1.0) * 6.0 * m", "0.0"), m=self.U_m, degree=2) bc0 = DirichletBC(VQ.sub(0), self.topflow, mf, self.bc_dict["top"]) bc1 = DirichletBC(VQ.sub(0), self.no_slip, mf, self.bc_dict["left"]) bc2 = DirichletBC(VQ.sub(0), self.no_slip, mf, self.bc_dict["bottom"]) bc3 = DirichletBC(VQ.sub(0), self.no_slip, mf, self.bc_dict["right"]) # bc4 = DirichletBC(VQ.sub(1), Constant(0), mf, self.bc_dict["top"]) bcs = [bc0, bc1, bc2, bc3] vup = TestFunction(VQ) up = TrialFunction(VQ) # the solution will be in here: up_ = Function(VQ) u, p = split(up) # Trial vu, vp = split(vup) # Test u_, p_ = split(up_) # Function holding the solution F = self.mu*inner(grad(vu), grad(u))*dx - inner(div(vu), p)*dx \ - inner(vp, div(u))*dx + dot(self.g*self.rho, vu)*dx solve(lhs(F) == rhs(F), up_, bcs=bcs) self.u_.assign(project(u_, self.V)) self.p_.assign(project(p_, self.Q)) return def initial_condition_from_file(self, path_u, path_p): f_in = XDMFFile(path_u) f_in.read_checkpoint(self.u_, "f", 0) f_in = XDMFFile(path_p) f_in.read_checkpoint(self.p_, "f", 0) return def get_rho(self): return self.rho.vector().vec().array def set_rho(self, rho): self.rho.vector().vec().array[:] = rho def get_mu(self): return self.mu.vector().vec().array def set_mu(self, mu): self.mu.vector().vec().array[:] = mu def get_t(self): return self.t_.vector().vec().array def set_t(self, t): self.t_.vector().vec().array[:] = t def get_dt(self): return self.dt.values() def set_dt(self, dt): self.dt.assign(dt) def get_D(self): return self.D.values() def set_D(self, D): self.D.assign(D) def get_t_amb(self): return self.t_amb.values() def set_t_amb(self, t_amb): self.t_amb.assign(t_amb) def plot(self): cmap = mpl.cm.inferno cmap_r = mpl.cm.inferno_r u, p, t, m, r = self.u_, self.p_, self.t_, self.mu, self.rho mesh = self.mesh w0 = u.compute_vertex_values(mesh) w0.shape = (2, -1) magnitude = np.linalg.norm(w0, axis=0) x, y = np.split(mesh.coordinates(), 2, 1) u, v = np.split(w0, 2, 0) x, y, u, v = x.ravel(), y.ravel(), u.ravel(), v.ravel() tri = mesh.cells() pressure = p.compute_vertex_values(mesh) temperature = t.compute_vertex_values(mesh) viscosity = m.compute_vertex_values(mesh) density = r.compute_vertex_values(mesh) fig = plt.figure(figsize=(12, 8)) ax1 = plt.subplot(121) ax2 = plt.subplot(243, sharex=ax1, sharey=ax1) ax3 = plt.subplot(244, sharex=ax1, sharey=ax1) ax4 = plt.subplot(247, sharex=ax1, sharey=ax1) ax5 = plt.subplot(248, sharex=ax1, sharey=ax1) ax1.plot(x, y, "k.", ms=.5) not0 = magnitude > 1e-6 if np.sum(not0) > 0: ax1.quiver(x[not0], y[not0], u[not0], v[not0], magnitude[not0]) c2 = ax2.tricontourf(x, y, tri, pressure, levels=40, cmap=cmap) c3 = ax3.tricontourf(x, y, tri, temperature, levels=40, cmap=cmap) c4 = ax4.tricontourf( x, y, tri, viscosity, levels=40, # vmin=self.mu(800, .1), vmax=self.mu(600, .1), cmap=cmap_r) c5 = ax5.tricontourf( x, y, tri, density, levels=40, # vmin=self.rho(800.), vmax=self.rho(600.), cmap=cmap_r) plt.colorbar(c2, ax=ax2) plt.colorbar(c3, ax=ax3, ticks=[temperature.min(), temperature.max()]) plt.colorbar(c4, ax=ax4, ticks=[viscosity.min(), viscosity.max()]) plt.colorbar(c5, ax=ax5, ticks=[density.min(), density.max()]) ax1.set_aspect("equal") ax2.set_aspect("equal") ax3.set_aspect("equal") ax4.set_aspect("equal") ax5.set_aspect("equal") ax1.set_title("velocity\n{:.4f} ... {:.5f} m/s".format( magnitude.min(), magnitude.max())) ax2.set_title("pressure") ax3.set_title("temperature") ax4.set_title("viscosity") ax5.set_title("density") ax1.set_xlim([-.1, 1.1]) ax1.set_ylim([-.1, 1.1]) # plt.tight_layout() return fig, (ax1, ax2)