def bottom_wall_shear_integrand(self): nhat = fenics.FacetNormal(self.mesh) p, u, T, C = fenics.split(self.solution) bottom_wall_id = 2 mesh_function = fenics.MeshFunction("size_t", self.mesh, self.mesh.topology().dim() - 1) self.bottom_wall.mark(mesh_function, bottom_wall_id) dot, grad = fenics.dot, fenics.grad ds = fenics.ds(domain=self.mesh, subdomain_data=mesh_function, subdomain_id=bottom_wall_id) return dot(grad(u[0]), nhat) * ds
def solve_wave_equation(u0, u1, u_boundary, f, domain, mesh, degree): """Solving the wave equation using CG-CG method. Args: u0: Initial data. u1: Initial velocity. u_boundary: Dirichlet boundary condition. f: Right-hand side. domain: Space-time domain. mesh: Computational mesh. degree: CG(degree) will be used as the finite element. Outputs: uh: Numerical solution. """ # Element V = FunctionSpace(mesh, "CG", degree) # Measures on the initial and terminal slice mask = MeshFunction("size_t", mesh, mesh.topology().dim() - 1, 0) domain.get_initial_slice().mark(mask, 1) ends = ds(subdomain_data=mask) # Form g = Constant(((-1.0, 0.0), (0.0, 1.0))) u = TrialFunction(V) v = TestFunction(V) a = dot(grad(v), dot(g, grad(u))) * dx L = f * v * dx + u1 * v * ends(1) # Assembled matrices A = assemble(a, keep_diagonal=True) b = assemble(L, keep_diagonal=True) # Spatial boundary condition bc = DirichletBC(V, u_boundary, domain.get_spatial_boundary()) bc.apply(A, b) # Temporal boundary conditions (by hand) (A, b) = apply_time_boundary_conditions(domain, V, u0, A, b) # Solve solver = LUSolver() solver.set_operator(A) uh = Function(V) solver.solve(uh.vector(), b) return uh
def runModel(self): ########################################################## ################ FILES ################# ########################################################## #FIXME Probably dont have to save then open mesh self.mesh = Mesh() self.in_file = HDF5File(self.mesh.mpi_comm(), self.hdf_name, "r") #mesh.mpi_comm() is ussed to read in parallel? # out_file = HDF5File(mesh.mpi_comm(),"./output_data/peterman.h5","w") # cell_indices: self-explanatory # coordinates: self-explanatory # topology: Shows which nodes are linked together ########################################################## ################ GUI ################# ########################################################## ########################################################## ################ MESH ################# ########################################################## self.in_file.read(self.mesh,"/mesh", False) # H5FILE Data: # bed and surface are datasets shape (378,) # mesh is a group with datasets # cell_indices Shape (377,) Type i8 Array [0 1 2 ... n-1 n] incremented by 1 # coordinates Shape (378,1) Type f8 Array [[0.] [1000.] ... [ 377000.]] incremented by 1,000 # topology Shape (377,2) Type i8 Array [[0 1] [1 2] ... [n-1 n]] incremented by 1, shows which points are attched to each other ######################################################### ################# FUNCTION SPACES ##################### ######################################################### self.E_Q = FiniteElement("CG",self.mesh.ufl_cell(),1) self.Q = FunctionSpace(self.mesh, self.E_Q) # E_Q defined over the mesh self.E_V = MixedElement(self.E_Q, self.E_Q, self.E_Q) self.V = FunctionSpace(self.mesh ,self.E_V) # For moving data between vector functions and scalar functions self.assigner_inv = FunctionAssigner([self.Q,self.Q,self.Q],self.V) self.assigner = FunctionAssigner(self.V, [self.Q, self.Q, self.Q]) # For solution self.U = Function(self.V) self.dU = TrialFunction(self.V) self.Phi = TestFunction(self.V) self.u, self.u2, self.H = split(self.U) # H will be the thickness at current time self.phi, self.phi1, self.xsi = split(self.Phi) # Individual test functions needed for forms # Placeholders needed for assignment self.un = Function(self.Q) self.u2n = Function(self.Q) # Zeros, an initial guess for velocity for when solver fails self.zero_sol = Function(self.Q) #zero_sol.assign(Constant(0)) ######################################################### ############# FIELD INITIALIZATION ############### ######################################################### self.S0 = Function(self.Q) # Initial surface elevation self.B = Function(self.Q) # Bed elevation self.H0 = Function(self.Q) # Thickness at previous time step self.A = Function(self.Q) # SMB data # in_file.read(H0.vector(), "/thickness", True) #NEW self.in_file.read(self.S0.vector(), "/surface", True) self.in_file.read(self.B.vector(), "/bed", True) self.in_file.read(self.A.vector(), "/smb", True) self.H0.assign(self.S0-self.B) # Initial thickness #OLD # A generalization of the Crank-Nicolson method, which is theta = .5 self.Hmid = theta*self.H + (1-theta)*self.H0 # Define surface elevation self.S = self.B + self.Hmid #OLD # S = Max(Hmid+B, rho/rho_w * Hmid) # Expressions for now, later move to data from files # adot = interpolate(Adot(degree=1),Q) # dolfin.fem.interpolation.interpolate: adot is an expression, Q is a functionspace # returns an interpolation of a given function into a given finite element space # i think this is a vector # print 'adot: ', adot.vector()[:][0] # Q is a functionspace # print 'adot: ', adot #printed 'f_51 self.width = interpolate(Width(degree=2), self.Q) ############################################################################# ####################### MOMENTUM CONSERVATION ############################# ############################################################################# # This object stores the stresses self.strs = Stresses(self.U, self.Hmid, self.H0, self.H, self.width, self.B, self.S, self.Phi) # Conservation of momentum form: self.R = -(self.strs.tau_xx + self.strs.tau_xz + self.strs.tau_b + self.strs.tau_d + self.strs.tau_xy)*dx ############################################################################# ######################## MASS CONSERVATION ################################ ############################################################################# self.h = CellSize(self.mesh) self.D = self.h*abs(self.U[0])/2. self.area = self.Hmid*self.width self.mesh_min = self.mesh.coordinates().min() self.mesh_max = self.mesh.coordinates().max() # Define boundaries self.ocean = FacetFunctionSizet(self.mesh,0) self.ds = fc.ds(subdomain_data=self.ocean) #THIS DS IS FROM FENICS! border integral for f in facets(self.mesh): if near(f.midpoint().x(),self.mesh_max): self.ocean[f] = 1 if near(f.midpoint().x(),self.mesh_min): self.ocean[f] = 2 # Directly write the form, with SPUG and area correction, self.R += ((self.H-self.H0)/dt*self.xsi - self.xsi.dx(0)*self.U[0]*self.Hmid + self.D*self.xsi.dx(0)*self.Hmid.dx(0) - (self.A - self.U[0]*self.H/self.width*self.width.dx(0))*self.xsi)*dx\ + self.U[0]*self.area*self.xsi*self.ds(1) - self.U[0]*self.area*self.xsi*self.ds(0) ##################################################################### ######################### SOLVER SETUP ########################### ##################################################################### # Bounds self.l_thick_bound = project(Constant(thklim),self.Q) self.u_thick_bound = project(Constant(1e4),self.Q) self.l_v_bound = project(-10000.0,self.Q) self.u_v_bound = project(10000.0,self.Q) self.l_bound = Function(self.V) self.u_bound = Function(self.V) self.assigner.assign(self.l_bound,[self.l_v_bound]*2+[self.l_thick_bound]) self.assigner.assign(self.u_bound,[self.u_v_bound]*2+[self.u_thick_bound]) # This should set the velocity at the divide (left) to zero self.dbc0 = DirichletBC(self.V.sub(0),0,lambda x,o:near(x[0],self.mesh_min) and o) # Set the velocity on the right terminus to zero self.dbc1 = DirichletBC(self.V.sub(0),0,lambda x,o:near(x[0],self.mesh_max) and o) # overkill? self.dbc2 = DirichletBC(self.V.sub(1),0,lambda x,o:near(x[0],self.mesh_max) and o) # set the thickness on the right edge to thklim self.dbc3 = DirichletBC(self.V.sub(2),thklim,lambda x,o:near(x[0],self.mesh_max) and o) #Define variational solver for the mass-momentum coupled problem self.J = derivative(self.R,self.U,self.dU) self.coupled_problem = NonlinearVariationalProblem(self.R,self.U,bcs=[self.dbc0,self.dbc1,self.dbc3],J=self.J) self.coupled_problem.set_bounds(self.l_bound, self.u_bound) self.coupled_solver = NonlinearVariationalSolver(self.coupled_problem) # Accquire the optimizations in fenics_optimizations set_solver_options(self.coupled_solver) ###################################################################### ####################### TIME LOOP ################################ ###################################################################### # Time interval self.t = 0 # t_end = 20000. self.t_end = float(self.tEndLineEdit.text()) self.dt_float = float(self.tStepLineEdit.text()) self.pPlt = pyqtplotter(self.strs, self.mesh, self.plt1, self.plt2, self.plt3, self.t, self.dt_float, str(self.saveFileLineEdit.text())) self.pPlt.refresh_plot(0) pg.QtGui.QApplication.processEvents() self.in_file.close() self.runLoop()
def __init__(self, fileName, timeEnd, timeStep, average=False): fc.set_log_active(False) self.times = [] self.BB = [] self.HH = [] self.TD = [] self.TB = [] self.TX = [] self.TY = [] self.TZ = [] self.us = [] self.ub = [] ########################################################## ################ MESH ################# ########################################################## # TODO: Probably do not have to save then open mesh self.mesh = df.Mesh() self.inFile = fc.HDF5File(self.mesh.mpi_comm(), fileName, "r") self.inFile.read(self.mesh, "/mesh", False) ######################################################### ################# FUNCTION SPACES ##################### ######################################################### self.E_Q = df.FiniteElement("CG", self.mesh.ufl_cell(), 1) self.Q = df.FunctionSpace(self.mesh, self.E_Q) self.E_V = df.MixedElement(self.E_Q, self.E_Q, self.E_Q) self.V = df.FunctionSpace(self.mesh, self.E_V) self.assigner_inv = fc.FunctionAssigner([self.Q, self.Q, self.Q], self.V) self.assigner = fc.FunctionAssigner(self.V, [self.Q, self.Q, self.Q]) self.U = df.Function(self.V) self.dU = df.TrialFunction(self.V) self.Phi = df.TestFunction(self.V) self.u, self.u2, self.H = df.split(self.U) self.phi, self.phi1, self.xsi = df.split(self.Phi) self.un = df.Function(self.Q) self.u2n = df.Function(self.Q) self.zero_sol = df.Function(self.Q) self.Bhat = df.Function(self.Q) self.H0 = df.Function(self.Q) self.A = df.Function(self.Q) if average: self.inFile.read(self.Bhat.vector(), "/bedAvg", True) self.inFile.read(self.A.vector(), "/smbAvg", True) self.inFile.read(self.H0.vector(), "/thicknessAvg", True) else: self.inFile.read(self.Bhat.vector(), "/bed", True) self.inFile.read(self.A.vector(), "/smb", True) self.inFile.read(self.H0.vector(), "/thickness", True) self.Hmid = theta * self.H + (1 - theta) * self.H0 self.B = softplus(self.Bhat, -rho / rho_w * self.Hmid, alpha=0.2) # Is not the bed, it is the lower surface self.S = self.B + self.Hmid self.width = df.interpolate(Width(degree=2), self.Q) self.strs = Stresses(self.U, self.Hmid, self.H0, self.H, self.width, self.B, self.S, self.Phi) self.R = -(self.strs.tau_xx + self.strs.tau_xz + self.strs.tau_b + self.strs.tau_d + self.strs.tau_xy) * df.dx ############################################################################# ######################## MASS CONSERVATION ################################ ############################################################################# self.h = df.CellSize(self.mesh) self.D = self.h * abs(self.U[0]) / 2. self.area = self.Hmid * self.width self.mesh_min = self.mesh.coordinates().min() self.mesh_max = self.mesh.coordinates().max() # Define boundaries self.ocean = df.FacetFunctionSizet(self.mesh, 0) self.ds = fc.ds(subdomain_data=self.ocean) # THIS DS IS FROM FENICS! border integral for f in df.facets(self.mesh): if df.near(f.midpoint().x(), self.mesh_max): self.ocean[f] = 1 if df.near(f.midpoint().x(), self.mesh_min): self.ocean[f] = 2 self.R += ((self.H - self.H0) / dt * self.xsi \ - self.xsi.dx(0) * self.U[0] * self.Hmid \ + self.D * self.xsi.dx(0) * self.Hmid.dx(0) \ - (self.A - self.U[0] * self.H / self.width * self.width.dx(0)) \ * self.xsi) * df.dx + self.U[0] * self.area * self.xsi * self.ds(1) \ - self.U[0] * self.area * self.xsi * self.ds(0) ##################################################################### ######################### SOLVER SETUP ########################### ##################################################################### # Bounds self.l_thick_bound = df.project(Constant(thklim), self.Q) self.u_thick_bound = df.project(Constant(1e4), self.Q) self.l_v_bound = df.project(-10000.0, self.Q) self.u_v_bound = df.project(10000.0, self.Q) self.l_bound = df.Function(self.V) self.u_bound = df.Function(self.V) self.assigner.assign(self.l_bound, [self.l_v_bound] * 2 + [self.l_thick_bound]) self.assigner.assign(self.u_bound, [self.u_v_bound] * 2 + [self.u_thick_bound]) # This should set the velocity at the divide (left) to zero self.dbc0 = df.DirichletBC(self.V.sub(0), 0, lambda x, o: df.near(x[0], self.mesh_min) and o) # Set the velocity on the right terminus to zero self.dbc1 = df.DirichletBC(self.V.sub(0), 0, lambda x, o: df.near(x[0], self.mesh_max) and o) # overkill? self.dbc2 = df.DirichletBC(self.V.sub(1), 0, lambda x, o: df.near(x[0], self.mesh_max) and o) # set the thickness on the right edge to thklim self.dbc3 = df.DirichletBC(self.V.sub(2), thklim, lambda x, o: df.near(x[0], self.mesh_max) and o) # Define variational solver for the mass-momentum coupled problem self.J = df.derivative(self.R, self.U, self.dU) self.coupled_problem = df.NonlinearVariationalProblem(self.R, self.U, bcs=[self.dbc0, self.dbc1, self.dbc3], \ J=self.J) self.coupled_problem.set_bounds(self.l_bound, self.u_bound) self.coupled_solver = df.NonlinearVariationalSolver(self.coupled_problem) # Acquire the optimizations in fenics_optimizations set_solver_options(self.coupled_solver) self.t = 0 self.timeEnd = float(timeEnd) self.dtFloat = float(timeStep) self.inFile.close()
bcU = fn.DirichletBC(Hh.sub(0), u_g, bdry, 31) bcP = fn.DirichletBC(Hh.sub(2), p_g, bdry, 32) bcs = [bcU, bcP] # weak forms PLeft = 2*mu*fn.inner(strain(u), strain(v)) * fn.dx \ - fn.div(v) * phi * fn.dx \ + (c_0/alpha + 1.0/lmbda) * p * q * fn.dx \ + kappa/(alpha*nu) * fn.dot(fn.grad(p), fn.grad(q)) * fn.dx \ - 1.0/lmbda * phi * q * fn.dx \ - fn.div(u) * psi * fn.dx \ + 1.0/lmbda * psi * p * fn.dx \ - 1.0/lmbda * phi * psi * fn.dx PRight = fn.dot(f, v) * fn.dx + fn.dot(h_g, v)*fn.ds(32) Sol = fn.Function(Hh) # solve! fn.solve(PLeft == PRight, Sol, bcs) u, phi, p = Sol.split() # save u.rename("u", "u") fileU << u p.rename("p", "p") fileP << p
def runModel(hdf_name): ########################################################## ################ FILES ################# ########################################################## mesh = Mesh() in_file = HDF5File(mesh.mpi_comm(), hdf_name, "r") #mesh.mpi_comm() is ussed to read in parallel? # outF = h5py.File('./data/modelOut') # out_file = HDF5File(mesh.mpi_comm(),"./output_data/peterman.h5","w") # cell_indices: self-explanatory # coordinates: self-explanatory # topology: Shows which nodes are linked together ########################################################## ################ GUI ################# ########################################################## ########################################################## ################ MESH ################# ########################################################## in_file.read(mesh, "/mesh", False) # H5FILE Data: # bed and surface are datasets shape (378,) # mesh is a group with datasets # cell_indices Shape (377,) Type i8 Array [0 1 2 ... n-1 n] incremented by 1 # coordinates Shape (378,1) Type f8 Array [[0.] [1000.] ... [ 377000.]] incremented by 1,000 # topology Shape (377,2) Type i8 Array [[0 1] [1 2] ... [n-1 n]] incremented by 1, shows which points are attched to each other ######################################################### ################# FUNCTION SPACES ##################### ######################################################### E_Q = FiniteElement("CG", mesh.ufl_cell(), 1) Q = FunctionSpace(mesh, E_Q) # E_Q defined over the mesh E_V = MixedElement(E_Q, E_Q, E_Q) V = FunctionSpace(mesh, E_V) # For moving data between vector functions and scalar functions assigner_inv = FunctionAssigner([Q, Q, Q], V) assigner = FunctionAssigner(V, [Q, Q, Q]) # For solution U = Function(V) dU = TrialFunction(V) Phi = TestFunction(V) u, u2, H = split(U) # H will be the thickness at current time phi, phi1, xsi = split(Phi) # Individual test functions needed for forms # Placeholders needed for assignment un = Function(Q) u2n = Function(Q) # Zeros, an initial guess for velocity for when solver fails zero_sol = Function(Q) #zero_sol.assign(Constant(0)) ######################################################### ############# FIELD INITIALIZATION ############### ######################################################### S0 = Function(Q) # Initial surface elevation B = Function(Q) # Bed elevation H0 = Function(Q) # Thickness at previous time step A = Function(Q) # SMB data # in_file.read(H0.vector(), "/thickness", True) #NEW in_file.read(S0.vector(), "/surface", True) in_file.read(B.vector(), "/bed", True) in_file.read(A.vector(), "/smb", True) H0.assign(S0 - B) # Initial thickness #OLD # A generalization of the Crank-Nicolson method, which is theta = .5 Hmid = theta * H + (1 - theta) * H0 # Define surface elevation S = B + Hmid #OLD # S = Max(Hmid+B, rho/rho_w * Hmid) # Expressions for now, later move to data from files # adot = interpolate(Adot(degree=1),Q) # dolfin.fem.interpolation.interpolate: adot is an expression, Q is a functionspace # returns an interpolation of a given function into a given finite element space # i think this is a vector # print 'adot: ', adot.vector()[:][0] # Q is a functionspace # print 'adot: ', adot #printed 'f_51 width = interpolate(Width(degree=2), Q) ############################################################################# ####################### MOMENTUM CONSERVATION ############################# ############################################################################# # This object stores the stresses strs = Stresses(U, Hmid, H0, H, width, B, S, Phi) # Conservation of momentum form: R = -(strs.tau_xx + strs.tau_xz + strs.tau_b + strs.tau_d + strs.tau_xy) * dx ############################################################################# ######################## MASS CONSERVATION ################################ ############################################################################# h = CellSize(mesh) D = h * abs(U[0]) / 2. area = Hmid * width mesh_min = mesh.coordinates().min() mesh_max = mesh.coordinates().max() # Define boundaries ocean = FacetFunctionSizet(mesh, 0) ds = fc.ds(subdomain_data=ocean) #THIS DS IS FROM FENICS! border integral for f in facets(mesh): if near(f.midpoint().x(), mesh_max): ocean[f] = 1 if near(f.midpoint().x(), mesh_min): ocean[f] = 2 # Directly write the form, with SPUG and area correction, R += ((H-H0)/dt*xsi - xsi.dx(0)*U[0]*Hmid + D*xsi.dx(0)*Hmid.dx(0) - (A - U[0]*H/width*width.dx(0))*xsi)*dx\ + U[0]*area*xsi*ds(1) - U[0]*area*xsi*ds(0) ##################################################################### ######################### SOLVER SETUP ########################### ##################################################################### # Bounds l_thick_bound = project(Constant(thklim), Q) u_thick_bound = project(Constant(1e4), Q) l_v_bound = project(-10000.0, Q) u_v_bound = project(10000.0, Q) l_bound = Function(V) u_bound = Function(V) assigner.assign(l_bound, [l_v_bound] * 2 + [l_thick_bound]) assigner.assign(u_bound, [u_v_bound] * 2 + [u_thick_bound]) # This should set the velocity at the divide (left) to zero dbc0 = DirichletBC(V.sub(0), 0, lambda x, o: near(x[0], mesh_min) and o) # Set the velocity on the right terminus to zero dbc1 = DirichletBC(V.sub(0), 0, lambda x, o: near(x[0], mesh_max) and o) # overkill? dbc2 = DirichletBC(V.sub(1), 0, lambda x, o: near(x[0], mesh_max) and o) # set the thickness on the right edge to thklim dbc3 = DirichletBC(V.sub(2), thklim, lambda x, o: near(x[0], mesh_max) and o) #Define variational solver for the mass-momentum coupled problem J = derivative(R, U, dU) coupled_problem = NonlinearVariationalProblem(R, U, bcs=[dbc0, dbc1, dbc3], J=J) coupled_problem.set_bounds(l_bound, u_bound) coupled_solver = NonlinearVariationalSolver(coupled_problem) # Accquire the optimizations in fenics_optimizations set_solver_options(coupled_solver) ###################################################################### ####################### TIME LOOP ################################ ###################################################################### # Time interval t = 0 # t_end = 20000. t_end = float(t_end_lineEdit.text()) dt_float = float(t_step_lineEdit.text()) # PyQt gui items mw2 = QtGui.QMainWindow(mw) mw2.setWindowTitle('PyQt PLOTTER') # MAIN WINDOW cw2 = QtGui.QWidget( ) # GENERIC WIDGET AS CENTRAL WIDGET (inside main window) mw2.setCentralWidget(cw2) l = QtGui.QVBoxLayout( ) # CENTRAL WIDGET LAYOUT (layout of the central widget) cw2.setLayout(l) plt1 = pg.PlotWidget() plt2 = pg.PlotWidget() plt3 = pg.PlotWidget() l.addWidget(plt1) l.addWidget(plt2) l.addWidget(plt3) mw2.show() pPlt = pyqtplotter(strs, mesh, plt1, plt2, plt3, t, dt_float) pPlt.refresh_plot(0) mw2.closeEvent = pPlt.closed pg.QtGui.QApplication.processEvents() print 'mw2..isActive', mw2.isActiveWindow() mw2.activateWindow() print 'mw2..isActive', mw2.isActiveWindow() while t < t_end and pPlt.run: # time0 = time.time() print("Solving for time: ", t) t_current.setText("Current year: " + str(t)) coupled_problem = NonlinearVariationalProblem(R, U, bcs=[dbc0, dbc1, dbc3], J=J) coupled_problem.set_bounds(l_bound, u_bound) coupled_solver = NonlinearVariationalSolver(coupled_problem) # Accquire the optimizations in fenics_optimizations set_solver_options(coupled_solver) try: coupled_solver.solve(set_solver_options()) except: print("Exception Triggered!") coupled_solver.parameters['snes_solver'][ 'error_on_nonconvergence'] = False assigner.assign(U, [zero_sol, zero_sol, H0]) coupled_solver.solve() coupled_solver.parameters['snes_solver'][ 'error_on_nonconvergence'] = True assigner_inv.assign([un, u2n, H0], U) t += dt_float pPlt.refresh_plot(t) pg.QtGui.QApplication.processEvents() in_file.close()
V = fnc.VectorFunctionSpace(mesh, "CG", 1) # Acá es distinto, definimos un tensor! Vsig = fnc.TensorFunctionSpace(mesh, "DG", 0) # Funciones Test y trial du = fnc.TrialFunction(V) w = fnc.TestFunction(V) # Desplazamiento actual Desconocido! u = fnc.Function(V, name="Desplazamiento") #Campos del paso anterior (Desplazamiento, velocidad, aceleración) u_old = fnc.Function(V) v_old = fnc.Function(V) a_old = fnc.Function(V) #Define la medida de la integral de borde (contorno) dss = fnc.ds(subdomain_data=bordes) fnc.dx = fnc.dx(metadata={'quadrature_degree': 3}) #Condición de borde del costado izquierdo zero = fnc.Constant((0.0, 0.0, 0.0)) bc = fnc.DirichletBC(V, zero, bordes, 1) #bc2 = fnc.DirichletBC(V, zero, bordes, 2) #bc3 = fnc.DirichletBC(V, zero, bordes, 10) #bc = [bc1, bc2] def eps(v): return fnc.sym(fnc.grad(v))