def solve_thermal(self): """ Solve the thermal diffusion problem. Both ice and solution. """ ### Solve heat equation alphalog_i = dolfin.project(dolfin.Expression('astar*exp(-2.*x[0])',degree=1,astar=self.astar_i),self.ice_V) # Set up the variational form for the current mesh location F_i = (self.u_i-self.u0_i)*self.v_i*dolfin.dx + self.dt*dolfin.inner(dolfin.grad(self.u_i), dolfin.grad(alphalog_i*self.v_i))*dolfin.dx a_i = dolfin.lhs(F_i) L_i = dolfin.rhs(F_i) # Solve ice temperature dolfin.solve(a_i==L_i,self.T_i,[self.bc_inf,self.bc_iWall]) # Update previous profile to current self.u0_i.assign(self.T_i) diff_ratio = (self.ks*const.rhoi*const.ci)/(const.ki*self.rhos*self.cs) alphalog_s = dolfin.project(dolfin.Expression('astar*exp(-2.*x[0])',degree=1,astar=self.astar_i),self.sol_V) # Set up the variational form for the current mesh location F_s = (self.u_s-self.u0_s)*self.v_s*dolfin.dx + self.dt*dolfin.inner(dolfin.grad(self.u_s), dolfin.grad(alphalog_s*diff_ratio*self.v_s))*dolfin.dx #- self.dt*(self.Q_sol*self.t0/abs(self.T_inf)/(const.rhoi*const.ci))*self.v_s*dolfin.dx #TODO: check this solution source term # TODO: Center heat flux #F_s -= (self.Q_center/(self.ks*diff_ratio*2.*np.pi*abs(self.T_inf)))*self.v_s*self.sds(2) a_s = dolfin.lhs(F_s) L_s = dolfin.rhs(F_s) # Solve solution temperature dolfin.solve(a_s==L_s,self.T_s,self.bc_sWall) # Update previous profile to current self.u0_s.assign(self.T_s)
def solve(self): print("solving mock problem at mu =", self.mu) assert not hasattr(self, "_is_solving") self._is_solving = True project(self.f, self.V, function=self._solution) delattr(self, "_is_solving") return self._solution
def get_demagfield(self, phi=None, use_default_function_space=True): """ Returns the projection of the negative gradient of phi onto a DG0 space defined on the same mesh Note: Do not trust the viper solver to plot the DeMag field, it can give some wierd results, paraview is recommended instead use_default_function_space - If true project into self.W, if false project into a Vector DG0 space over the mesh of phi. """ if phi is None: phi = self.phi Hdemag = -df.grad(phi) if use_default_function_space == True: Hdemag = df.project(Hdemag, self.W) else: if self.D == 1: Hspace = df.FunctionSpace(phi.function_space().mesh(), "DG", 0) else: Hspace = df.VectorFunctionSpace(phi.function_space().mesh(), "DG", 0) Hdemag = df.project(Hdemag, Hspace) return Hdemag
def compute_functionals(self, velocity, pressure, t): if self.args.wss: info('Computing stress tensor') I = Identity(velocity.geometric_dimension()) T = TensorFunctionSpace(self.mesh, 'Lagrange', 1) stress = project(-pressure*I + 2*sym(grad(velocity)), T) info('Generating boundary mesh') wall_mesh = BoundaryMesh(self.mesh, 'exterior') # wall_mesh = SubMesh(self.mesh, self.facet_function, 1) # QQ why does not work? # plot(wall_mesh, interactive=True) info(' Boundary mesh geometric dim: %d' % wall_mesh.geometry().dim()) info(' Boundary mesh topologic dim: %d' % wall_mesh.topology().dim()) info('Projecting stress to boundary mesh') Tb = TensorFunctionSpace(wall_mesh, 'Lagrange', 1) stress_b = interpolate(stress, Tb) self.fileDict['wss']['file'] << stress_b if False: # does not work info('Computing WSS') n = FacetNormal(wall_mesh) info(stress_b, True) # wss = stress_b*n - inner(stress_b*n, n)*n wss = dot(stress_b, n) - inner(dot(stress_b, n), n)*n # equivalent Vb = VectorFunctionSpace(wall_mesh, 'Lagrange', 1) Sb = FunctionSpace(wall_mesh, 'Lagrange', 1) # wss_func = project(wss, Vb) wss_norm = project(sqrt(inner(wss, wss)), Sb) plot(wss_norm, interactive=True)
def initControl(self): self.controlSpace = [FunctionSpace(self.mesh, "DG", 0)] x, y = SpatialCoordinate(self.mesh) u_ = (2*x-1.) \ * (exp(1 - abs(2*x-1.)) - 1) \ * (y + (1 - exp(y/self.delta))/(exp(1/self.delta)-1)) cs = self.controlSpace[0] du = self.u - u_ du_xx = Dx(Dx(du, 0), 0) du_xy = Dx(Dx(du, 0), 1) du_yx = Dx(Dx(du, 1), 0) du_yy = Dx(Dx(du, 1), 1) du_xx_proj = project(du_xx, cs) du_xy_proj = project(du_xy, cs) du_yx_proj = project(du_yx, cs) du_yy_proj = project(du_yy, cs) # Use the UserExpression gamma_star = Gallistl_Sueli_1_optControl(du_xx_proj, du_xy_proj, du_yx_proj, du_yy_proj, self.alphamin, self.alphamax) # Interpolate evaluates expression in centers of mass # Project evaluates expression in vertices self.gamma = [gamma_star]
def _test_reduced_mesh_elliptic_function(V, reduced_mesh): reduced_V = reduced_mesh.get_reduced_function_spaces() dofs = [d[0] for d in reduced_mesh.get_dofs_list()] # convert from 1-tuple to int reduced_dofs = [d[0] for d in reduced_mesh.get_reduced_dofs_list()] # convert from 1-tuple to int mesh_dim = V.mesh().geometry().dim() assert mesh_dim in (1, 2) if mesh_dim == 1: e = Expression("1+x[0]", element=V.ufl_element()) else: e = Expression("(1+x[0])*(1+x[1])", element=V.ufl_element()) f = project(e, V) f_N = project(e, reduced_V[0]) f_dofs = evaluate_sparse_function_at_dofs(f, dofs, V, dofs) f_reduced_dofs = evaluate_sparse_function_at_dofs(f, dofs, reduced_V[0], reduced_dofs) f_N_reduced_dofs = evaluate_sparse_function_at_dofs(f_N, reduced_dofs, reduced_V[0], reduced_dofs) test_logger.log(DEBUG, "f at dofs:") test_logger.log(DEBUG, str(nonzero_values(f_dofs))) test_logger.log(DEBUG, "f at reduced dofs:") test_logger.log(DEBUG, str(nonzero_values(f_reduced_dofs))) test_logger.log(DEBUG, "f_N at reduced dofs:") test_logger.log(DEBUG, str(nonzero_values(f_N_reduced_dofs))) test_logger.log(DEBUG, "Error:") test_logger.log(DEBUG, str(nonzero_values(f_dofs) - nonzero_values(f_reduced_dofs))) test_logger.log(DEBUG, "Error:") test_logger.log(DEBUG, str(f_reduced_dofs.vector().get_local() - f_N_reduced_dofs.vector().get_local())) assert isclose(nonzero_values(f_dofs), nonzero_values(f_reduced_dofs)).all() assert isclose(f_reduced_dofs.vector().get_local(), f_N_reduced_dofs.vector().get_local()).all()
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 get_field(self): """ compute field .. todo:: find better representation for real and imaginary part .. todo:: decide whether field should be of same order as solution """ self.logger.debug("Entering Field computation") if self.data['degree'] > 1: self.Vector = d.VectorFunctionSpace( self.mesh.mesh, self.data['properties']['project_element'], self.data['properties']['project_degree']) else: raise Exception( "Use for this computation a 2nd or higher order element") self.Efield_real = d.project(-d.grad(self.u.sub(0)), self.Vector, solver_type='mumps') self.Efield_imag = d.project(-d.grad(self.u.sub(1)), self.Vector, solver_type='mumps') self.Efield_real.rename('E-field real', 'E-field real') self.Efield_imag.rename('E-field imag', 'E-field imag') self.logger.debug("Computed E-Field")
def savePerturbationData(): log(LogLevel.INFO, 'Save perturbation data') with files['bifurcation'] as file: for n in range(len(pert)): mode = dolfin.project(stability.perturbations_beta[n], V_alpha) modename = 'beta-%d'%n mode.rename(modename, modename) log(LogLevel.INFO, 'Saved mode {}'.format(modename)) file.write(mode, load) with files['file_bif_postproc'] as file: leneigs = len(modes) maxmodes = min(3, leneigs) beta0v = dolfin.project(stability.perturbation_beta, V_alpha) log(LogLevel.DEBUG, 'DEBUG: irrev {}'.format(alpha.vector()-alpha_old.vector())) file.write_checkpoint(beta0v, 'beta0', 0, append = True) file.write_checkpoint(alpha_bif_old, 'alpha-old', 0, append=True) file.write_checkpoint(alpha_bif, 'alpha-bif', 0, append=True) file.write_checkpoint(alpha, 'alpha', 0, append=True) np.save(os.path.join(outdir, 'energy_perturbations'), en_perts, allow_pickle=True, fix_imports=True) with files['eigen'] as file: _v = dolfin.project(dolfin.Constant(h_opt)*perturbation_v, V_u) _beta = dolfin.project(dolfin.Constant(h_opt)*perturbation_beta, V_alpha) _v.rename('perturbation displacement', 'perturbation displacement') _beta.rename('perturbation damage', 'perturbation damage') file.write(_v, load) file.write(_beta, load) pass
def stokes(self): P2 = df.VectorElement("CG", self.mesh.ufl_cell(), 2) P1 = df.FiniteElement("CG", self.mesh.ufl_cell(), 1) TH = P2 * P1 VQ = df.FunctionSpace(self.mesh, TH) mf = self.mf self.no_slip = df.Constant((0., 0)) U0_str = "4.*U_m*x[1]*(.41-x[1])/(.41*.41)" U0 = df.Expression((U0_str, "0"), U_m=self.U_m, degree=2) bc0 = df.DirichletBC(VQ.sub(0), df.Constant((0, 0)), mf, self.bc_dict["obstacle"]) bc1 = df.DirichletBC(VQ.sub(0), df.Constant((0, 0)), mf, self.bc_dict["channel_walls"]) bc2 = df.DirichletBC(VQ.sub(0), U0, mf, self.bc_dict["inlet"]) bc3 = df.DirichletBC(VQ.sub(1), df.Constant(0), mf, self.bc_dict["outlet"]) bcs = [bc0, bc1, bc2, bc3] vup = df.TestFunction(VQ) up = df.TrialFunction(VQ) up_ = df.Function(VQ) u, p = df.split(up) # Trial vu, vp = df.split(vup) # Test u_, p_ = df.split(up_) # Function holding the solution inner, grad, dx, div = df.inner, df.grad, df.dx, df.div F = self.mu*inner(grad(vu), grad(u))*dx - inner(div(vu), p)*dx \ - inner(vp, div(u))*dx df.solve(df.lhs(F) == df.rhs(F), up_, bcs=bcs) self.u_.assign(df.project(u_, self.V)) self.p_.assign(df.project(p_, self.Q)) return
def get_adot_from_orog_precip(ltop_constants): """ Calculates SMB for Linear Orographic Precipitation Model """ amin = ltop_constants["amin"] amax = ltop_constants["amax"] Smin = ltop_constants["Smin"] Smax = ltop_constants["Smax"] Sela = ltop_constants["Sela"] Pscale = ltop_constants["P_scale"] P0 = ltop_constants["P0"] x_a = df.project(X[0]).vector().get_local() y_a = df.project(S).vector().get_local() XX, YY = np.meshgrid(x_a, list(range(3))) Orography = np.tile(y_a, (3, 1)) OP = OrographicPrecipitation( XX, YY, Orography, ltop_constants, truncate=True, ounits="m year-1", tomass=False, ) P = OP.P P = P[1, :] return P
def test_print(self): from .expr import tuple_to_point mesh = dolfin.UnitSquareMesh(25, 25) muc = mesh.ufl_cell() R = ReferenceFrame('R') from sympy import exp, atan x, y = R[0], R[1] s_expr = x**2 + exp(y - DolfinConstant(0.5)) - atan(x - y) u_expr = sympy_to_ufl(R, mesh, s_expr) el1 = dolfin.FiniteElement('CG', muc, 1) W1 = dolfin.FunctionSpace(mesh, el1) u1 = dolfin.project(u_expr, W1) f = sympy.lambdify((x, y), DolfinConstant.release(s_expr)) for x0 in np.linspace(0, 1, 10): for y0 in np.linspace(0, 1, 10): a, b = f(x0, y0), u1(tuple_to_point((x0, y0))) self.assertLess(abs(a / b - 1), 0.001) s2_expr = (y * R.x + x * y * R.y).to_matrix(R)[:2, :] u2_expr = sympy_to_ufl(R, mesh, s2_expr) el2 = dolfin.FiniteElement('BDM', muc, 1) W2 = dolfin.FunctionSpace(mesh, el2) u2 = dolfin.project(u2_expr, W2) self.assertLess(abs(u2(tuple_to_point((0.2, 0.2)))[1] - 0.04), 0.001)
def get_list_of_functions_2(block_V): shape_1 = block_V[0].ufl_element().value_shape() if len(shape_1) is 0: f1 = Expression("2*x[0] + 4*x[1]*x[1]", degree=2) elif len(shape_1) is 1 and shape_1[0] is 2: f1 = Expression(("2*x[0] + 4*x[1]*x[1]", "3*x[0] + 5*x[1]*x[1]"), degree=2) elif len(shape_1) is 1 and shape_1[0] is 3: f1 = Expression(("2*x[0] + 4*x[1]*x[1]", "3*x[0] + 5*x[1]*x[1]", "7*x[0] + 11*x[1]*x[1]"), degree=2) elif len(shape_1) is 2: f1 = Expression((("2*x[0] + 4*x[1]*x[1]", "3*x[0] + 5*x[1]*x[1]"), ("7*x[0] + 11*x[1]*x[1]", "13*x[0] + 17*x[1]*x[1]")), degree=2) shape_2 = block_V[1].ufl_element().value_shape() if len(shape_2) is 0: f2 = Expression("2*x[1] + 4*x[0]*x[0]", degree=2) elif len(shape_2) is 1 and shape_2[0] is 2: f2 = Expression(("2*x[1] + 4*x[0]*x[0]", "3*x[1] + 5*x[0]*x[0]"), degree=2) elif len(shape_2) is 1 and shape_2[0] is 3: f2 = Expression(("2*x[1] + 4*x[0]*x[0]", "3*x[1] + 5*x[0]*x[0]", "7*x[1] + 11*x[0]*x[0]"), degree=2) elif len(shape_2) is 2: f2 = Expression((("2*x[1] + 4*x[0]*x[0]", "3*x[1] + 5*x[0]*x[0]"), ("7*x[1] + 11*x[0]*x[0]", "13*x[1] + 17*x[0]*x[0]")), degree=2) return [project(f1, block_V[0]), project(f2, block_V[1])]
def solve_cycle(state): print('Solving state:', state['name']) # u1.assign(state['u_prev']) u0.assign(state['u_last']) p0.assign(state['pressure']) rhs.assign( project(dt * (-u0.dx(0) * u0 - nu * u0.dx(0).dx(0) / 2.0 - p0.dx(0)), Q)) plot(rhs, title='RHS') # rhs_nonlinear.assign(project(dt*(- u0.dx(0)*u0), Q)) # rhs_visc.assign(project(dt*(-nu*u0.dx(0).dx(0)/2.0), Q)) # rhs_pressure.assign(project(dt*(-p0.dx(0)), Q)) # plot(rhs_nonlinear, title='RHS nonlin') # plot(rhs_visc, title='RHS visc') # plot(rhs_pressure, title='RHS pressure') solve(a_tent == L_tent, u_tent_computed, bcu) if state['rot']: if state['null']: b = assemble(L_p_rot) null_space.orthogonalize(b) solve(A_p_rot, p_computed.vector(), b, 'cg') else: solve(a_p_rot == L_p_rot, p_computed, bcp) solve(a_cor_rot == L_cor_rot, u_cor_computed) div_u_tent.assign(project(-nu * u_tent_computed.dx(0), Vplot)) plot(div_u_tent, title=state['name'] + '_div u_tent (pressure correction), t = ' + str(t)) # div_u_tent.assign(project(p0+p_computed-nu*state['p_tent'].dx(0), Q)) # plot(div_u_tent, title=state['name']+'_RHS (pressure correction), t = ' +str(t)) solve(a_rot == L_rot, p_cor_computed) p_correction.assign(p_cor_computed - p_computed - p0) plot(p_correction, title=state['name'] + '_(computed pressure correction), t = ' + str(t)) print(' updating state') state['u_prev'].assign(state['u_last']) state['u_tent'].assign(u_tent_computed) state['u_last'].assign(u_cor_computed) state['pressure'].assign(p_cor_computed) state['p_tent'].assign(p_computed + p0) else: if state['null']: b = assemble(L_p) null_space.orthogonalize(b) print('new:', assemble((v_in_expr - u_tent_computed) * ds(2))) # plot(interpolate((v_in_expr-u_tent_computed)*ds(2), Q), title='new') # print(A_p.array()) # print(b.array()) solve(A_p, p_computed.vector(), b, 'gmres') else: solve(a_p == L_p, p_computed, bcp) solve(a_cor == L_cor, u_cor_computed) print(' updating state') # state['u_prev'].assign(state['u_last']) state['u_tent'].assign(u_tent_computed) state['u_last'].assign(u_cor_computed) state['pressure'].assign(p_computed)
def initialize_plot(self): # Create variables for plotting the topography self.full_mesh = d.IntervalMesh(100, 0, 500e3) self.full_x = self.full_mesh.coordinates() self.full_V = d.FunctionSpace(self.full_mesh, 'Lagrange', 1) self.full_bed = map(d.project(self.h_b, self.full_V), self.full_x) self.full_W = \ npy.array(map(d.project(self.W, self.full_V), self.full_x))/1000. self.full_x = self.full_x * 0.001 # convert from meters to kilometers
def solve(self): assert not hasattr(self, "_is_solving") self._is_solving = True f00 = project(self.f00, self.V00) f01 = project(self.f01, self.V00) assign(self._solution.sub(0).sub(0), f00) assign(self._solution.sub(0).sub(1), f01) delattr(self, "_is_solving") return self._solution
def solve(self): print("solving mock problem at mu =", self.mu) assert not hasattr(self, "_is_solving") self._is_solving = True f00 = project(self.f00, self.V00) f01 = project(self.f01, self.V00) assign(self._solution.sub(0).sub(0), f00) assign(self._solution.sub(0).sub(1), f01) delattr(self, "_is_solving") return self._solution
def update_plot_fields(self): """ These fields are only needed to visualise the rho and nu fields in xdmf format for Paraview or similar """ if not self.plot_fields: return V = self.rho_for_plot.function_space() dolfin.project(self.get_density(0), V, function=self.rho_for_plot) dolfin.project(self.get_laminar_kinematic_viscosity(0), V, function=self.nu_for_plot)
def compute_solution_flux(pde, RV_samples, coeff_field, u, maxm, proj_basis, vec_proj_basis): a = coeff_field.mean_func for m in range(maxm): a_m = RV_samples[m] * coeff_field[m][0] a = a + a_m print type(a) uN = u._fefunc uN = project(u._fefunc, proj_basis._fefs) s = pde.weak_form.flux(uN, a) return FEniCSVector(project(s, vec_proj_basis._fefs))
def compute(self, get): u1 = get(self.valuename1) u2 = get(self.valuename2) if u1 is None or u2 is None: return if not (isinstance(u1, GenericFunction) or isinstance(u2, GenericFunction)): return npdot(u1, u2) if not isinstance(u1, GenericFunction): u1 = Constant(u1) u1, u2 = u2, u1 if not isinstance(u2, GenericFunction): u2 = Constant(u2) if isinstance(u2, Function): u1, u2 = u2, u1 assert isinstance(u1, Function) assert isinstance(u2, GenericFunction) if u1.value_rank() == u2.value_rank(): if u1.value_rank() == 0: V = u1.function_space() else: V = u1.function_space().sub(0).collapse() elif u1.value_rank() > u2.value_rank(): assert u2.value_rank() == 0 V = u1.function_space() u1, u2 = u2, u1 else: assert isinstance(u2, Function) assert u1.value_rank() == 0 V = u2.function_space() #N = max([u1.value_rank(), u2.value_rank()]) if not hasattr(self, "u"): self.u = Function(V) if isinstance(u2, Function) and u1.function_space().dim( ) == u2.function_space().dim() and u1.value_rank() == 0: self.u.vector()[:] = u1.vector().array() * u2.vector().array() elif u1.value_rank() == u2.value_rank(): project(dot(u1, u2), function=self.u, V=self.u.function_space()) else: assert u1.value_rank() == 0 if isinstance(u1, Constant): self.u.vector()[:] = float(u1) * u2.vector().array() else: project(u1 * u2, function=self.u, V=self.u.function_space()) return self.u
def project(self, obj, initial = False): """Project given function to the Smart Function. Args: obj(:class:`dolfin.GenericFunction`): Function to project. initial(:obj:`bool`): Project to initial function space. Defaults to False. """ if initial and self.functionSpace0: self.vector()[:] = project(obj, self.functionSpace0).vector()[:] else: self.vector()[:] = project(obj, self.functionSpace).vector()[:]
def move_wall(self,const=const): """ Calculate the amount of melting/freezing at the hole wall This is the Stefan condition. """ # --- Calculate Distance Wall Moves --- # # Melting/freezing at the hole wall from prescribed flux and temperature gradient # Humphrey and Echelmeyer (1990) eq. 13 dRdt = dolfin.project(dolfin.Expression('exp(-x[0])',degree=1)*self.u0_i.dx(0),self.ice_V).vector()[self.ice_idx_wall] + \ self.Qstar/self.Rstar # second half of the Stefan condition dRdt -= (self.ks_wall/const.ki)*dolfin.project(dolfin.Expression('exp(-x[0])',degree=1)*self.u0_s.dx(0),self.sol_V).vector()[self.sol_idx_wall] self.dR = dRdt*self.dt # Is the hole completely frozen? If so, exit Frozen = np.exp(self.ice_coords[self.ice_idx_wall,0])+self.dR < 0. if Frozen: self.flags.append('Frozen') return # --- Move the Mesh --- ### # stretch mesh rather than uniform displacement dRsi = self.dR/(self.Rstar_inf-self.Rstar)*(self.Rstar_inf-np.exp(self.ice_coords[:,0])) # Interpolate the points onto what will be the new mesh (ice) self.ice_idx_extrapolate = np.exp(self.ice_coords[:,0]) + self.dR >= self.Rstar u0_i_hold = self.u0_i.vector()[:].copy() u0_i_hold[self.ice_idx_extrapolate] = np.array([self.u0_i(xi) for xi in np.log(np.exp(self.ice_coords[self.ice_idx_extrapolate,0])+dRsi[self.ice_idx_extrapolate])]) u0_i_hold[~self.ice_idx_extrapolate] = self.Tf_wall self.u0_i.vector()[:] = u0_i_hold[:] # advect the mesh according to the movement of the hole wall dolfin.ALE.move(self.ice_mesh,dolfin.Expression('std::log(exp(x[0])+dRsi*(Rstar_inf-exp(x[0])))-x[0]',degree=1,dRsi=self.dR/(self.Rstar_inf-self.Rstar),Rstar_inf=self.Rstar_inf)) self.ice_mesh.bounding_box_tree().build(self.ice_mesh) self.ice_coords = self.ice_V.tabulate_dof_coordinates().copy() # stretch mesh rather than uniform displacement dRss = self.dR/(self.Rstar-self.Rstar_center)*(np.exp(self.sol_coords[:,0])-self.Rstar_center) # Interpolate the points onto what will be the new mesh (solution) self.sol_idx_extrapolate = np.exp(self.sol_coords[:,0]) + self.dR <= self.Rstar u0_s_hold = self.u0_s.vector()[:].copy() u0_s_hold[self.sol_idx_extrapolate] = np.array([self.u0_s(xi) for xi in np.log(np.exp(self.sol_coords[self.sol_idx_extrapolate,0])+dRss[self.sol_idx_extrapolate])]) u0_s_hold[~self.sol_idx_extrapolate] = self.Tf_wall self.u0_s.vector()[:] = u0_s_hold[:] u0_c_hold = self.u0_c.vector()[:].copy() u0_c_hold[self.sol_idx_extrapolate] = np.array([self.u0_c(xi) for xi in np.log(np.exp(self.sol_coords[self.sol_idx_extrapolate,0])+dRss[self.sol_idx_extrapolate])]) u0_c_hold[~self.sol_idx_extrapolate] = np.nan self.u0_c.vector()[:] = u0_c_hold[:] # advect the mesh according to the movement of teh hole wall dolfin.ALE.move(self.sol_mesh,dolfin.Expression('std::log(exp(x[0])+dRs*(exp(x[0])-Rstar_center))-x[0]', degree=1,dRs=self.dR/(self.Rstar-self.Rstar_center),Rstar_center=self.Rstar_center)) self.sol_mesh.bounding_box_tree().build(self.sol_mesh) self.sol_coords = self.sol_V.tabulate_dof_coordinates().copy()
def Forces0(v, u): E = -grad(v) pi = 3.141592653589793 Fel = dolfin.Constant(qTarget) * E Fdrag = dolfin.Constant(6 * pi * eta * rTarget) * u F = Fel + Fdrag V = dolfin.VectorFunctionSpace(geo.mesh, "CG", 1) Fel = dolfin.project(Fel, V) Fdrag = dolfin.project(Fdrag, V) F = dolfin.project(F, V) return F, Fel, Fdrag
def plot_exactsolution(PrP, TsP): u_file = dolfin.File("results/exa_velocity.pvd") p_file = dolfin.File("results/exa_pressure.pvd") for tcur in np.linspace(TsP.t0, TsP.tE, 11): PrP.v.t = tcur PrP.p.t = tcur vcur = dolfin.project(PrP.v, PrP.V) pcur = dolfin.project(PrP.p, PrP.Q) u_file << vcur, tcur p_file << pcur, tcur
def evaluate_backend(self, r, j, problem_wrapper): project(self.initial_guess_expression, self.V, function=self.u) solver = NonlinearSolver(problem_wrapper, self.u) solver.set_parameters({ "linear_solver": "mumps", "maximum_iterations": 20, "relative_tolerance": 1e-9, "absolute_tolerance": 1e-9, "report": True }) solver.solve() return self.u.copy(deepcopy=True)
def solve_cycle(state): print('Solving state:', state['name']) # u1.assign(state['u_prev']) u0.assign(state['u_last']) p0.assign(state['pressure']) rhs.assign(project(dt*(- u0.dx(0)*u0 - nu*u0.dx(0).dx(0)/2.0 - p0.dx(0)), Q)) plot(rhs, title='RHS') # rhs_nonlinear.assign(project(dt*(- u0.dx(0)*u0), Q)) # rhs_visc.assign(project(dt*(-nu*u0.dx(0).dx(0)/2.0), Q)) # rhs_pressure.assign(project(dt*(-p0.dx(0)), Q)) # plot(rhs_nonlinear, title='RHS nonlin') # plot(rhs_visc, title='RHS visc') # plot(rhs_pressure, title='RHS pressure') solve(a_tent == L_tent, u_tent_computed, bcu) if state['rot']: if state['null']: b = assemble(L_p_rot) null_space.orthogonalize(b) solve(A_p_rot, p_computed.vector(), b, 'cg') else: solve(a_p_rot == L_p_rot, p_computed, bcp) solve(a_cor_rot == L_cor_rot, u_cor_computed) div_u_tent.assign(project(-nu*u_tent_computed.dx(0), Vplot)) plot(div_u_tent, title=state['name']+'_div u_tent (pressure correction), t = ' +str(t)) # div_u_tent.assign(project(p0+p_computed-nu*state['p_tent'].dx(0), Q)) # plot(div_u_tent, title=state['name']+'_RHS (pressure correction), t = ' +str(t)) solve(a_rot == L_rot, p_cor_computed) p_correction.assign(p_cor_computed-p_computed-p0) plot(p_correction, title=state['name']+'_(computed pressure correction), t = ' +str(t)) print(' updating state') state['u_prev'].assign(state['u_last']) state['u_tent'].assign(u_tent_computed) state['u_last'].assign(u_cor_computed) state['pressure'].assign(p_cor_computed) state['p_tent'].assign(p_computed+p0) else: if state['null']: b = assemble(L_p) null_space.orthogonalize(b) print('new:', assemble((v_in_expr-u_tent_computed)*ds(2))) # plot(interpolate((v_in_expr-u_tent_computed)*ds(2), Q), title='new') # print(A_p.array()) # print(b.array()) solve(A_p, p_computed.vector(), b, 'gmres') else: solve(a_p == L_p, p_computed, bcp) solve(a_cor == L_cor, u_cor_computed) print(' updating state') # state['u_prev'].assign(state['u_last']) state['u_tent'].assign(u_tent_computed) state['u_last'].assign(u_cor_computed) state['pressure'].assign(p_computed)
def _write_projected_efield(self, i): """ take domain :param str i: and project e-field there """ Vector_sub = d.VectorFunctionSpace(self.sub_mesh, self.data['properties']['project_element'], self.data['properties']['project_degree']) efield_sub = d.project(self.Efield_real, Vector_sub, solver_type=self.data['properties']['project_solver'], preconditioner_type=self.data['properties']['project_preconditioner']) efield_sub.rename('E-Field real part', 'E-Field real part sub') self.dataXDMFEreal.write(efield_sub) efield_sub = d.project(self.Efield_imag, Vector_sub, solver_type=self.data['properties']['project_solver'], preconditioner_type=self.data['properties']['project_preconditioner']) efield_sub.rename('E-Field imag part', 'E-Field imag part sub') self.dataXDMFEimag.write(efield_sub) self.logger.debug("Wrote e-field for domain " + i)
def _compute_time_errors(problem, method, mesh_sizes, Dt, plot_error=False): mesh_generator, solution, ProblemClass, cell_type = problem() # Translate data into FEniCS expressions. fenics_sol = Expression(smp.printing.ccode(solution['value']), degree=solution['degree'], t=0.0, cell=cell_type ) # Compute the problem errors = {'theta': numpy.empty((len(mesh_sizes), len(Dt)))} # Create initial state. # Deepcopy the expression into theta0. Specify the cell to allow for # more involved operations with it (e.g., grad()). theta0 = Expression(fenics_sol.cppcode, degree=solution['degree'], t=0.0, cell=cell_type ) for k, mesh_size in enumerate(mesh_sizes): mesh = mesh_generator(mesh_size) V = FunctionSpace(mesh, 'CG', 1) theta_approx = Function(V) theta0p = project(theta0, V) stepper = method(ProblemClass(V)) if plot_error: error = Function(V) for j, dt in enumerate(Dt): # TODO We are facing a little bit of a problem here, being the # fact that the time stepper only accept elements from V as u0. # In principle, though, this isn't necessary or required. We # could allow for arbitrary expressions here, but then the API # would need changing for problem.lhs(t, u). # Think about this. stepper.step(theta_approx, theta0p, 0.0, dt, tol=1.0e-12, verbose=False ) fenics_sol.t = dt # # NOTE # When using errornorm(), it is quite likely to see a good part # of the error being due to the spatial discretization. Some # analyses "get rid" of this effect by (sometimes implicitly) # projecting the exact solution onto the discrete function # space. errors['theta'][k][j] = errornorm(fenics_sol, theta_approx) if plot_error: error.assign(project(fenics_sol - theta_approx, V)) plot(error, title='error (dt=%e)' % dt) interactive() return errors, stepper.name, stepper.order
def __init__(self, strs, mesh, BHat, plot1, plot2, plot3): self.run = True self.strs = strs self.mesh = mesh self.x = mesh.coordinates().flatten() S = project(strs.H0+strs.B) B = project(strs.B) TD = project(self.strs.tau_d_plot) TB = project(self.strs.tau_b_plot) TX = project(self.strs.tau_xx_plot) TY = project(self.strs.tau_xy_plot) TZ = project(self.strs.tau_xz_plot) self.plot1 = plot1 self.plot1.showGrid(x=True, y=True) self.ph0 = self.plot1.plot(self.x, B.compute_vertex_values(), pen=bluePlotPen) self.ph100 = self.plot1.plot(self.x, S.compute_vertex_values(), pen=redPlotPen) self.ph1 = self.plot1.plot(self.x, S.compute_vertex_values(), pen=whitePlotPen) self.ph2 = self.plot1.plot(self.x, BHat.compute_vertex_values(), pen=brownPlotPen) self.legend1 = ModelLegend(offset=(-50, 50)) self.legend1.setParentItem(self.plot1.graphicsItem()) self.legend1.addItem(self.ph0, '<i>B</i>') self.legend1.addItem(self.ph100, '<i>S</i><sub>o</sub>') self.legend1.addItem(self.ph1, '<i>S</i>') self.legend1.addItem(self.ph2, '<i>Bed</i>') self.plot2 = plot2 self.plot2.showGrid(x=True, y=True) self.ph2 = self.plot2.plot(self.x, TD.compute_vertex_values(), pen=bluePlotPen) self.ph3 = self.plot2.plot(self.x, TB.compute_vertex_values(), pen=greenPlotPen) self.ph4 = self.plot2.plot(self.x, TX.compute_vertex_values(), pen=redPlotPen) self.ph5 = self.plot2.plot(self.x, TY.compute_vertex_values(), pen=tealPlotPen) self.ph6 = self.plot2.plot(self.x, TZ.compute_vertex_values(), pen=pinkPlotPen) self.legend2 = ModelLegend(offset=(-50, 50)) self.legend2.setParentItem(self.plot2.graphicsItem()) self.legend2.addItem(self.ph2, 'τ<sub>d</sub>') self.legend2.addItem(self.ph3, 'τ<sub>b</sub>') self.legend2.addItem(self.ph4, 'τ<sub>xx</sub>') self.legend2.addItem(self.ph5, 'τ<sub>xy</sub>') self.legend2.addItem(self.ph6, 'τ<sub>xz</sub>') self.plot3 = plot3 self.plot3.showGrid(x=True, y=True) self.legend3 = ModelLegend(offset=(-50, 50)) self.legend3.setParentItem(self.plot3.graphicsItem()) us = project(self.strs.u(0)) ub = project(self.strs.u(1)) self.ph7 = self.plot3.plot(self.x, us.compute_vertex_values(), pen=bluePlotPen) self.ph8 = self.plot3.plot(self.x, ub.compute_vertex_values(), pen=greenPlotPen) self.legend3.addItem(self.ph7, 'μ<sub>s</sub>') self.legend3.addItem(self.ph8, 'μ<sub>b</sub>')
def costab(self, m1, m2): self.gradm1 = project(nabla_grad(m1), self.Vd) self.gradm2 = project(nabla_grad(m2), self.Vd) cost = 0.0 for x, vol in zip(self.x, self.vol): G = np.array([self.gradm1(x), self.gradm2(x)]).T u, s, v = np.linalg.svd(G) sqrts2eps = np.sqrt(s**2 + self.eps) cost += vol * sqrts2eps.sum() cost_global = MPI.sum(self.mpicomm, cost) return self.k * cost_global
def helper_test_roundtrip(self, dedup): mesh0 = dolfin.UnitSquareMesh(3, 5) uc0 = mesh0.ufl_cell() el0 = dolfin.FiniteElement('CG', uc0, 2) W0 = dolfin.FunctionSpace(mesh0, el0) u0 = dolfin.Function(W0) mf0 = dolfin.MeshFunction("size_t", mesh0, 1, 0) mf0.array()[:] = range(len(mf0.array())) x = dolfin.SpatialCoordinate(mesh0) dolfin.project(x[0] - x[1]**2, W0, function=u0) outdir = tempfile.mkdtemp('.solution_io') # atexit.register(partial(shutil.rmtree, outdir)) outfile = os.path.join(outdir, 'test.yaml') man = DolfinH5Manager(outfile) with open(outfile, 'wt') as stream: yaml.dump( dict(mesh=mesh0, u=u0, mf=mf0), stream, Dumper=partial(XDumper, x_attr_dict=dict( dolfin_h5_manager=man))) with open(outfile, 'rt') as h: print(h.read()) if dedup: from h5dedup.dedup import DedupRepository repo = DedupRepository(outdir) repo.deduplicate_file_tree(outdir) with open(outfile, 'rt') as stream: r = yaml.load(stream, Loader=partial(XLoader, x_attr_dict=dict( dolfin_h5_manager=man))) mesh1 = dolfin.Mesh() r['mesh'].load_into(mesh1) W1 = dolfin.FunctionSpace(mesh1, el0) u1 = dolfin.Function(W1) r['u'].load_into(u1) mf1 = dolfin.MeshFunction("size_t", mesh1, 1, 0) r['mf'].load_into(mf1) u1_ = dolfin.project(u1, W0) self.assertLess(dolfin.assemble((u0-u1_)**2*dolfin.dx), 1e-26) self.assertEqual(tuple(mf0.array()), tuple(mf1.array()))
def gradab(self, m1, m2): self.gradm1 = project(nabla_grad(m1), self.Vd) self.gradm2 = project(nabla_grad(m2), self.Vd) uwv00, uwv00ind = [], [] uwv10, uwv10ind = [], [] uwv01, uwv01ind = [], [] uwv11, uwv11ind = [], [] for ii, x in enumerate(self.x): G = np.array([self.gradm1(x), self.gradm2(x)]).T u, s, v = np.linalg.svd(G) sqrts2eps = np.sqrt(s**2 + self.eps) W = np.diag(s / sqrts2eps) uwv = u.dot(W.dot(v)) uwv00.append(uwv[0][0]) uwv00ind.append(ii) uwv10.append(uwv[1][0]) uwv10ind.append(ii) uwv01.append(uwv[0][1]) uwv01ind.append(ii) uwv11.append(uwv[1][1]) uwv11ind.append(ii) Grad = Function(self.VV) grad = Grad.vector() rhsG = Vector() self.Gx1test.init_vector(rhsG, 1) rhsG.set_local(np.array(uwv00), np.array(uwv00ind, dtype=np.intc)) rhsG.apply('insert') grad.axpy(1.0, self.Gx1test * rhsG) rhsG.zero() rhsG.set_local(np.array(uwv10), np.array(uwv10ind, dtype=np.intc)) rhsG.apply('insert') grad.axpy(1.0, self.Gy1test * rhsG) rhsG.set_local(np.array(uwv01), np.array(uwv01ind, dtype=np.intc)) rhsG.apply('insert') grad.axpy(1.0, self.Gx2test * rhsG) rhsG.set_local(np.array(uwv11), np.array(uwv11ind, dtype=np.intc)) rhsG.apply('insert') grad.axpy(1.0, self.Gy2test * rhsG) return grad * self.k
def plot_deltas_2D(vertex_vector, mesh_path, save_dir): mesh = Mesh() with XDMFFile(mesh_path) as f: f.read(mesh) V = FunctionSpace(mesh, 'CG', 1) value = Function(V) value.vector()[:] = vertex_vector[dof_to_vertex_map(V)] delta_S = project(value.dx(0), V) delta_file = XDMFFile(save_dir) delta_file.write_checkpoint(delta_S, 'delta_S', 0, XDMFFile.Encoding.HDF5, True) delta_v = project(value.dx(1), V) delta_file.write_checkpoint(delta_v, 'delta_v', 0, XDMFFile.Encoding.HDF5, True)
def runNextStep(self): 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) # Optimizations in fenics optimizations set_solver_options(self.coupled_solver) try: self.coupled_solver.solve(set_solver_options()) except: self.coupled_solver.parameters['snes_solver']['error_on_nonconvergence'] = False self.assigner.assign(self.U, [self.zero_sol, self.zero_sol, self.H0]) self.coupled_solver.solve() self.coupled_solver.parameters['snes_solver']['error_on_nonconvergence'] = True self.assigner_inv.assign([self.un, self.u2n, self.H0], self.U) self.times.append(self.t) self.BB.append(df.project(self.strs.B).compute_vertex_values()) self.HH.append(self.strs.H0.compute_vertex_values()) self.TD.append(df.project(self.strs.tau_d_plot).compute_vertex_values()) self.TB.append(df.project(self.strs.tau_b_plot).compute_vertex_values()) self.TX.append(df.project(self.strs.tau_xx_plot).compute_vertex_values()) self.TY.append(df.project(self.strs.tau_xy_plot).compute_vertex_values()) self.TZ.append(df.project(self.strs.tau_xz_plot).compute_vertex_values()) self.us.append(df.project(self.strs.u(0)).compute_vertex_values()) self.ub.append(df.project(self.strs.u(1)).compute_vertex_values()) self.t += self.dtFloat return self.BB[-1], self.HH[-1], self.TD[-1], self.TB[-1], self.TX[-1], self.TY[-1], self.TZ[-1], self.us[-1], \ self.ub[-1]
def evaluate_expression(expression, function, replaced_expression=None): if replaced_expression is None: replaced_expression = expression assert isinstance(expression, (BaseExpression, Function, Operator)) if isinstance(expression, BaseExpression): LagrangeInterpolator.interpolate(function, replaced_expression) elif isinstance(expression, Function): assign(function, replaced_expression) elif isinstance(expression, Operator): project(replaced_expression, function.function_space(), function=function) else: raise ValueError("Invalid expression")
def get_initial_conditions(self,rho_solute=const.rhom): """ Set the initial condition at the end of melting (melting can be solved analytically """ # --- Initial states --- # # ice temperature self.u0_i = dolfin.Function(self.ice_V) T,lam,self.R_melt,self.t_melt = analyticalMelt(np.exp(self.ice_coords[:,0])*self.R_melt,self.T_inf,self.Q_initialize,R_target=self.R_melt) self.u0_i.vector()[:] = T/abs(self.T_inf) # solution temperature self.u0_s = dolfin.Function(self.sol_V) T,lam,self.R_melt,self.t_melt = analyticalMelt(np.exp(self.sol_coords[:,0])*self.R_melt,self.T_inf,self.Q_initialize,R_target=self.R_melt) self.u0_s.vector()[:] = T/abs(self.T_inf) # solution concentration self.u0_c = dolfin.interpolate(dolfin.Constant(self.C_init),self.sol_V) # --- Time Array --- # # Now that we have the melt-out time, we can define the time array self.ts = np.arange(self.t_melt,self.t_final+self.dt,self.dt)/self.t0 self.dt /= self.t0 # Define the ethanol source self.source_timing = self.ts[np.argmin(abs(self.ts-self.source_timing/self.t0))] if 'gaussian_source' in self.flags: self.source_duration /= self.t0 self.source = self.source_mass_final/(self.source_duration*np.sqrt(np.pi))*np.exp(-((self.ts-self.source_timing)/self.source_duration)**2.) else: self.source = np.zeros_like(self.ts) self.source[np.argmin(abs(self.ts-self.source_timing))] = self.source_mass_final/self.dt # --- Define the test and trial functions --- # self.u_i = dolfin.TrialFunction(self.ice_V) self.v_i = dolfin.TestFunction(self.ice_V) self.T_i = dolfin.Function(self.ice_V) self.u_s = dolfin.TrialFunction(self.sol_V) self.v_s = dolfin.TestFunction(self.sol_V) self.T_s = dolfin.Function(self.sol_V) self.C = dolfin.Function(self.sol_V) self.Tf = Tf_depression(self.C,linear=True)/abs(self.T_inf) self.Tf_wall = dolfin.project(self.Tf,self.sol_V).vector()[self.sol_idx_wall] # Get the updated solution properties self.rhos = dolfin.project(dolfin.Expression('C + rhow*(1.-C/rho)',degree=1,C=self.C,rhow=const.rhow,rho=rho_solute),self.sol_V) self.cs = dolfin.project(dolfin.Expression('ce*(C/rho) + cw*(1.-C/rho)',degree=1,C=self.C,cw=const.cw,ce=const.ce,rho=rho_solute),self.sol_V) self.ks = dolfin.project(dolfin.Expression('ke*(C/rho) + kw*(1.-C/rho)',degree=1,C=self.C,kw=const.kw,ke=const.ke,rho=rho_solute),self.sol_V) self.rhos_wall = self.rhos.vector()[self.sol_idx_wall] self.cs_wall = self.cs.vector()[self.sol_idx_wall] self.ks_wall = self.ks.vector()[self.sol_idx_wall] self.flags.append('get_ic')
def symmetrize(u, d, sym): """ Symmetrize function u. """ if len(d) == 3: # three dimensions -> cycle XYZ return cyclic3D(u) elif len(d) >= 4: # four dimensions -> rotations in 2D return rotational(u, d[-1]) nrm = np.linalg.norm(u.vector()) V = u.function_space() mesh = Mesh(V.mesh()) # test if domain is symmetric using function equal 0 inside, 1 on boundary # extrapolation will force large values if not symmetric since the flipped # domain is different bc = DirichletBC(V, 1, DomainBoundary()) test = Function(V) bc.apply(test.vector()) if len(d) == 2: # two dimensions given: swap dimensions mesh.coordinates()[:, d] = mesh.coordinates()[:, d[::-1]] else: # one dimension given: reflect mesh.coordinates()[:, d[0]] *= -1 # FIXME functionspace takes a long time to construct, maybe copy? W = FunctionSpace(mesh, 'CG', 1) try: # testing test = interpolate(Function(W, test.vector()), V) # max-min should be around 1 if domain was symmetric # may be slightly above due to boundary approximation assert max(test.vector()) - min(test.vector()) < 1.1 v = interpolate(Function(W, u.vector()), V) if sym: # symmetric pr = project(u+v) else: # antisymmetric pr = project(u-v) # small solution norm most likely means that symmetrization gives # trivial function assert np.linalg.norm(pr.vector())/nrm > 0.01 return pr except: # symmetrization failed for some reason print "Symmetrization " + str(d) + " failed!" return u
def cyclic3D(u): """ Symmetrize with respect to (xyz) cycle. """ try: nrm = np.linalg.norm(u.vector()) V = u.function_space() assert V.mesh().topology().dim() == 3 mesh1 = Mesh(V.mesh()) mesh1.coordinates()[:, :] = mesh1.coordinates()[:, [1, 2, 0]] W1 = FunctionSpace(mesh1, 'CG', 1) # testing if symmetric bc = DirichletBC(V, 1, DomainBoundary()) test = Function(V) bc.apply(test.vector()) test = interpolate(Function(W1, test.vector()), V) assert max(test.vector()) - min(test.vector()) < 1.1 v1 = interpolate(Function(W1, u.vector()), V) mesh2 = Mesh(mesh1) mesh2.coordinates()[:, :] = mesh2.coordinates()[:, [1, 2, 0]] W2 = FunctionSpace(mesh2, 'CG', 1) v2 = interpolate(Function(W2, u.vector()), V) pr = project(u+v1+v2) assert np.linalg.norm(pr.vector())/nrm > 0.01 return pr except: print "Cyclic symmetrization failed!" return u
def plot_site_constraints(config, vertices): ineqs = [] for p in range(len(vertices)): # x1 and x2 are the two points that describe one of the sites edge x1 = numpy.array(vertices[p]) x2 = numpy.array(vertices[(p + 1) % len(vertices)]) c = x2 - x1 # Normal vector of c n = [c[1], -c[0]] ineqs.append((x1, n)) class SiteConstraintExpr(dolfin.Expression): def eval(self, value, x): inside = True for x1, n in ineqs: # The inequality for this edge is: g(x) := n^T.(x1-x) >= 0 inside = inside and (numpy.dot(n, x1 - x) >= 0) value[0] = int(inside) f = dolfin.project(SiteConstraintExpr(), config.turbine_function_space) out_file = dolfin.File(config.params['base_path'] + os.path.sep + "site_constraints.pvd", "compressed") out_file << f
def to_array(z_func, V): """Converts a dolfin function or expression to an array by interpolating or projecting onto some FunctionSpace""" try: return dolfin.interpolate(z_func, V).vector().array() except: return dolfin.project(z_func, V).vector().array()
def get_funcexpr_as_vec(u, U, invinds=None, t=None): if t is not None: u.t = t if invinds is None: invinds = range(U.dim()) ua = project(u, U) ua = ua.vector() ua = ua.array() return ua
def test_m_110(): theta = np.pi/4 m = df.project(df.Constant((1, 0, 1)), VV) u, j, i = amr(mesh, m, DirichletBoundary, g, mesh2d, s0=1, alpha=1) # Check the potential in the middle of the sample. assert abs(u(d/2., d/2., d/2.) - 0.5) < tol # Check electric field. E = df.project(-df.grad(u), VV) assert abs(E(0.5, 0.5, 0.5)[0] - 1./d) < tol assert abs(E(0.5, 0.5, 0.5)[1] - 0) < tol assert abs(E(0.5, 0.5, 0.5)[2] - 0) < tol # Check current density. rho = 1 + np.cos(theta)**2 assert abs(j(0.5, 0.5, 0.5)[0] - 1./(d*rho)) < tol assert abs(j(0.5, 0.5, 0.5)[1] - 0) < tol assert abs(j(0.5, 0.5, 0.5)[2] - 0) < tol # Check current (current density flux). assert abs(i - d/rho) < tol
def compute_functionals(self, velocity, pressure, t, step): if self.args.wss == 'all' or \ (step >= self.stepsInCycle and self.args.wss == 'peak' and (self.distance_from_chosen_steps < 0.5 * self.metadata['dt'])): # TODO check if choosing time steps works properly # QQ might skip step? change 0.5 to 0.51? self.tc.start('WSS') begin('WSS (%dth step)' % step) if self.args.wss_method == 'expression': stress = project(self.nu*2*sym(grad(velocity)), self.T) # pressure is not used as it contributes only to the normal component stress.set_allow_extrapolation(True) # need because of some inaccuracies in BoundaryMesh coordinates stress_b = interpolate(stress, self.Tb) # restrict stress to boundary mesh # self.fileDict['stress']['file'].write(stress_b, self.actual_time) # info('Saved stress tensor') info('Computing WSS') wss = dot(stress_b, self.nb) - inner(dot(stress_b, self.nb), self.nb)*self.nb wss_func = project(wss, self.Vb) wss_norm = project(sqrt_ufl(inner(wss, wss)), self.Sb) info('Saving WSS') self.fileDict['wss']['file'].write(wss_func, self.actual_time) self.fileDict['wss_norm']['file'].write(wss_norm, self.actual_time) if self.args.wss_method == 'integral': wss_norm = Function(self.SDG) mS = TestFunction(self.SDG) scaling = 1/FacetArea(self.mesh) stress = self.nu*2*sym(grad(velocity)) wss = dot(stress, self.normal) - inner(dot(stress, self.normal), self.normal)*self.normal wss_norm_form = scaling*mS*sqrt_ufl(inner(wss, wss))*ds # ds is integral over exterior facets only assemble(wss_norm_form, tensor=wss_norm.vector()) self.fileDict['wss_norm']['file'].write(wss_norm, self.actual_time) # to get vector WSS values: # NT this works, but in ParaView for (DG,1)-vector space glyphs are displayed in cell centers # wss_vector = [] # for i in range(3): # wss_component = Function(self.SDG) # wss_vector_form = scaling*wss[i]*mS*ds # assemble(wss_vector_form, tensor=wss_component.vector()) # wss_vector.append(wss_component) # wss_func = project(as_vector(wss_vector), self.VDG) # self.fileDict['wss']['file'].write(wss_func, self.actual_time) self.tc.end('WSS') end()
def after_last_compute(self, get): self.mag_ta_wss = get("Magnitude_TimeIntegral_WSS-OSI") self.ta_mag_wss = get("TimeIntegral_Magnitude_WSS-OSI") #print self.name, " Calling after_last_compute" expr = conditional(self.ta_mag_wss < 1e-15, 0.0, 0.5 * (1.0 - self.mag_ta_wss / self.ta_mag_wss)) self.osi.assign(project(expr, self.osi.function_space())) return self.osi
def get_length(vtu_path, mesh): """Get the edgelength from the original mesh""" DG = FunctionSpace(mesh, "DG", 0) # Compute local edgelength h = project(CellSize(mesh), DG) # Compute median, more robust than mean mean = np.median(h.vector().array()) return mean
def save_vel(self, is_tent, field, t): self.vFunction.assign(field) self.fileDict['u2' if is_tent else 'u']['file'] << self.vFunction if self.doSaveDiff: self.vFunction.assign((1.0 / self.vel_normalization_factor[0]) * (field - self.solution)) self.fileDict['u2D' if is_tent else 'uD']['file'] << self.vFunction if self.args.ldsg: # info(div(2.*sym(grad(field))-grad(field)).ufl_shape) form = div(2.*sym(grad(field))-grad(field)) self.pFunction.assign(project(sqrt_ufl(inner(form, form)), self.pSpace)) self.fileDict['ldsg2' if is_tent else 'ldsg']['file'] << self.pFunction
def evaluate_oscillations(f, mesh, degree, dg0, osc_quad_degree = 15): # project f and evaluate oscillations dx = Measure('dx') PV = FunctionSpace(mesh, 'CG', degree) if degree > 0 else FunctionSpace(mesh, 'DG', 0) Pf = project(f, PV) h = CellSize(mesh) osc_form = h**2 * ((f-Pf)**2) * dg0 * dx osc_local = assemble(osc_form, form_compiler_parameters={'quadrature_degree': osc_quad_degree}) osc_global = np.sqrt(np.sum(osc_local.array())) osc_local = [np.sqrt(o) for o in osc_local.array()] return osc_global, osc_local, Pf
def test_dolf_derivatives(self): fsin = self.dolf_sin dfsin = fsin.dx(0) V = dol.FunctionSpace(self.mesh, 'CG', 1) dfsin = dol.project(dfsin, V) npt.assert_allclose(self.np_cos, dfsin.vector().array(), rtol=1e-2, atol=1e-2, \ err_msg="derivative of sin(x) is not cos(x)")
def test_m_001(): theta = np.pi/2 m = df.project(df.Constant((0, 0, 1)), VV) u, j, i = amr(mesh, m, DirichletBoundary, g, mesh2d, s0=1, alpha=1) # Check the potential in the middle of the sample. # The correct solution should be one half of applied potential (0.5). assert abs(u(d/2., d/2., d/2.) - 0.5) < tol # Check electric field. # The electric field magnitude can be computed as U/d where U # is the applied voltage and d is the sample length. # In this case the correct E = (1/d, 0, 0) E = df.project(-df.grad(u), VV) assert abs(E(0.5, 0.5, 0.5)[0] - 1./d) < tol assert abs(E(0.5, 0.5, 0.5)[1] - 0) < tol assert abs(E(0.5, 0.5, 0.5)[2] - 0) < tol # Check current density. # Current density is the conductivity * electric field. rho = 1 + np.cos(theta)**2 assert abs(j(0.5, 0.5, 0.5)[0] - 1./(d*rho)) < tol assert abs(j(0.5, 0.5, 0.5)[1] - 0) < tol assert abs(j(0.5, 0.5, 0.5)[2] - 0) < tol # Check current (current density flux). assert abs(i - d/rho) < tol
def project_onto(self, vec, ptype=None): import spuq.fem.fenics.fenics_vector as FV # this circumvents circular inclusions if ptype is None: ptype = self._ptype if ptype == PROJECTION.INTERPOLATION: # print "fenics_basis::project_onto" # print vec._fefunc.value_size() # print "sub spaces", self.num_sub_spaces # print type(self._fefs) new_fefunc = dolfin.interpolate(vec._fefunc, self._fefs) elif ptype == PROJECTION.L2PROJECTION: new_fefunc = dolfin.project(vec._fefunc, self._fefs) else: raise AttributeError return FV.FEniCSVector(new_fefunc)
def solve(self, it=0): if self.group_GS: self.solve_group_GS(it) else: super(EllipticSNFluxModule, self).solve(it) self.slns_mg = split(self.sln) i,p,q,k1,k2 = ufl.indices(5) sol_timer = Timer("-- Complete solution") aux_timer = Timer("---- SOL: Computing angular flux + adjoint") # TODO: Move to Discretization V11 = FunctionSpace(self.DD.mesh, "CG", self.DD.parameters["p"]) for gto in range(self.DD.G): self.PD.get_xs('D', self.D, gto) form = self.D * ufl.diag_vector(ufl.as_matrix(self.DD.ordinates_matrix[i,p]*self.slns_mg[gto][q].dx(i), (p,q))) for gfrom in range(self.DD.G): pres_Ss = False # TODO: Enlarge self.S and self.C to (L+1)^2 (or 1./2.*(L+1)*(L+2) in 2D) to accomodate for anisotropic # scattering (lines below using CC, SS are correct only for L = 0, when the following inner loop runs only # once. for l in range(self.L+1): for m in range(-l, l+1): if self.DD.angular_quad.get_D() == 2 and divmod(l+m, 2)[1] == 0: continue pres_Ss |= self.PD.get_xs('Ss', self.S[l], gto, gfrom, l) self.PD.get_xs('C', self.C[l], gto, gfrom, l) if pres_Ss: Cd = ufl.diag(self.C) CC = self.tensors.Y[p,k1] * Cd[k1,k2] * self.tensors.Qt[k2,q,i] form += ufl.as_vector(CC[p,q,i] * self.slns_mg[gfrom][q].dx(i), p) # project(form, self.DD.Vpsi1, function=self.aux_slng, preconditioner_type="petsc_amg") # FASTER, but requires form compilation for each dir.: for pp in range(self.DD.M): assign(self.aux_slng.sub(pp), project(form[pp], V11, preconditioner_type="petsc_amg")) self.psi_mg[gto].assign(self.slns_mg[gto] + self.aux_slng) self.adj_psi_mg[gto].assign(self.slns_mg[gto] - self.aux_slng)
def test_linearized_mat_NSE_form(self): """check the conversion: dolfin form <-> numpy arrays and the linearizations""" import dolfin_navier_scipy.dolfin_to_sparrays as dts u = self.fenics_sol_u u.t = 1.0 ufun = dolfin.project(u, self.V) uvec = ufun.vector().get_local().reshape(len(ufun.vector()), 1) N1, N2, fv = dts.get_convmats(u0_dolfun=ufun, V=self.V) conv = dts.get_convvec(u0_dolfun=ufun, V=self.V) self.assertTrue(np.allclose(conv, N1 * uvec)) self.assertTrue(np.allclose(conv, N2 * uvec))
def test_expand_condense_vfuncs(self): """check the expansion of vectors to dolfin funcs """ from dolfin_navier_scipy.dolfin_to_sparrays import expand_vp_dolfunc u = dolfin.Expression(('x[1]', '0'), element=self.V.ufl_element()) ufun = dolfin.project(u, self.V, solver_type='lu') uvec = ufun.vector().get_local().reshape(len(ufun.vector()), 1) # Boundaries def top(x, on_boundary): return x[1] > 1.0 - dolfin.DOLFIN_EPS def leftbotright(x, on_boundary): return (x[0] > 1.0 - dolfin.DOLFIN_EPS or x[1] < dolfin.DOLFIN_EPS or x[0] < dolfin.DOLFIN_EPS) # No-slip boundary condition for velocity noslip = u bc0 = dolfin.DirichletBC(self.V, noslip, leftbotright) # Boundary condition for velocity at the lid lid = u bc1 = dolfin.DirichletBC(self.V, lid, top) # Collect boundary conditions diribcs = [bc0, bc1] bcinds = [] for bc in diribcs: bcdict = bc.get_boundary_values() bcinds.extend(bcdict.keys()) # indices of the innernodes innerinds = np.setdiff1d(range(self.V.dim()), bcinds).astype(np.int32) # take only the inner nodes uvec_condensed = uvec[innerinds, ] v, p = expand_vp_dolfunc(V=self.V, vc=uvec_condensed, invinds=innerinds, diribcs=diribcs) vvec = v.vector().get_local().reshape(len(v.vector()), 1) self.assertTrue(np.allclose(uvec, vvec))
def compute(self, get): # Requires the fields Magnitude(TimeIntegral("WSS", label="OSI")) and # TimeIntegral(Magnitude("WSS"), label="OSI") #self.mag_ta_wss = get("Magnitude_TimeIntegral_WSS_OSI") #self.ta_mag_wss = get("TimeIntegral_Magnitude_WSS_OSI") self.mag_ta_wss = get("Magnitude_TimeIntegral_WSS-OSI") self.ta_mag_wss = get("TimeIntegral_Magnitude_WSS-OSI") if self.params.finalize: return None elif self.mag_ta_wss == None or self.ta_mag_wss == None: return None else: expr = conditional(self.ta_mag_wss < 1e-15, 0.0, 0.5 * (1.0 - self.mag_ta_wss / self.ta_mag_wss)) self.osi.assign(project(expr, self.osi.function_space())) return self.osi
def test_jacobian(self): dolf_j = dol.inner(self.dolf_sin.dx(0), self.dolf_sin.dx(0)) V = dol.FunctionSpace(self.mesh, 'CG', 1) pj = dol.project(dolf_j, V) coeffs = pj.vector().array() dj = np.sqrt(np.sum(coeffs)) nj = np.sqrt(np.dot(self.np_cos,self.np_cos)) f = self.dolf_sin dola = dol.assemble(dol.inner(f,f*dj)*dol.dx) npa = dol.assemble(dol.inner(f,f*nj)*dol.dx) # Again.. not totally close! npt.assert_allclose(dola, npa, rtol=1e-2, atol=1e-2)
def initialize(self, V, Q, PS, D): """ :param V: velocity space :param Q: pressure space :param PS: scalar space of same order as V, used for analytic solution generation :param D: divergence of velocity space """ self.vSpace = V self.divSpace = D self.pSpace = Q self.solutionSpace = V self.vFunction = Function(V) self.divFunction = Function(D) self.pFunction = Function(Q) # self.pgSpace = VectorFunctionSpace(mesh, "DG", 0) # used to save pressure gradient as vectors # self.pgFunction = Function(self.pgSpace) self.initialize_xdmf_files() self.stepsInCycle = self.cycle_length / self.metadata['dt'] info('stepsInCycle = %f' % self.stepsInCycle) if self.args.wss != 'none': self.tc.start('WSSinit') if self.args.wss_method == 'expression': self.T = TensorFunctionSpace(self.mesh, 'Lagrange', 1) info('Generating boundary mesh') self.wall_mesh = BoundaryMesh(self.mesh, 'exterior') self.wall_mesh_oriented = BoundaryMesh(self.mesh, 'exterior', order=False) info(' Boundary mesh geometric dim: %d' % self.wall_mesh.geometry().dim()) info(' Boundary mesh topologic dim: %d' % self.wall_mesh.topology().dim()) self.Tb = TensorFunctionSpace(self.wall_mesh, 'Lagrange', 1) self.Vb = VectorFunctionSpace(self.wall_mesh, 'Lagrange', 1) info('Generating normal to boundary') normal_expr = self.NormalExpression(self.wall_mesh_oriented) Vn = VectorFunctionSpace(self.wall_mesh, 'DG', 0) self.nb = project(normal_expr, Vn) self.Sb = FunctionSpace(self.wall_mesh, 'DG', 0) if self.args.wss_method == 'integral': self.SDG = FunctionSpace(self.mesh, 'DG', 0) self.tc.end('WSSinit')
def amr(mesh, m, DirichletBoundary, g, mesh2d, s0=1, alpha=1): """Function for computing the Anisotropic MagnetoResistance (AMR), using given magnetisation configuration.""" # Scalar and vector function spaces. V = df.FunctionSpace(mesh, "CG", 1) VV = df.VectorFunctionSpace(mesh, 'CG', 1, 3) # Define boundary conditions. bcs = df.DirichletBC(V, g, DirichletBoundary()) # Nonlinear conductivity. def sigma(u): E = -df.grad(u) costheta = df.dot(m, E)/(df.sqrt(df.dot(E, E))*df.sqrt(df.dot(m, m))) return s0/(1 + alpha*costheta**2) # Define variational problem for Picard iteration. u = df.TrialFunction(V) # electric potential v = df.TestFunction(V) u_k = df.interpolate(df.Expression('x[0]'), V) # previous (known) u a = df.inner(sigma(u_k)*df.grad(u), df.grad(v))*df.dx # RHS to mimic linear problem. f = df.Constant(0.0) # set to 0 -> nonlinear Poisson equation. L = f*v*df.dx u = df.Function(V) # new unknown function eps = 1.0 # error measure ||u-u_k|| tol = 1.0e-20 # tolerance iter = 0 # iteration counter maxiter = 50 # maximum number of iterations allowed while eps > tol and iter < maxiter: iter += 1 df.solve(a == L, u, bcs) diff = u.vector().array() - u_k.vector().array() eps = np.linalg.norm(diff, ord=np.Inf) print 'iter=%d: norm=%g' % (iter, eps) u_k.assign(u) # update for next iteration j = df.project(-sigma(u)*df.grad(u), VV) return u, j, compute_flux(j, mesh2d)
def __eval_fexpl(self,u,t): """ Helper routine to evaluate the explicit part of the RHS Args: u: current values (not used here) t: current time Returns: explicit part of RHS """ A = 1.0*self.K b = self.apply_mass_matrix(u) psi = fenics_mesh(self.V) df.solve(A,psi.values.vector(),b.values.vector()) fexpl = fenics_mesh(self.V) fexpl.values = df.project(df.Dx(psi.values,1)*df.Dx(u.values,0) - df.Dx(psi.values,0)*df.Dx(u.values,1),self.V) return fexpl
def rotational(u, n): """ Symmetrize with respect to n-fold symmetry. """ # TODO: test one rotation only V = u.function_space() if V.mesh().topology().dim() > 2 or n < 2: return u mesh = V.mesh() sum = u nrm = np.linalg.norm(u.vector()) rotation = np.array([[np.cos(2*np.pi/n), np.sin(2*np.pi/n)], [-np.sin(2*np.pi/n), np.cos(2*np.pi/n)]]) for i in range(1, n): mesh = Mesh(mesh) mesh.coordinates()[:, :] = np.dot(mesh.coordinates(), rotation) W = FunctionSpace(mesh, 'CG', 1) v = interpolate(Function(W, u.vector()), V) sum += v pr = project(sum) if np.linalg.norm(pr.vector())/nrm > 0.01: return pr else: return u
nz = 10 m = dolfin.UnitCubeMesh(nx,ny,nz) Q = dolfin.FunctionSpace(m,"CG",1) u = dolfin.Function(Q) v = dolfin.Function(Q) w = dolfin.Function(Q) S = dolfin.Function(Q) for L in [5000,10000,20000,40000,80000,160000]: dolfin.File('./results_stokes/'+str(L)+'/u.xml') >> u dolfin.File('./results_stokes/'+str(L)+'/v.xml') >> v dolfin.File('./results_stokes/'+str(L)+'/w.xml') >> w U = pylab.zeros(100) profile = pylab.linspace(0,1,100) for ii,x in enumerate(profile): uu = u(x,0.25,0.99999) vv = v(x,0.25,0.99999) ww = w(x,0.25,0.99999) U[ii] = pylab.sqrt(uu**2 + vv**2) #pylab.plot(profile,U) #data = zip(profile,U) #pickle.dump(data,open("djb1a{0:03d}.p".format(L/1000),'w')) U = dolfin.project(dolfin.as_vector([u,v,w])) dolfin.File('./results_stokes/'+str(L)+'/U.pvd') << U