element=Vh.ufl_element()) true_initial_condition = dl.interpolate(ic_expr, Vh).vector() orderPrior = 2 if orderPrior == 1: gamma = 1 delta = 1e1 prior = LaplacianPrior(Vh, gamma, delta) elif orderPrior == 2: gamma = 1 delta = 8 prior = BiLaplacianPrior(Vh, gamma, delta) # prior.mean = interpolate(Expression('min(0.6,exp(-50*(pow(x[0]-0.34,2) + pow(x[1]-0.71,2))))'), Vh).vector() prior.mean = dl.interpolate(dl.Constant(0.5), Vh).vector() if rank == 0: print( "Prior regularization: (delta - gamma*Laplacian)^order: delta={0}, gamma={1}, order={2}" .format(delta, gamma, orderPrior)) wind_velocity = computeVelocityField(mesh) problem = TimeDependentAD(mesh, [Vh, Vh, Vh], 0., 4., 1., .2, wind_velocity, True, prior) if rank == 0: print(sep, "Generate synthetic observation", sep) rel_noise = 0.001 utrue = problem.generate_vector(STATE) x = [utrue, true_initial_condition, None] problem.solveFwd(x[STATE], x, 1e-9)
def __init__(self, Vh): test = dl.TestFunction(Vh[STATE]) f = dl.Constant(1.0) self.f = dl.assemble(f * test * dl.dx)
def __init__(self, turbine, flow): # add radius to model params if model_parameters is None: model_parameters = {"radius": turbine_radius} else: model_parameters.update({"radius": turbine_radius}) # check if gradient required if "compute_gradient" in model_parameters: compute_gradient = model_parameters["compute_gradient"] else: compute_gradient = True # check if a wake and wake gradients are provided if "wake" in model_parameters: if "wake_gradients" in model_parameters: gradients = model_parameters["wake_gradients"] else: gradients = None self.wake = ADDolfinExpression(model_parameters["wake"], compute_gradient=compute_gradient, gradients=gradients) # compute wake and gradients else: # mimic a SteadyConfiguration but change a few things along the way config = otf.DefaultConfiguration() config.params['steady_state'] = True config.params[ 'initial_condition'] = otf.ConstantFlowInitialCondition(config) config.params['include_advection'] = True config.params['include_diffusion'] = True config.params['diffusion_coef'] = 3.0 config.params['quadratic_friction'] = True config.params['newton_solver'] = True config.params['friction'] = dolfin.Constant(0.0025) config.params['theta'] = 1.0 config.params["dump_period"] = 0 xmin, ymin = -100, -200 xsize, ysize = 1000, 400 xcells, ycells = 400, 160 mesh = dolfin.RectangleMesh(xmin, ymin, xmin + xsize, ymin + ysize, xcells, ycells) V, H = config.finite_element(mesh) config.function_space = dolfin.MixedFunctionSpace([V, H]) config.turbine_function_space = dolfin.FunctionSpace(mesh, 'CG', 2) class Domain(object): """ Domain object used for setting boundary conditions etc later on """ def __init__(self, mesh): class InFlow(dolfin.SubDomain): def inside(self, x, on_boundary): return dolfin.near(x[0], -100) class OutFlow(dolfin.SubDomain): def inside(self, x, on_boundary): return dolfin.near(x[0], 900) inflow = InFlow() outflow = OutFlow() self.mesh = mesh self.boundaries = dolfin.FacetFunction("size_t", mesh) self.boundaries.set_all(0) inflow.mark(self.boundaries, 1) outflow.mark(self.boundaries, 2) self.ds = dolfin.Measure('ds')[self.boundaries] config.domain = Domain(mesh) config.set_domain(config.domain, warning=False) # Boundary conditions bc = otf.DirichletBCSet(config) bc.add_constant_flow(1, 1.0 + 1e-10) bc.add_zero_eta(2) config.params['bctype'] = 'strong_dirichlet' config.params['strong_bc'] = bc config.params['free_slip_on_sides'] = True # Optimisation settings config.params['functional_final_time_only'] = True config.params['automatic_scaling'] = False # Turbine settings config.params['turbine_pos'] = [] config.params['turbine_friction'] = [] config.params['turbine_x'] = turbine_radius * 2 config.params['turbine_y'] = turbine_radius * 2 config.params['controls'] = ['turbine_pos'] # Finally set some DOLFIN optimisation flags dolfin.parameters['form_compiler']['cpp_optimize'] = True dolfin.parameters['form_compiler']['cpp_optimize_flags'] = '-O3' dolfin.parameters['form_compiler']['optimize'] = True # place a turbine with default friction turbine = [(0., 0.)] config.set_turbine_pos(turbine) # solve the shallow water equations rf = otf.ReducedFunctional(config, plot=False) dolfin.info_blue("Generating the wake model...") rf.j(rf.initial_control()) # get state state = rf.last_state V = dolfin.VectorFunctionSpace(config.function_space.mesh(), "CG", 2, dim=2) u_out = dolfin.TrialFunction(V) v_out = dolfin.TestFunction(V) M_out = dolfin_adjoint.assemble( dolfin.inner(v_out, u_out) * dolfin.dx) out_state = dolfin.Function(V) rhs = dolfin_adjoint.assemble( dolfin.inner(v_out, state.split()[0]) * dolfin.dx) dolfin_adjoint.solve(M_out, out_state.vector(), rhs, "cg", "sor", annotate=False) dolfin.info_green("Wake model generated.") self.wake = ADDolfinExpression(out_state.split()[0], compute_gradient) super(ApproximateShallowWater, self).__init__("ApproximateShallowWater", flow_field, model_parameters)
init_mode="random", alpha=0.0, ) cmd_kwargs = parse_command_line() parameters.update(**cmd_kwargs) if parameters["restart_folder"]: load_parameters( parameters, os.path.join(parameters["restart_folder"], "parameters.dat")) parameters.update(**cmd_kwargs) R = parameters["R"] Rz = parameters["Rz"] res = parameters["res"] dt = TimeStepSelector(parameters["dt"]) tau = df.Constant(parameters["tau"]) h = df.Constant(parameters["h"]) M = df.Constant(parameters["M"]) #geo_map = EllipsoidMap(R, R, Rz) geo_map = CylinderMap(R, 2 * np.pi * R) geo_map.initialize(res, restart_folder=parameters["restart_folder"]) W = geo_map.mixed_space(4) # Define trial and test functions du = df.TrialFunction(W) chi, xi, eta, etahat = df.TestFunctions(W) # Define functions
def eta_v(s): return df.Constant(b)/2.*(1./Lmid**2*(u.dx(s,0) + u.ds(s)*dsdx(s))**2 \ +0.25*((u.ds(s)*dsdz(s))**2) \ + eps_reg)**((1.-n)/(2*n))
from mpi4py import MPI comm = MPI.COMM_WORLD rank = comm.Get_rank() size = comm.Get_size() print("Hello World from {}/{}".format(rank, size)) import dolfin as df #df.parameters.reorder_dofs_serial = False nx = ny = 10 mesh = df.RectangleMesh(df.Point(0, 0), df.Point(1, 1), nx, ny) V = df.VectorFunctionSpace(mesh, 'CG', 1, dim=3) vector_value_constant = df.Constant(list([0, 1, 2])) our_function = df.interpolate(vector_value_constant, V) print("{}: My vector is of shape {}.".format( rank, our_function.vector().array().shape)) print(our_function.vector().array())
quad_scheme="default") fiber_space = dolfin.FunctionSpace(mesh, fiber_element) fiber = dolfin.Function(fiber_space, "data/fiber.xml") microstructure = pulse.Microstructure(f0=fiber) # Create the geometry geometry = pulse.HeartGeometry( mesh=mesh, markers=markers, marker_functions=marker_functions, microstructure=microstructure, ) activation = dolfin.Function(dolfin.FunctionSpace(geometry.mesh, "R", 0)) activation.assign(dolfin.Constant(0.2)) matparams = pulse.HolzapfelOgden.default_parameters() material = pulse.HolzapfelOgden(activation=activation, parameters=matparams, f0=geometry.f0) # LV Pressure lvp = dolfin.Constant(1.0) lv_marker = markers_dict["ENDO"][0] lv_pressure = pulse.NeumannBC(traction=lvp, marker=lv_marker, name="lv") neumann_bc = [lv_pressure] # Add spring term at the base with stiffness 1.0 kPa/cm^2 base_spring = 1.0 robin_bc = [ pulse.RobinBC(value=dolfin.Constant(base_spring),
def mass_lumps_rowsum_petsc(me): if me._mass_lumps_rowsum_petsc is None: me._mass_lumps_rowsum_petsc = dl.assemble( dl.Constant(1.0) * me.test_function * dl.dx) return me._mass_lumps_rowsum_petsc
def setup_scalar_equation(self): sim = self.simulation V = sim.data['Vphi'] mesh = V.mesh() P = V.ufl_element().degree() # Source term source_cpp = sim.input.get_value('solver/source', '0', 'string') f = dolfin.Expression(source_cpp, degree=P) # Create the solution function sim.data['phi'] = dolfin.Function(V) # DG elliptic penalty penalty = define_penalty(mesh, P, k_min=1.0, k_max=1.0) penalty_dS = dolfin.Constant(penalty) penalty_ds = dolfin.Constant(penalty * 2) yh = dolfin.Constant(1 / (penalty * 2)) # Define weak form u, v = dolfin.TrialFunction(V), dolfin.TestFunction(V) a = dot(grad(u), grad(v)) * dx L = f * v * dx # Symmetric Interior Penalty method for -∇⋅∇φ n = dolfin.FacetNormal(mesh) a -= dot(n('+'), avg(grad(u))) * jump(v) * dS a -= dot(n('+'), avg(grad(v))) * jump(u) * dS # Symmetric Interior Penalty coercivity term a += penalty_dS * jump(u) * jump(v) * dS # Dirichlet boundary conditions # Nitsche's (1971) method, see e.g. Epshteyn and Rivière (2007) dirichlet_bcs = sim.data['dirichlet_bcs'].get('phi', []) for dbc in dirichlet_bcs: bcval, dds = dbc.func(), dbc.ds() # SIPG for -∇⋅∇φ a -= dot(n, grad(u)) * v * dds a -= dot(n, grad(v)) * u * dds L -= dot(n, grad(v)) * bcval * dds # Weak Dirichlet a += penalty_ds * u * v * dds L += penalty_ds * bcval * v * dds # Neumann boundary conditions neumann_bcs = sim.data['neumann_bcs'].get('phi', []) for nbc in neumann_bcs: L += nbc.func() * v * nbc.ds() # Robin boundary conditions # See Juntunen and Stenberg (2009) # n⋅∇φ = (φ0 - φ)/b + g robin_bcs = sim.data['robin_bcs'].get('phi', []) for rbc in robin_bcs: b, rds = rbc.blend(), rbc.ds() dval, nval = rbc.dfunc(), rbc.nfunc() # From IBP of the main equation a -= dot(n, grad(u)) * v * rds # Test functions for the Robin BC z1 = 1 / (b + yh) * v z2 = -yh / (b + yh) * dot(n, grad(v)) # Robin BC added twice with different test functions for z in [z1, z2]: a += b * dot(n, grad(u)) * z * rds a += u * z * rds L += dval * z * rds L += b * nval * z * rds # Does the system have a null-space? self.has_null_space = len(dirichlet_bcs) + len(robin_bcs) == 0 self.form_lhs = a self.form_rhs = L
'incompressible': args.incompressible, 'density': 10.0 } if args.material in ['fung', 'guccione']: if args.material == 'fung': material_dict['d'] = [10.0] * 3 + [0.0] * 3 + [5.0] * 3 else: material_dict['bt'] = 10.0 material_dict['bf'] = 1.0 material_dict['bfs'] = 5.0 from numpy import sqrt material_dict['C'] = 20.0 material_dict['kappa'] = 1e4 if args.dim == 2: e1 = dlf.Constant([1.0 / sqrt(2.0)] * 2) e2 = dlf.Constant([1.0 / sqrt(2.0), -1.0 / sqrt(2.0)]) else: e1 = dlf.Constant([1.0 / sqrt(2.0)] * 2 + [0.0]) e2 = dlf.Constant([1.0 / sqrt(2.0), -1.0 / sqrt(2.0), 0.0]) material_dict['fibers'] = { 'fiber_files': [e1, e2], 'fiber_names': ['e1', 'e2'], 'element': None } else: material_dict.update({'inv_la': inv_la, 'mu': mu}) # Mesh subdictionary mesh_dict = {'mesh_file': mesh_file, 'boundaries': boundaries}
import dolfin as df import time mesh = df.UnitSquareMesh(200, 200) print mesh S1 = df.FunctionSpace(mesh, 'CG', 1) S3 = df.VectorFunctionSpace(mesh, 'CG', 1, 3) u = df.TrialFunction(S3) v = df.TestFunction(S3) m = df.Function(S3) # magnetisation Heff = df.Function(S3) # effective field Ms = df.Function(S1) # saturation magnetisation alpha = df.Function(S1) # damping gamma = df.Constant(1) # gyromagnetic ratio m.assign(df.Constant((1, 0, 0))) Heff.assign(df.Constant((0, 0, 1))) alpha.assign(df.Constant(1)) Ms.assign(df.Constant(1)) # just assembling it LLG = -gamma / (1 + alpha * alpha) * df.cross(m, Heff) - alpha * gamma / ( 1 + alpha * alpha) * df.cross(m, df.cross(m, Heff)) L = df.dot(LLG, df.TestFunction(S3)) * df.dP dmdt = df.Function(S3) start = time.time() for i in xrange(1000): df.assemble(L, tensor=dmdt.vector()) stop = time.time()
import matplotlib matplotlib.use('TkAgg') import matplotlib.pyplot as plt import dolfin import pulse from problem import Problem from force import ca_transient # pulse.parameters['log_level'] = dolfin.WARNING geometry = pulse.HeartGeometry.from_file(pulse.mesh_paths['simple_ellipsoid']) # Scale mesh to fit Windkessel parameters geometry.mesh.coordinates()[:] *= 2.4 activation = dolfin.Constant(0.0) matparams = pulse.Guccione.default_parameters() material = pulse.Guccione(activation=activation, parameters=matparams) # Add spring term at the base with stiffness 1.0 kPa/cm^2 base_spring = 1.0 robin_bc = [pulse.RobinBC(value=dolfin.Constant(base_spring), marker=geometry.markers["BASE"][0])] # Fix the basal plane in the longitudinal direction # 0 in V.sub(0) refers to x-direction, which is the longitudinal direction def fix_basal_plane(W): V = W if W.sub(0).num_sub_spaces() == 0 else W.sub(0)
def apex_to_base( mesh: df.Mesh, base_marker: int, ffun: df.MeshFunction, use_krylov_solver: bool = False, krylov_solver_atol: Optional[float] = None, krylov_solver_rtol: Optional[float] = None, krylov_solver_max_its: Optional[int] = None, verbose: bool = False, ): """ Find the apex coordinate and compute the laplace equation to find the apex to base solution Arguments --------- mesh : dolfin.Mesh The mesh base_marker : int The marker value for the basal facets ffun : dolfin.MeshFunctionSizet (optional) A facet function containing markers for the boundaries. If not provided, the markers stored within the mesh will be used. use_krylov_solver: bool If True use Krylov solver, by default False krylov_solver_atol: float (optional) If a Krylov solver is used, this option specifies a convergence criterion in terms of the absolute residual. Default: 1e-15. krylov_solver_rtol: float (optional) If a Krylov solver is used, this option specifies a convergence criterion in terms of the relative residual. Default: 1e-10. krylov_solver_max_its: int (optional) If a Krylov solver is used, this option specifies the maximum number of iterations to perform. Default: 10000. verbose: bool If true, print more info, by default False """ # Find apex by solving a laplacian with base solution = 0 # Create Base variational problem V = df.FunctionSpace(mesh, "CG", 1) u = df.TrialFunction(V) v = df.TestFunction(V) a = df.dot(df.grad(u), df.grad(v)) * df.dx L = v * df.Constant(1) * df.dx apex = df.Function(V) base_bc = df.DirichletBC(V, 1, ffun, base_marker, "topological") # Solver options solver = solve_system( a, L, base_bc, apex, solver_parameters={ "linear_solver": "cg", "preconditioner": "amg" }, use_krylov_solver=use_krylov_solver, krylov_solver_atol=krylov_solver_atol, krylov_solver_rtol=krylov_solver_rtol, krylov_solver_max_its=krylov_solver_max_its, verbose=verbose, ) if utils.DOLFIN_VERSION_MAJOR < 2018: dof_x = utils.gather_broadcast(V.tabulate_dof_coordinates()).reshape( (-1, 3)) apex_values = utils.gather_broadcast(apex.vector().get_local()) ind = apex_values.argmax() apex_coord = dof_x[ind] else: dof_x = V.tabulate_dof_coordinates() apex_values = apex.vector().get_local() local_max_val = apex_values.max() local_apex_coord = dof_x[apex_values.argmax()] comm = utils.mpi_comm_world() from mpi4py import MPI global_max, apex_coord = comm.allreduce( sendobj=(local_max_val, local_apex_coord), op=MPI.MAXLOC, ) df.info(" Apex coord: ({0:.2f}, {1:.2f}, {2:.2f})".format(*apex_coord)) # Update rhs L = v * df.Constant(0) * df.dx apex_domain = df.CompiledSubDomain( "near(x[0], {0}) && near(x[1], {1}) && near(x[2], {2})".format( *apex_coord), ) apex_bc = df.DirichletBC(V, 0, apex_domain, "pointwise") # Solve the poisson equation bcs = [base_bc, apex_bc] if solver is not None: # Reuse existing solver A, b = df.assemble_system(a, L, bcs) solver.set_operator(A) solver.solve(apex.vector(), b) else: solve_system( a, L, bcs, apex, use_krylov_solver=use_krylov_solver, krylov_solver_atol=krylov_solver_atol, krylov_solver_rtol=krylov_solver_rtol, krylov_solver_max_its=krylov_solver_max_its, solver_parameters={"linear_solver": "gmres"}, verbose=verbose, ) return apex
def __init__(self, mesh, Vh, t_init, t_final, t_1, dt, wind_velocity, gls_stab, Prior): self.mesh = mesh self.Vh = Vh self.t_init = t_init self.t_final = t_final self.t_1 = t_1 self.dt = dt self.sim_times = np.arange(self.t_init, self.t_final + .5 * self.dt, self.dt) u = dl.TrialFunction(Vh[STATE]) v = dl.TestFunction(Vh[STATE]) kappa = dl.Constant(.001) dt_expr = dl.Constant(self.dt) r_trial = u + dt_expr * (-dl.div(kappa * dl.nabla_grad(u)) + dl.inner(wind_velocity, dl.nabla_grad(u))) r_test = v + dt_expr * (-dl.div(kappa * dl.nabla_grad(v)) + dl.inner(wind_velocity, dl.nabla_grad(v))) h = dl.CellSize(mesh) vnorm = dl.sqrt(dl.inner(wind_velocity, wind_velocity)) if gls_stab: tau = dl.Min((h * h) / (dl.Constant(2.) * kappa), h / vnorm) else: tau = dl.Constant(0.) self.M = dl.assemble(dl.inner(u, v) * dl.dx) self.M_stab = dl.assemble(dl.inner(u, v + tau * r_test) * dl.dx) self.Mt_stab = dl.assemble(dl.inner(u + tau * r_trial, v) * dl.dx) Nvarf = (dl.inner(kappa * dl.nabla_grad(u), dl.nabla_grad(v)) + dl.inner(wind_velocity, dl.nabla_grad(u)) * v) * dl.dx Ntvarf = (dl.inner(kappa * dl.nabla_grad(v), dl.nabla_grad(u)) + dl.inner(wind_velocity, dl.nabla_grad(v)) * u) * dl.dx self.N = dl.assemble(Nvarf) self.Nt = dl.assemble(Ntvarf) stab = dl.assemble(tau * dl.inner(r_trial, r_test) * dl.dx) self.L = self.M + dt * self.N + stab self.Lt = self.M + dt * self.Nt + stab boundaries = dl.FacetFunction("size_t", mesh) boundaries.set_all(0) class InsideBoundary(dl.SubDomain): def inside(self, x, on_boundary): x_in = x[0] > dl.DOLFIN_EPS and x[0] < 1 - dl.DOLFIN_EPS y_in = x[1] > dl.DOLFIN_EPS and x[1] < 1 - dl.DOLFIN_EPS return on_boundary and x_in and y_in Gamma_M = InsideBoundary() Gamma_M.mark(boundaries, 1) ds_marked = dl.Measure("ds", subdomain_data=boundaries) self.Q = dl.assemble(self.dt * dl.inner(u, v) * ds_marked(1)) self.Prior = Prior if dlversion() <= (1, 6, 0): self.solver = dl.PETScLUSolver() else: self.solver = dl.PETScLUSolver(self.mesh.mpi_comm()) self.solver.set_operator(self.L) if dlversion() <= (1, 6, 0): self.solvert = dl.PETScLUSolver() else: self.solvert = dl.PETScLUSolver(self.mesh.mpi_comm()) self.solvert.set_operator(self.Lt) self.ud = self.generate_vector(STATE) self.noise_variance = 0 # Part of model public API self.gauss_newton_approx = False
def set_potential(self, potential): if self.floating and potential != 0: potential=0 print("Potential cannot be set when using floating") self._potential = potential self.set_value(df.Constant(self._potential))
class Bottom(df.SubDomain): def inside(self, x, on_boundary): return df.near(x[1], 0.0) and on_boundary boundaries = df.MeshFunction("size_t", mesh, mesh.topology().dim()-1) boundaries.set_all(0) right = Right() top = Top() bottom = Bottom() right.mark(boundaries, 1) top.mark(boundaries, 2) bottom.mark(boundaries, 3) # Define Dirichlet boundary conditions zero = df.Constant(0.0) vzero = df.Constant((0.0, 0.0, 0.0)) dt = params.params["dt"] squeeze = df.Expression("-1e-2*t", t=0.0, degree=1) pprob.add_solid_dirichlet_condition(vzero, boundaries, 1) # pprob.add_solid_dirichlet_condition(squeeze, boundaries, 2, n=1, time=True) pprob.add_solid_dirichlet_condition(vzero, boundaries, 3) def set_xdmf_parameters(f): f.parameters['flush_output'] = True f.parameters['functions_share_mesh'] = True f.parameters['rewrite_function_mesh'] = False # Files for output f1 = df.XDMFFile(comm, '../data/demo_unitcube/uf.xdmf')
def _discretize_fenics(): # assemble system matrices - FEniCS code ######################################## import dolfin as df mesh = df.UnitSquareMesh(GRID_INTERVALS, GRID_INTERVALS, 'crossed') V = df.FunctionSpace(mesh, 'Lagrange', FENICS_ORDER) u = df.TrialFunction(V) v = df.TestFunction(V) diffusion = df.Expression('(lower0 <= x[0]) * (open0 ? (x[0] < upper0) : (x[0] <= upper0)) *' '(lower1 <= x[1]) * (open1 ? (x[1] < upper1) : (x[1] <= upper1))', lower0=0., upper0=0., open0=0, lower1=0., upper1=0., open1=0, element=df.FunctionSpace(mesh, 'DG', 0).ufl_element()) def assemble_matrix(x, y, nx, ny): diffusion.user_parameters['lower0'] = x/nx diffusion.user_parameters['lower1'] = y/ny diffusion.user_parameters['upper0'] = (x + 1)/nx diffusion.user_parameters['upper1'] = (y + 1)/ny diffusion.user_parameters['open0'] = (x + 1 == nx) diffusion.user_parameters['open1'] = (y + 1 == ny) return df.assemble(df.inner(diffusion * df.nabla_grad(u), df.nabla_grad(v)) * df.dx) mats = [assemble_matrix(x, y, XBLOCKS, YBLOCKS) for x in range(XBLOCKS) for y in range(YBLOCKS)] mat0 = mats[0].copy() mat0.zero() h1_mat = df.assemble(df.inner(df.nabla_grad(u), df.nabla_grad(v)) * df.dx) f = df.Constant(1.) * v * df.dx F = df.assemble(f) bc = df.DirichletBC(V, 0., df.DomainBoundary()) for m in mats: bc.zero(m) bc.apply(mat0) bc.apply(h1_mat) bc.apply(F) # wrap everything as a pyMOR model ################################## # FEniCS wrappers from pymor.bindings.fenics import FenicsVectorSpace, FenicsMatrixOperator, FenicsVisualizer # define parameter functionals (same as in pymor.analyticalproblems.thermalblock) parameter_functionals = [ProjectionParameterFunctional('diffusion', size=YBLOCKS*XBLOCKS, index=YBLOCKS - y - 1 + x*YBLOCKS) for x in range(XBLOCKS) for y in range(YBLOCKS)] # wrap operators ops = [FenicsMatrixOperator(mat0, V, V)] + [FenicsMatrixOperator(m, V, V) for m in mats] op = LincombOperator(ops, [1.] + parameter_functionals) rhs = VectorOperator(FenicsVectorSpace(V).make_array([F])) h1_product = FenicsMatrixOperator(h1_mat, V, V, name='h1_0_semi') # build model visualizer = FenicsVisualizer(FenicsVectorSpace(V)) fom = StationaryModel(op, rhs, products={'h1_0_semi': h1_product}, visualizer=visualizer) return fom
def test_forms(scheme, N, dim, th, plotter): model, DS, bcs = prepare_model_and_bcs(scheme, N, dim, th) prm = model.parameters["sigma"] prm.add("12", 4.0) if N == 3: prm.add("13", 2.0) prm.add("23", 1.0) for key in ["rho", "nu"]: prm = model.parameters[key] prm.add("1", 42.) prm.add("2", 4.0) if N == 3: prm.add("3", 1.0) #dolfin.info(model.parameters, True) # Check that bcs were recorded correctly bcs_ret = model.bcs() assert id(bcs_ret) == id(bcs) # Create forms with pytest.raises(RuntimeError): model.update_TD_factors(1) forms = model.create_forms() # Check interpolated quantities itype = { "Monolithic": "lin", #"SemiDecoupled": "sin", "SemiDecoupled": "odd", "FullyDecoupled": "log" } if N == 2: pv = DS.primitive_vars_ctl(indexed=True) model.parameters["rho"]["itype"] = itype[scheme] rho_mat = model.collect_material_params("rho") rho = model.density(rho_mat, pv["phi"]) phi_ic = prepare_initial_condition(DS) r = dolfin.project(rho, phi_ic.function_space()) prm = model.parameters tol = 1e-3 p1, p2 = dolfin.Point(0.5, 0.01), dolfin.Point(0.5, 0.99) BBT = DS.mesh().bounding_box_tree() if BBT.collides(p1): assert dolfin.near(r(0.5, 0.01), prm["rho"]["1"], tol) if BBT.collides(p2): assert dolfin.near(r(0.5, 0.99), prm["rho"]["2"], tol) del prm, tol # Visual check (uncomment also 'pyplot.show()' in the finalizer below) #pyplot.figure(); dolfin.plot(r, mode="warp", title=itype[scheme]) # Update order of time discretization if scheme in ["Monolithic", "SemiDecoupled"]: model.update_TD_factors(2) flag = False for c in forms["nln"].coefficients(): if c.name() == "TD_theta": flag = True assert float(c) == 0.5 assert flag else: model.update_TD_factors(2) flag = False for c in forms["lin"]["lhs"][0].coefficients(): if c.name() == "TD_gamma0": flag = True assert float(c) == 1.5 assert flag # Check assembly of returned forms if scheme == "Monolithic": assert forms["lin"] is None F = forms["nln"] r = dolfin.assemble(F) elif scheme == "FullyDecoupled": assert forms["nln"] is None bforms = forms["lin"] for a, L in zip(bforms["lhs"], bforms["rhs"]): A, b = dolfin.assemble_system(a, L) # Test variable time step dt = 42 model.update_time_step_value(dt) assert dt == model.time_step_value() if scheme in ["Monolithic", "FullyDecoupled"]: F = forms["nln"] \ if scheme == "Monolithic" else forms["lin"]["lhs"][0] flag = False for c in F.coefficients(): if c.name() == "dt": flag = True a = dolfin.Constant(c) # for correct evaluation in parallel assert dt == a(0) # Constant can be evaluated anywhere, # independently of the mesh assert flag
def top(x): return np.abs(x[0] - width / 2) < dolfin.DOLFIN_EPS def bottom(x): return np.abs(x[0] + width / 2) < dolfin.DOLFIN_EPS print('ugly stuff took {:.2f} s'.format(time.time() - t_ini)) nodal_space = dolfin.FunctionSpace(mesh, 'Lagrange', 1) (L_i, ) = dolfin.TestFunctions(nodal_space) (L_j, ) = dolfin.TrialFunctions(nodal_space) bc_ground = dolfin.DirichletBC(nodal_space, dolfin.Constant(0.0), markers, other) bc_source = dolfin.DirichletBC(nodal_space, dolfin.Constant(1.0), markers, metal) rho = dolfin.Constant(0.0) A_ij = dolfin.inner(dolfin.grad(L_i), dolfin.grad(L_j)) * dolfin.dx b_ij = rho * L_j * dolfin.dx A = dolfin.assemble(A_ij) b = dolfin.assemble(b_ij) bc_ground.apply(A, b) bc_source.apply(A, b) phi = dolfin.Function(nodal_space) c = phi.vector() print('before solve took {:.2f} s'.format(time.time() - t_ini)) t_ini = time.time()
def run_and_calculate_error(N, dt, tmax, polydeg_u, polydeg_p, modifier=None): """ Run Ocellaris and return L2 & H1 errors in the last time step """ say(N, dt, tmax, polydeg_u, polydeg_p) # Setup and run simulation sim = Simulation() sim.input.read_yaml('kovasznay.inp') sim.input.set_value('mesh/Nx', N) sim.input.set_value('mesh/Ny', N) sim.input.set_value('time/dt', dt) sim.input.set_value('time/tmax', tmax) sim.input.set_value('solver/polynomial_degree_velocity', polydeg_u) sim.input.set_value('solver/polynomial_degree_pressure', polydeg_p) sim.input.set_value('output/stdout_enabled', False) if modifier: modifier(sim) # Running regression tests, modify some input params say('Running ...') try: t1 = time.time() setup_simulation(sim) run_simulation(sim) duration = time.time() - t1 except KeyboardInterrupt: raise except BaseException as e: raise import traceback traceback.print_exc() return [1e10] * 6 + [1, dt, time.time() - t1] say('DONE') tmax_warning = ' <------ NON CONVERGENCE!!' if sim.time > tmax - dt / 2 else '' # Interpolate the analytical solution to the same function space Vu = sim.data['Vu'] Vp = sim.data['Vp'] lambda_ = sim.input.get_value('user_code/constants/LAMBDA', required_type='float') u0e = dolfin.Expression( sim.input.get_value('boundary_conditions/0/u/cpp_code/0'), LAMBDA=lambda_, degree=polydeg_u) u1e = dolfin.Expression( sim.input.get_value('boundary_conditions/0/u/cpp_code/1'), LAMBDA=lambda_, degree=polydeg_u) pe = dolfin.Expression( '-0.5*exp(LAMBDA*2*x[0]) + 1/(4*LAMBDA)*(exp(2*LAMBDA) - 1.0)', LAMBDA=lambda_, degree=polydeg_p, ) u0a = dolfin.project(u0e, Vu) u1a = dolfin.project(u1e, Vu) pa = dolfin.project(pe, Vp) # Correct pa (we want to be spot on, not close) int_pa = dolfin.assemble(pa * dolfin.dx) vol = dolfin.assemble(dolfin.Constant(1.0) * dolfin.dx(domain=Vp.mesh())) pa.vector()[:] -= int_pa / vol # Calculate L2 errors err_u0 = calc_err(sim.data['u0'], u0a) err_u1 = calc_err(sim.data['u1'], u1a) err_p = calc_err(sim.data['p'], pa) # Calculate H1 errors err_u0_H1 = calc_err(sim.data['u0'], u0a, 'H1') err_u1_H1 = calc_err(sim.data['u1'], u1a, 'H1') err_p_H1 = calc_err(sim.data['p'], pa, 'H1') say('Number of time steps:', sim.timestep, tmax_warning) loglines = sim.log.get_full_log().split('\n') say('Num inner iterations:', sum(1 if 'Inner iteration' in line else 0 for line in loglines)) say('max(ui_new-ui_prev)', sim.reporting.get_report('max(ui_new-ui_prev)')[1][-1]) int_p = dolfin.assemble(sim.data['p'] * dolfin.dx) say('p*dx', int_p) say('pa*dx', dolfin.assemble(pa * dolfin.dx(domain=Vp.mesh()))) div_u_Vp = abs( dolfin.project(dolfin.div(sim.data['u']), Vp).vector().get_local()).max() say('div(u)|Vp', div_u_Vp) div_u_Vu = abs( dolfin.project(dolfin.div(sim.data['u']), Vu).vector().get_local()).max() say('div(u)|Vu', div_u_Vu) Vdg0 = dolfin.FunctionSpace(sim.data['mesh'], "DG", 0) div_u_DG0 = abs( dolfin.project(dolfin.div(sim.data['u']), Vdg0).vector().get_local()).max() say('div(u)|DG0', div_u_DG0) Vdg1 = dolfin.FunctionSpace(sim.data['mesh'], "DG", 1) div_u_DG1 = abs( dolfin.project(dolfin.div(sim.data['u']), Vdg1).vector().get_local()).max() say('div(u)|DG1', div_u_DG1) if False: # Plot the results for fa, name in ((u0a, 'u0'), (u1a, 'u1'), (pa, 'p')): p1 = dolfin.plot(sim.data[name] - fa, title='%s_diff' % name, key='%s_diff' % name) p2 = dolfin.plot(fa, title=name + ' analytical', key=name) p1.write_png('%g_%g_%s_diff' % (N, dt, name)) p2.write_png('%g_%g_%s' % (N, dt, name)) dolfin.interactive() from numpy import argmax for d in range(2): up = sim.data['up%d' % d] upp = sim.data['upp%d' % d] V = up.function_space() coords = V.tabulate_dof_coordinates().reshape((-1, 2)) up.vector()[:] -= upp.vector() diff = abs(up.vector().get_local()) i = argmax(diff) say('Max difference in %d direction is %.4e at %r' % (d, diff[i], coords[i])) if 'uppp%d' % d in sim.data: uppp = sim.data['uppp%d' % d] upp.vector()[:] -= uppp.vector() diffp = abs(upp.vector().get_local()) ip = argmax(diffp) say('Prev max diff. in %d direction is %.4e at %r' % (d, diffp[ip], coords[ip])) if False and N == 24: # dolfin.plot(sim.data['u0'], title='u0') # dolfin.plot(sim.data['u1'], title='u1') # dolfin.plot(sim.data['p'], title='p') # dolfin.plot(u0a, title='u0a') # dolfin.plot(u1a, title='u1a') # dolfin.plot(pa, title='pa') plot_err(sim.data['u0'], u0a, title='u0a - u0') plot_err(sim.data['u1'], u1a, title='u1a - u1') plot_err(sim.data['p'], pa, 'pa - p') # plot_err(sim.data['u0'], u0a, title='u0a - u0') dolfin.plot(sim.data['up0'], title='up0 - upp0') dolfin.plot(sim.data['upp0'], title='upp0 - uppp0') # plot_err(sim.data['u1'], u1a, title='u1a - u1') dolfin.plot(sim.data['up1'], title='up1 - upp1') # dolfin.plot(sim.data['upp1'], title='upp1 - uppp1') hmin = sim.data['mesh'].hmin() return err_u0, err_u1, err_p, err_u0_H1, err_u1_H1, err_p_H1, hmin, dt, duration
def fix_basal_plane(W): V = W if W.sub(0).num_sub_spaces() == 0 else W.sub(0) bc = dolfin.DirichletBC(V.sub(0), dolfin.Constant(0.0), geometry.ffun, markers_dict["BASE"][0]) return bc
# Initialize sub-domain instances. # left = Left() right = Right() top = Top() bottom = Bottom() # # Next, we initialize the mesh function for boundary domains in sub-domains. # left.mark(boundaries, 1) right.mark(boundaries, 2) top.mark(boundaries, 3) bottom.mark(boundaries, 4) # # Define Dirichlet boundary conditions for solid, allows for focusing on fluid problem comparable to darcy flow zero = df.Constant((0, 0)) # Dirichlet BC were set according a simulation without boundary conditions. # For time independency of boundary conditions set kwargs time=False # no definition of paramtere 'Source' needed since one compartment (N=1) zero = df.Constant(0.0) start = df.Constant(2.6) end = df.Constant(2.6) fprob.add_fluid_dirichlet_condition(start, boundaries, 1, time=False) fprob.add_fluid_dirichlet_condition(end, boundaries, 2, time=False) # def set_xdmf_parameters(f): f.parameters['flush_output'] = True f.parameters['functions_share_mesh'] = True
# Split vector functions into scalar components ubar, udef, H_c, H, L = df.split(U) phibar, phidef, xsi_c, xsi, chi = df.split(Phi) # Values of model variables at previous time step un = df.Function(Q) u2n = df.Function(Q) H0_c = df.Function(Q) H0 = df.Function(Q_dg) L0 = df.Function(Q_R) Bhat = df.Function(Q) # The bed topography beta2 = df.Function(Q) # The basal traction adot = df.Function(Q) # The surface mass balance l = softplus(df.Constant(0), Bhat) # Water surface, or the greater of # bedrock topography or zero B = softplus(Bhat, -rho / rho_w * H_c, alpha=0.2) # Ice base is the greater of the # bedrock topography or the base of # the shelf D = softplus(-Bhat, df.Constant(0)) # Water depth S = B + H_c # Ice surface = Ice base + thickness #################################################### ############ FUNCTION INITIALIZATION ############# #################################################### # Initialize thickness and length to reasonable values. It is particularly
T = dolfin.PETScMatrix() print('before assemble: {:}s'.format(time.time() - t_ini)) dolfin.assemble(s_ij, tensor=S) print('first assembly') dolfin.assemble(t_ij, tensor=T) #%% print("starting the boundary conditions") t_ini = time.time() markers = dolfin.MeshFunction('size_t', mesh, 2) vals = np.zeros(markers.array().shape, dtype=int) vals[boundary_facets] = int(BBOX) markers.set_values(vals) electric_wall = dolfin.DirichletBC(vector_space, dolfin.Constant((0.0, 0.0, 0.0)), markers, BBOX) electric_wall.apply(S) electric_wall.apply(T) print('boundary conditions took {:} s'.format(time.time() - t_ini)) #%% print("starting the solving") solver = dolfin.SLEPcEigenSolver(S, T) solver.parameters["solver"] = "krylov-schur" solver.parameters["problem_type"] = "gen_hermitian" solver.parameters["spectrum"] = "target magnitude" solver.parameters["spectral_transform"] = "shift-and-invert" solver.parameters["spectral_shift"] = 30. n_to_solve = 1
nx = 32 ny = 32 mesh = dl.UnitSquareMesh(dl.mpi_comm_self(), nx, ny) Vh2 = dl.FunctionSpace(mesh, 'Lagrange', 1) Vh1 = dl.FunctionSpace(mesh, 'Lagrange', 1) Vh = [Vh2, Vh1, Vh2] ndofs = [Vh[STATE].dim(), Vh[PARAMETER].dim(), Vh[ADJOINT].dim()] if rank == 0: print(sep, "Set up the mesh and finite element spaces", sep) print( "Number of dofs: STATE={0}, PARAMETER={1}, ADJOINT={2}".format(*ndofs)) u_bdr = dl.Expression("x[1]", degree=1) u_bdr0 = dl.Constant(0.0) bc = dl.DirichletBC(Vh[STATE], u_bdr, u_boundary) bc0 = dl.DirichletBC(Vh[STATE], u_bdr0, u_boundary) pde = PDEVariationalProblem(Vh, pde_varf, bc, bc0, is_fwd_linear=True) if dlversion() <= (1, 6, 0): pde.solver = dl.PETScKrylovSolver("cg", amg_method()) pde.solver_fwd_inc = dl.PETScKrylovSolver("cg", amg_method()) pde.solver_adj_inc = dl.PETScKrylovSolver("cg", amg_method()) else: pde.solver = dl.PETScKrylovSolver(mesh.mpi_comm(), "cg", amg_method()) pde.solver_fwd_inc = dl.PETScKrylovSolver(mesh.mpi_comm(), "cg", amg_method()) pde.solver_adj_inc = dl.PETScKrylovSolver(mesh.mpi_comm(), "cg", amg_method()) pde.solver.parameters["relative_tolerance"] = 1e-15
n = extH1.dim() # test and trial functions A = dlfn.TrialFunction(intHCurl) B = dlfn.TestFunction(intHCurl) u = dlfn.TrialFunction(intH1) phi = dlfn.TrialFunction(extH1) psi = dlfn.TestFunction(extH1) # measures and normal vectors dA, dV, normals = dict(), dict(), dict() for i in subIds: dA[i] = dlfn.Measure("ds", subMeshes[i], subdomain_data=facetSubMeshFuns[i]) dV[i] = dlfn.Measure("dx", subMeshes[i]) normals[i] = dlfn.FacetNormal(subMeshes[i]) intV = dlfn.assemble(dlfn.Constant(1.0) * dV[intId]) extV = dlfn.assemble(dlfn.Constant(1.0) * dV[extId]) #------------------------------------------------------------------------------# # solution functions #------------------------------------------------------------------------------# sol_A = dlfn.Function(intHCurl) sol_A0 = dlfn.Function(intHCurl) sol_phi = dlfn.Function(extH1) #------------------------------------------------------------------------------# # weak forms and assembly in interior #------------------------------------------------------------------------------# # linear forms in interior domain from dolfin import curl, inner, dot, grad id_int = dlfn.Constant(1. / dt) * dot(A, B) * dV[intId] a_int = dlfn.Constant(0.5 * eta) * inner(curl(A), curl(B)) * dV[intId] b_int = u * dot(normals[intId], curl(B)) * dA[intId](intrfcId)
def pde_varf(u, m, p): return dl.exp(m) * dl.inner(dl.nabla_grad(u), dl.nabla_grad( p)) * dl.dx - dl.Constant(0.0) * p * dl.dx
def __init__(self, V, sub_domain, method="topological"): df.DirichletBC.__init__(self, V, df.Constant(0), sub_domain, method)
u_e = df.Expression(("A*exp(B*x[0]) + C"), A=A, B=B, C=C, degree=2) for j, N in enumerate(Ns): mesh = df.UnitSquareMesh(N, N) V = df.FunctionSpace(mesh, 'P', 1) v = df.TestFunction(V) u_ = df.Function(V) u = df.TrialFunction(V) if SUPG_stabilization: alpha = 2 h = 1 / N magnitude = 1 Pe = magnitude * h / (2.0 * mu) tau = h / (2.0 * magnitude) * (1.0 / np.tanh(Pe) - 1.0 / Pe) beta = df.Constant(tau * alpha) v = v + beta * h * v.dx(0) F = df.Constant(mu) * inner(grad(u), grad(v)) * dx + inner(u.dx(0), v) * dx bc1 = df.DirichletBC(V, df.Constant(0), left) bc2 = df.DirichletBC(V, df.Constant(1), right) # Neumann on y = 0 and y = 1 enforced implicitly df.solve(df.lhs(F) == df.rhs(F), u_, bcs=[bc1, bc2]) # interpolate(u_e, VV) # u_numerical = u_.vector().vec().array # X = V.tabulate_dof_coordinates() X = mesh.coordinates() u_numerical = u_.compute_vertex_values(mesh)
sources=cpp_sources, include_dirs=["."]) #Generate a mesh and some matrices nx = 32 ny = 32 mesh = dl.UnitSquareMesh(nx, ny) Vh = dl.FunctionSpace(mesh, 'Lagrange', 1) ndof = Vh.dim() uh, vh = dl.TrialFunction(Vh), dl.TestFunction(Vh) A = dl.assemble( dl.inner( dl.nabla_grad(uh), dl.nabla_grad(vh) ) *dl.dx ) M = dl.assemble( dl.inner( uh, vh ) *dl.dx ) ones = dl.interpolate(dl.Constant(1.), Vh).vector() Mones = M*ones s = Mones s.set_local( np.ones(ndof) / Mones.array() ) M.zero() M.set_diagonal(s) myla = cpp_module.cpp_linalg() B = myla.MatPtAP(M, A) x = dl.Vector() B.init_vector(x,1) #This works fine B.mult(s,x)