def solve_something(mesh): V = fd.FunctionSpace(mesh, "CG", 1) u = fd.Function(V) v = fd.TestFunction(V) x, y = fd.SpatialCoordinate(mesh) # f = fd.sin(x) * fd.sin(y) + x**2 + y**2 # uex = x**4 * y**4 uex = fd.sin(x) * fd.sin(y) #*(x*y)**3 # def source(xs, ys): # return 1/((x-xs)**2+(y-ys)**2 + 0.1) # uex = source(0, 0) uex = uex - fd.assemble(uex * fd.dx) / fd.assemble(1 * fd.dx(domain=mesh)) # f = fd.conditional(fd.ge(abs(x)-abs(y), 0), 1, 0) from firedrake import inner, grad, dx, ds, div, sym eps = fd.Constant(0.0) f = uex - div(grad(uex)) + eps * div(grad(div(grad(uex)))) n = fd.FacetNormal(mesh) g = inner(grad(uex), n) g1 = inner(grad(div(grad(uex))), n) g2 = div(grad(uex)) # F = 0.1 * inner(u, v) * dx + inner(grad(u), grad(v)) * dx + inner(grad(grad(u)), grad(grad(v))) * dx - f * v * dx - g * v * ds F = inner(u, v) * dx + inner(grad(u), grad(v)) * dx - f * v * dx - g * v * ds F += eps * inner(div(grad(u)), div(grad(v))) * dx F += eps * g1 * v * ds F -= eps * g2 * inner(grad(v), n) * ds # f = -div(grad(uex)) # F = inner(grad(u), grad(v)) * dx - f * v * dx # bc = fd.DirichletBC(V, uex, "on_boundary") bc = None fd.solve(F == 0, u, bcs=bc, solver_parameters={ "ksp_type": "cg", "ksp_atol": 1e-13, "ksp_rtol": 1e-13, "ksp_dtol": 1e-13, "ksp_stol": 1e-13, "pc_type": "jacobi", "pc_factor_mat_solver_type": "mumps", "snes_type": "ksponly", "ksp_converged_reason": None }) print("||u-uex|| =", fd.norm(u - uex)) print("||grad(u-uex)|| =", fd.norm(grad(u - uex))) print("||grad(grad(u-uex))|| =", fd.norm(grad(grad(u - uex)))) err = fd.Function( fd.TensorFunctionSpace(mesh, "DG", V.ufl_element().degree() - 2)).interpolate( grad(grad(u - uex))) # err = fd.Function(fd.FunctionSpace(mesh, "DG", V.ufl_element().degree())).interpolate(u-uex) fd.File(outdir + "sln.pvd").write(u) fd.File(outdir + "err.pvd").write(err)
def run_L2tracking_optimization(write_output=False): """ Test template for fsz.LevelsetFunctional.""" # tool for developing new tests, allows storing shape iterates if write_output: out = fd.File("domain.pvd") def cb(*args): out.write(Q.mesh_m.coordinates) cb() else: cb = None # setup problem mesh = fd.UnitSquareMesh(30, 30) Q = fs.FeControlSpace(mesh) inner = fs.ElasticityInnerProduct(Q) q = fs.ControlVector(Q, inner) # setup PDE constraint mesh_m = Q.mesh_m e = PoissonSolver(mesh_m) # create PDEconstrained objective functional J_ = L2trackingObjective(e, Q, cb=cb) J = fs.ReducedObjective(J_, e) # ROL parameters params_dict = { 'General': { 'Secant': { 'Type': 'Limited-Memory BFGS', 'Maximum Storage': 10 } }, 'Step': { 'Type': 'Line Search', 'Line Search': { 'Descent Method': { 'Type': 'Quasi-Newton Step' } }, }, 'Status Test': { 'Gradient Tolerance': 1e-4, 'Step Tolerance': 1e-5, 'Iteration Limit': 15 } } # assemble and solve ROL optimization problem params = ROL.ParameterList(params_dict, "Parameters") problem = ROL.OptimizationProblem(J, q) solver = ROL.OptimizationSolver(problem, params) solver.solve() # verify that the norm of the gradient at optimum is small enough state = solver.getAlgorithmState() assert (state.gnorm < 1e-4)
def retract(self, input_phi, delta_x, scaling=1): """input_phi is not modified, output_phi refers to problem.phi Args: input_phi ([type]): [description] delta_x ([type]): [description] scaling (int, optional): [description]. Defaults to 1. Returns: [type]: [description] """ self.current_max_distance_at_t0 = self.current_max_distance self.hj_solver.ts.setMaxTime(scaling) try: output_phi = self.hj_solver.solve(input_phi) except: reason = self.hj_solver.ts.getConvergedReason() print(f"Time stepping of Hamilton Jacobi failed. Reason: {reason}") if self.output_dir: print(f"Printing last solution to {self.output_dir}") fd.File(f"{self.output_dir}/failed_hj.pvd").write(input_phi) max_vel = calculate_max_vel(delta_x) self.last_distance = max_vel * scaling conv = self.hj_solver.ts.getConvergedReason() rtol, atol = ( self.hj_solver.parameters["ts_rtol"], self.hj_solver.parameters["ts_atol"], ) max_steps = self.hj_solver.parameters.get("ts_max_steps", 800) current_time = self.hj_solver.ts.getTime() total_time = self.hj_solver.ts.getMaxTime() if conv == 2: warning = ( f"Maximum number of time steps {self.hj_solver.ts.getStepNumber()} reached." f"Current time is only: {current_time} for total time: {total_time}." "Consider making the optimization time step dt shorter." "Restarting this step with more time steps and tighter tolerances if applicable." ) fd.warning(warning) # Tighten tolerances if we are really far if current_time / total_time < 0.2: current_rtol, current_atol = self.hj_solver.ts.getTolerances() new_rtol, new_atol = max(rtol / 200, current_rtol / 10), max( atol / 200, current_atol / 10) self.hj_solver.ts.setTolerances(rtol=new_rtol, atol=new_atol) # Relax max time steps current_max_steps = self.hj_solver.ts.getMaxSteps() new_max_steps = min(current_max_steps * 1.5, max_steps * 3) self.hj_solver.ts.setMaxSteps(new_max_steps) output_phi.assign(input_phi) elif conv == 1: self.hj_solver.ts.setTolerances(rtol=rtol, atol=atol) return output_phi
def test_equality_constraint(pytestconfig): mesh = fs.DiskMesh(0.05, radius=2.) Q = fs.FeControlSpace(mesh) inner = fs.ElasticityInnerProduct(Q, direct_solve=True) mesh_m = Q.mesh_m (x, y) = fd.SpatialCoordinate(mesh_m) q = fs.ControlVector(Q, inner) if pytestconfig.getoption("verbose"): out = fd.File("domain.pvd") def cb(*args): out.write(Q.mesh_m.coordinates) else: cb = None f = (pow(2 * x, 2)) + pow(y - 0.1, 2) - 1.2 J = fsz.LevelsetFunctional(f, Q, cb=cb) vol = fsz.LevelsetFunctional(fd.Constant(1.0), Q) e = fs.EqualityConstraint([vol]) emul = ROL.StdVector(1) params_dict = { 'Step': { 'Type': 'Augmented Lagrangian', 'Augmented Lagrangian': { 'Subproblem Step Type': 'Line Search', 'Penalty Parameter Growth Factor': 2., 'Initial Penalty Parameter': 1., 'Subproblem Iteration Limit': 20, }, 'Line Search': { 'Descent Method': { 'Type': 'Quasi-Newton Step' } }, }, 'General': { 'Secant': { 'Type': 'Limited-Memory BFGS', 'Maximum Storage': 5 } }, 'Status Test': { 'Gradient Tolerance': 1e-4, 'Step Tolerance': 1e-10, 'Iteration Limit': 10 } } params = ROL.ParameterList(params_dict, "Parameters") problem = ROL.OptimizationProblem(J, q, econ=e, emul=emul) solver = ROL.OptimizationSolver(problem, params) solver.solve() state = solver.getAlgorithmState() assert (state.gnorm < 1e-4) assert (state.cnorm < 1e-6)
def load_inputs(self, in_dir): # Bed B = firedrake.Function(self.V_cg) firedrake.File(in_dir + "B.pvd") >> B # Ice thickness H = firedrake.Function(self.V_cg) firedrake.File(in_dir + "H.pvd") >> H # Melt m = firedrake.Function(self.V_cg) firedrake.File(in_dir + "m.pvd") >> m # Sliding speed u_b = firedrake.Function(self.V_cg) firedrake.File(in_dir + "u_b.pvd") >> u_b # Potential at 0 pressure phi_m = firedrake.Function(self.V_cg) firedrake.File(in_dir + "phi_m.pvd") >> phi_m # Potential at overburden pressure phi_0 = firedrake.Function(self.V_cg) firedrake.File(in_dir + "phi_0.pvd") >> phi_0 # Ice overburden pressure p_i = firedrake.Function(self.V_cg) firedrake.File(in_dir + "p_i.pvd") >> p_i self.model_inputs["B"] = B self.model_inputs["H"] = H self.model_inputs["m"] = m self.model_inputs["u_b"] = u_b self.model_inputs["phi_m"] = phi_m self.model_inputs["phi_0"] = phi_0 self.model_inputs["p_i"] = p_i
def write_outputs(self, headers: bool, checkpoint: bool = True, vtk: bool = False, plots: bool = False): """Write all outputs. This creates or appends the CSV report, writes the latest solution, and plots (in 1D/2D case). Redefine this to control outputs. Args: write_headers (bool): Write header line to report if True. You may want to set this to False, for example, if the header has already been written. checkpoint (bool): Write checkpoint if True. vtk (bool): Write solution to VTK if True. plots (bool): Write plots if True. """ self = self.postprocess() sapphire.output.report(sim=self, write_header=headers) if checkpoint: self.write_checkpoint() if vtk: if self.vtk_solution_file is None: vtk_solution_filepath = self.output_directory_path.joinpath( "solution").with_suffix(".pvd") self.vtk_solution_file = fe.File(str(vtk_solution_filepath)) sapphire.output.write_solution_to_vtk(sim=self, file=self.vtk_solution_file) if plots: if self.mesh.geometric_dimension() < 3: sapphire.output.writeplots( **self.kwargs_for_writeplots(), time=self.time.__float__(), time_index=self.state["index"], outdir_path=self.output_directory_path) elif self.mesh.geometric_dimension() == 3: # This could be done with VTK and PyVista, but VTK can be a # difficult dependency. It may be best to run a separate # program for generating 3D plots from the solution files. raise NotImplementedError()
def mh_cb(mh_r): fd.File("output/fine_init.pvd").write(mh_r[-1].coordinates) fd.File("output/coarse_init.pvd").write(mh_r[0].coordinates) # sys.exit() d = distance_function(mh_r[0]) mu = 0.01 / (d + 0.01) extension[0] = fs.ElasticityForm(mu=mu) if args.cr > 0: mu_cr = args.cr * mu extension[0] = fs.CauchyRiemannAugmentation(extension[0], mu=mu_cr) if args.htwo > 0: mu_c1 = fd.Constant(args.htwo) extension[0] = C1Regulariser(extension[0], mu=mu_c1) if args.surf: Q[0] = fs.ScalarFeMultiGridControlSpace(mh_r, extension[0], order=args.order, fixed_bids=fixed_bids) else: Q[0] = fs.FeMultiGridControlSpace(mh_r, order=args.order) return Q[0].mh_m
def test_read_and_write_segy(): vp_name = "velocity_models/test" segy_file = vp_name + ".segy" hdf5_file = vp_name + ".hdf5" mesh = fire.UnitSquareMesh(10, 10) mesh.coordinates.dat.data[:, 0] *= -1 V = fire.FunctionSpace(mesh, 'CG', 3) x, y = fire.SpatialCoordinate(mesh) r = 0.2 xc = -0.5 yc = 0.5 vp = fire.Function(V) c = fire.conditional((x - xc)**2 + (y - yc)**2 < r**2, 3.0, 1.5) vp.interpolate(c) xi, yi, zi = spyro.io.write_function_to_grid(vp, V, 10.0 / 1000.0) spyro.io.create_segy(zi, segy_file) write_velocity_model(segy_file, vp_name) model = {} model["opts"] = { "method": "CG", # either CG or KMV "quadrature": "CG", # Equi or KMV "degree": 3, # p order "dimension": 2, # dimension } model["mesh"] = { "Lz": 1.0, # depth in km - always positive "Lx": 1.0, # width in km - always positive "Ly": 0.0, # thickness in km - always positive "meshfile": None, "initmodel": None, "truemodel": hdf5_file, } model["BCs"] = { "status": False, } vp_read = spyro.io.interpolate(model, mesh, V, guess=False) fire.File("velocity_models/test.pvd").write(vp_read) value_at_center = vp_read.at(xc, yc) test1 = math.isclose(value_at_center, 3.0) value_outside_circle = vp_read.at(xc + r + 0.1, yc) test2 = math.isclose(value_outside_circle, 1.5) assert all([test1, test2])
def writereferenceresult(filename, mesh, icemodel, upc): assert filename.split('.')[-1] == 'pvd' variables = 'u,p,c,tau,nu,phydrostatic,jweight,velocitySIA' if mesh.comm.size > 1: variables += ',rank' fd.PETSc.Sys.Print('writing variables (%s) to output file %s ... ' \ % (variables,filename)) u, p, c = upc.split() u.rename('velocity') p.rename('pressure') c.rename('displacement') tau, nu = stresses(mesh, icemodel, u) ph = phydrostatic(mesh) jw = jweight(mesh, icemodel, c) velocitySIA = siahorizontalvelocity(mesh) if mesh.comm.size > 1: # integer-valued element-wise process rank rank = fd.Function(fd.FunctionSpace(mesh, 'DG', 0)) rank.dat.data[:] = mesh.comm.rank rank.rename('rank') fd.File(filename).write(u, p, c, tau, nu, ph, jw, velocitySIA, rank) else: fd.File(filename).write(u, p, c, tau, nu, ph, jw, velocitySIA) return 0
def write_outputs(self, write_headers, plotvars=None): self.output_directory_path.mkdir(parents=True, exist_ok=True) if self.solution_file is None: solution_filepath = self.output_directory_path.joinpath( "solution").with_suffix(".pvd") self.solution_file = fe.File(str(solution_filepath)) self = self.postprocess() sapphire.output.report(sim=self, write_header=write_headers) sapphire.output.write_solution(sim=self, file=self.solution_file) sapphire.output.plot(sim=self, plotvars=plotvars)
def writesolutiongeometry(filename, refmesh, mzfine, upc): # get fields on reference mesh u, p, c = upc.split() # compute h on base mesh as updated surface elevation # h(x,y) = lambda(x,y) + c(x,y,lambda(x,y)) lambase = surfaceelevation(refmesh) # bounded below by Href; space Q1base cbase, Q1base = _surfacevalue(refmesh, c) hbase0 = fd.Function(Q1base).interpolate(lambase + cbase) hbase = fd.Function(Q1base) hbase.interpolate(fd.conditional(hbase0 > 0.0, hbase0, 0.0)) # duplicate fine mesh and extend h onto it mesh = extrudedmesh(refmesh._base_mesh, mzfine, refine=-1, temporary_height=1.0) h = extend(mesh, hbase) # change mesh coordinate to linear times h Vcoord = mesh.coordinates.function_space() if mesh._base_mesh.cell_dimension() == 1: x, z = fd.SpatialCoordinate(mesh) Xnew = fd.Function(Vcoord).interpolate(fd.as_vector([x, h * z])) elif mesh._base_mesh.cell_dimension() == 2: x, y, z = fd.SpatialCoordinate(mesh) Xnew = fd.Function(Vcoord).interpolate(fd.as_vector([x, y, h * z])) else: raise ValueError('applies only to 2D and 3D extruded meshes') mesh.coordinates.assign(Xnew) # interpolate velocity u and pressure p from refmesh onto mesh and write Vu, Vp, _ = vectorspaces(mesh) unew = fd.Function(Vu) pnew = fd.Function(Vp) unew.rename('velocity') pnew.rename('pressure') # note f.at() searches for element to evaluate (thanks L Mitchell) print(Xnew.dat.data_ro) # FIXME shows inadmissible z: too high unew.dat.data[:] = u.at(Xnew.dat.data_ro) pnew.dat.data[:] = p.at(Xnew.dat.data_ro) fd.File(filename).write(unew, pnew) return 0
def run_solver(r): mesh = fd.UnitSquareMesh(2**r, 2**r) P2 = fd.VectorElement("CG", mesh.ufl_cell(), 1) P1 = fd.FiniteElement("CG", mesh.ufl_cell(), 1) TH = P2 * P1 W = fd.FunctionSpace(mesh, TH) (v, q) = fd.TestFunctions(W) # Stokes 1 w_sol1 = fd.Function(W) nu = fd.Constant(0.05) F = NavierStokesBrinkmannForm(W, w_sol1, nu, beta_gls=2.0) from firedrake import sin, grad, pi, sym, div, inner x, y = fd.SpatialCoordinate(mesh) u_mms = fd.as_vector( [sin(2.0 * pi * x) * sin(pi * y), sin(pi * x) * sin(2.0 * pi * y)]) p_mms = -0.5 * (u_mms[0]**2 + u_mms[1]**2) f_mms_u = (grad(u_mms) * u_mms + grad(p_mms) - 2.0 * nu * div(sym(grad(u_mms)))) f_mms_p = div(u_mms) F += -inner(f_mms_u, v) * dx - f_mms_p * q * dx bc1 = fd.DirichletBC(W.sub(0), u_mms, "on_boundary") bc2 = fd.DirichletBC(W.sub(1), p_mms, "on_boundary") solver_parameters = {"ksp_max_it": 200} problem1 = fd.NonlinearVariationalProblem(F, w_sol1, bcs=[bc1, bc2]) solver1 = NavierStokesBrinkmannSolver( problem1, options_prefix="navier_stokes", solver_parameters=solver_parameters, ) solver1.solve() u_sol, _ = w_sol1.split() fd.File("test_u_sol.pvd").write(u_sol) u_mms_func = fd.interpolate(u_mms, W.sub(0)) error = fd.errornorm(u_sol, u_mms_func) print(f"Error: {error}") return error
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # container for functional value self.J = 0 # target solution, which also specifies rhs and DirBC mesh_m = self.Q.mesh_m x, y = fd.SpatialCoordinate(mesh_m) sin = fd.sin cos = fd.cos pi = fd.pi self.u_t = lambda t: sin(pi * x) * sin(pi * y) * cos(t) self.f = lambda t: sin(pi * x) * sin(pi * y) * (2 * pi**2 * cos(t) - sin(t)) # perturbed initial guess to be fixed by shape optimization V = fd.FunctionSpace(mesh_m, "CG", 1) self.u0 = fd.Function(V) perturbation = 0.25 * sin(x * pi) * sin(y * pi)**2 self.u0.interpolate(sin(pi * x * (1 + perturbation)) * sin(pi * y)) # define self.cb, which is always called after self.solvePDE self.File = fd.File("u0.pvd") self.cb = lambda: self.File.write(self.u0) # heat equation discretized with implicit Euler self.u = fd.Function(V) self.u_old = fd.Function(V) # solution at previous time self.bcs = fd.DirichletBC(V, 0, "on_boundary") self.dx = fd.dx(metadata={"quadrature_degree": 1}) self.dt = 0.125 v = fd.TestFunction(V) self.F = lambda t, u, u_old: fd.inner((u-u_old)/self.dt, v)*self.dx \ + fd.inner(fd.grad(u), fd.grad(v))*self.dx \ - fd.inner(self.f(t+self.dt), v)*self.dx
def test_cone_cg_2D(): mesh = fd.UnitSquareMesh(100, 100) V = fd.FunctionSpace(mesh, "CG", 1) radius = 0.2 x, y = fd.SpatialCoordinate(mesh) x_shift = 0.5 phi_init = ((x - x_shift) * (x - x_shift) + (y - 0.5) * (y - 0.5) - radius**2) phi0 = fd.Function(V).interpolate(phi_init) phi_pvd = fd.File("phi_reinit.pvd") reinit_solver = ReinitSolverCG(V) phin = reinit_solver.solve(phi0, iters=10) phi_pvd.write(phin) phi_solution = fd.interpolate( sqrt((x - x_shift) * (x - x_shift) + (y - 0.5) * (y - 0.5)) - radius, V, ) error_numeri = fd.errornorm(phin, phi_solution) print(f"error: {error_numeri}") assert error_numeri < 1e-4
def __init__(self, model_inputs, in_dir=None): r"""Initialize model inputs and Parameters ---------- model_inputs: model input object """ self.mesh = model_inputs["mesh"] self.V_cg = firedrake.FunctionSpace(self.mesh, "CG", 2) self.model_inputs = model_inputs # If an input directory is specified, load model inputs from there. # Otherwise use the specified model inputs dictionary. if in_dir: model_inputs = self.load_inputs(in_dir) # Ice thickness self.H = self.model_inputs["H"] # Bed elevation self.B = self.model_inputs["B"] # Basal sliding speed self.u_b = self.model_inputs["u_b"] # Melt rate self.m = self.model_inputs["m"] # Cavity gap height self.h = self.model_inputs["h_init"] # Potential self.phi_prev = self.model_inputs["phi_init"] # Potential at 0 pressure self.phi_m = self.model_inputs["phi_m"] # Ice overburden pressure self.p_i = self.model_inputs["p_i"] # Potential at overburden pressure self.phi_0 = self.model_inputs["phi_0"] # Dirichlet boundary conditions self.d_bcs = self.model_inputs["d_bcs"] # Channel areas self.S = self.model_inputs["S_init"] # Drainage width self.width = self.model_inputs["width"] # Output directory self.out_dir = self.model_inputs["out_dir"] # If there is a dictionary of physical constants specified, use it. # Otherwise use the defaults. if "constants" in self.model_inputs: self.pcs = self.model_inputs["constants"] else: self.pcs = pcs self.n_bcs = [] if "n_bcs" in self.model_inputs: self.n_bcs = model_inputs["n_bcs"] ### Create some fields self.V_cg = firedrake.FunctionSpace(self.mesh, "CG", 1) # Potential self.phi = firedrake.Function(self.V_cg) # Effective pressure self.N = firedrake.Function(self.V_cg) # Stores the value of S**alpha. self.S_alpha = firedrake.Function(self.V_cg) self.update_S_alpha() # Water pressure self.p_w = firedrake.Function(self.V_cg) # Pressure as a fraction of overburden self.pfo = firedrake.Function(self.V_cg) # Current time self.t = 0.0 ### Output files self.S_out = firedrake.File(self.out_dir + "S.pvd") self.h_out = firedrake.File(self.out_dir + "h.pvd") self.phi_out = firedrake.File(self.out_dir + "phi.pvd") self.pfo_out = firedrake.File(self.out_dir + "pfo.pvd") ### Create the solver objects # Potential solver self.phi_solver = PhiSolver(self) # Gap height solver self.hs_solver = HSSolver(self)
def compliance(): parser = argparse.ArgumentParser(description="Compliance problem with MMA") parser.add_argument( "--nref", action="store", dest="nref", type=int, help="Number of mesh refinements", default=2, ) parser.add_argument( "--uniform", action="store", dest="uniform", type=int, help="Use uniform mesh", default=0, ) parser.add_argument( "--inner_product", action="store", dest="inner_product", type=str, help="Inner product, euclidean or L2", default="L2", ) parser.add_argument( "--output_dir", action="store", dest="output_dir", type=str, help="Directory for all the output", default="./", ) args = parser.parse_args() nref = args.nref inner_product = args.inner_product output_dir = args.output_dir assert inner_product == "L2" or inner_product == "euclidean" mesh = fd.Mesh("./beam_uniform.msh") #mh = fd.MeshHierarchy(mesh, 2) #mesh = mh[-1] if nref > 0: mh = fd.MeshHierarchy(mesh, nref) mesh = mh[-1] elif nref < 0: raise RuntimeError("Non valid mesh argument") V = fd.VectorFunctionSpace(mesh, "CG", 1) u, v = fd.TrialFunction(V), fd.TestFunction(V) # Elasticity parameters E, nu = 1e0, 0.3 mu, lmbda = fd.Constant(E / (2 * (1 + nu))), fd.Constant( E * nu / ((1 + nu) * (1 - 2 * nu)) ) # Helmholtz solver RHO = fd.FunctionSpace(mesh, "CG", 1) rho = fd.interpolate(fd.Constant(0.1), RHO) af, b = fd.TrialFunction(RHO), fd.TestFunction(RHO) #filter_radius = fd.Constant(0.2) #x, y = fd.SpatialCoordinate(mesh) #x_ = fd.interpolate(x, RHO) #y_ = fd.interpolate(y, RHO) #aH = filter_radius * inner(grad(af), grad(b)) * dx + af * b * dx #LH = rho * b * dx rhof = fd.Function(RHO) solver_params = { "ksp_type": "preonly", "pc_type": "lu", "pc_factor_mat_solver_type": "mumps", "mat_mumps_icntl_14": 200, "mat_mumps_icntl_24": 1, } #fd.solve(aH == LH, rhof, solver_parameters=solver_params) rhof.assign(rho) rhofControl = fda.Control(rhof) eps = fd.Constant(1e-5) p = fd.Constant(3.0) def simp(rho): return eps + (fd.Constant(1.0) - eps) * rho ** p def epsilon(v): return sym(nabla_grad(v)) def sigma(v): return 2.0 * mu * epsilon(v) + lmbda * tr(epsilon(v)) * Identity(2) DIRICHLET = 3 NEUMANN = 4 a = inner(simp(rhof) * sigma(u), epsilon(v)) * dx load = fd.Constant((0.0, -1.0)) L = inner(load, v) * ds(NEUMANN) u_sol = fd.Function(V) bcs = fd.DirichletBC(V, fd.Constant((0.0, 0.0)), DIRICHLET) fd.solve(a == L, u_sol, bcs=bcs, solver_parameters=solver_params) c = fda.Control(rho) J = fd.assemble(fd.Constant(1e-4) * inner(u_sol, load) * ds(NEUMANN)) Vol = fd.assemble(rhof * dx) VolControl = fda.Control(Vol) with fda.stop_annotating(): Vlimit = fd.assemble(fd.Constant(1.0) * dx(domain=mesh)) * 0.5 rho_viz_f = fd.Function(RHO, name="rho") plot_file = f"{output_dir}/design_{inner_product}.pvd" controls_f = fd.File(plot_file) def deriv_cb(j, dj, rho): with fda.stop_annotating(): rho_viz_f.assign(rhofControl.tape_value()) controls_f.write(rho_viz_f) Jhat = fda.ReducedFunctional(J, c, derivative_cb_post=deriv_cb) Volhat = fda.ReducedFunctional(Vol, c) class VolumeConstraint(fda.InequalityConstraint): def __init__(self, Vhat, Vlimit, VolControl): self.Vhat = Vhat self.Vlimit = float(Vlimit) self.VolControl = VolControl def function(self, m): # Compute the integral of the control over the domain integral = self.VolControl.tape_value() with fda.stop_annotating(): value = -integral / self.Vlimit + 1.0 return [value] def jacobian(self, m): with fda.stop_annotating(): gradients = self.Vhat.derivative() with gradients.dat.vec as v: v.scale(-1.0 / self.Vlimit) return [gradients] def output_workspace(self): return [0.0] def length(self): """Return the number of components in the constraint vector (here, one).""" return 1 lb = 1e-5 ub = 1.0 problem = fda.MinimizationProblem( Jhat, bounds=(lb, ub), constraints=[VolumeConstraint(Volhat, Vlimit, VolControl)], ) parameters_mma = { "move": 0.2, "maximum_iterations": 200, "m": 1, "IP": 0, "tol": 1e-6, "accepted_tol": 1e-4, "norm": inner_product, #"norm": "euclidean", "gcmma": False, } solver = MMASolver(problem, parameters=parameters_mma) rho_opt = solver.solve() with open(f"{output_dir}/finished_{inner_product}.txt", "w") as f: f.write("Done")
def heat_exchanger_optimization(mu=0.03, n_iters=1000): output_dir = "2D/" path = os.path.abspath(__file__) dir_path = os.path.dirname(path) mesh = fd.Mesh(f"{dir_path}/2D_mesh.msh") # Perturb the mesh coordinates. Necessary to calculate shape derivatives S = fd.VectorFunctionSpace(mesh, "CG", 1) s = fd.Function(S, name="deform") mesh.coordinates.assign(mesh.coordinates + s) # Initial level set function x, y = fd.SpatialCoordinate(mesh) PHI = fd.FunctionSpace(mesh, "CG", 1) phi_expr = sin(y * pi / 0.2) * cos(x * pi / 0.2) - fd.Constant(0.8) # Avoid recording the operation interpolate into the tape. # Otherwise, the shape derivatives will not be correct with fda.stop_annotating(): phi = fd.interpolate(phi_expr, PHI) phi.rename("LevelSet") fd.File(output_dir + "phi_initial.pvd").write(phi) # Physics mu = fd.Constant(mu) # viscosity alphamin = 1e-12 alphamax = 2.5 / (2e-4) parameters = { "mat_type": "aij", "ksp_type": "preonly", "ksp_converged_reason": None, "pc_type": "lu", "pc_factor_mat_solver_type": "mumps", } stokes_parameters = parameters temperature_parameters = parameters u_inflow = 2e-3 tin1 = fd.Constant(10.0) tin2 = fd.Constant(100.0) P2 = fd.VectorElement("CG", mesh.ufl_cell(), 2) P1 = fd.FiniteElement("CG", mesh.ufl_cell(), 1) TH = P2 * P1 W = fd.FunctionSpace(mesh, TH) U = fd.TrialFunction(W) u, p = fd.split(U) V = fd.TestFunction(W) v, q = fd.split(V) epsilon = fd.Constant(10000.0) def hs(phi, epsilon): return fd.Constant(alphamax) * fd.Constant(1.0) / ( fd.Constant(1.0) + exp(-epsilon * phi)) + fd.Constant(alphamin) def stokes(phi, BLOCK_INLET_MOUTH, BLOCK_OUTLET_MOUTH): a_fluid = mu * inner(grad(u), grad(v)) - div(v) * p - q * div(u) darcy_term = inner(u, v) return (a_fluid * dx + hs(phi, epsilon) * darcy_term * dx(0) + alphamax * darcy_term * (dx(BLOCK_INLET_MOUTH) + dx(BLOCK_OUTLET_MOUTH))) # Dirichlet boundary conditions inflow1 = fd.as_vector([ u_inflow * sin( ((y - (line_sep - (dist_center + inlet_width))) * pi) / inlet_width), 0.0, ]) inflow2 = fd.as_vector([ u_inflow * sin(((y - (line_sep + dist_center)) * pi) / inlet_width), 0.0, ]) noslip = fd.Constant((0.0, 0.0)) # Stokes 1 bcs1_1 = fd.DirichletBC(W.sub(0), noslip, WALLS) bcs1_2 = fd.DirichletBC(W.sub(0), inflow1, INLET1) bcs1_3 = fd.DirichletBC(W.sub(1), fd.Constant(0.0), OUTLET1) bcs1_4 = fd.DirichletBC(W.sub(0), noslip, INLET2) bcs1_5 = fd.DirichletBC(W.sub(0), noslip, OUTLET2) bcs1 = [bcs1_1, bcs1_2, bcs1_3, bcs1_4, bcs1_5] # Stokes 2 bcs2_1 = fd.DirichletBC(W.sub(0), noslip, WALLS) bcs2_2 = fd.DirichletBC(W.sub(0), inflow2, INLET2) bcs2_3 = fd.DirichletBC(W.sub(1), fd.Constant(0.0), OUTLET2) bcs2_4 = fd.DirichletBC(W.sub(0), noslip, INLET1) bcs2_5 = fd.DirichletBC(W.sub(0), noslip, OUTLET1) bcs2 = [bcs2_1, bcs2_2, bcs2_3, bcs2_4, bcs2_5] # Forward problems U1, U2 = fd.Function(W), fd.Function(W) L = inner(fd.Constant((0.0, 0.0, 0.0)), V) * dx problem = fd.LinearVariationalProblem(stokes(-phi, INMOUTH2, OUTMOUTH2), L, U1, bcs=bcs1) solver_stokes1 = fd.LinearVariationalSolver( problem, solver_parameters=stokes_parameters, options_prefix="stokes_1") solver_stokes1.solve() problem = fd.LinearVariationalProblem(stokes(phi, INMOUTH1, OUTMOUTH1), L, U2, bcs=bcs2) solver_stokes2 = fd.LinearVariationalSolver( problem, solver_parameters=stokes_parameters, options_prefix="stokes_2") solver_stokes2.solve() # Convection difussion equation ks = fd.Constant(1e0) cp_value = 5.0e5 cp = fd.Constant(cp_value) T = fd.FunctionSpace(mesh, "DG", 1) t = fd.Function(T, name="Temperature") w = fd.TestFunction(T) # Mesh-related functions n = fd.FacetNormal(mesh) h = fd.CellDiameter(mesh) u1, p1 = fd.split(U1) u2, p2 = fd.split(U2) def upwind(u): return (dot(u, n) + abs(dot(u, n))) / 2.0 u1n = upwind(u1) u2n = upwind(u2) # Penalty term alpha = fd.Constant(500.0) # Bilinear form a_int = dot(grad(w), ks * grad(t) - cp * (u1 + u2) * t) * dx a_fac = (fd.Constant(-1.0) * ks * dot(avg(grad(w)), jump(t, n)) * dS + fd.Constant(-1.0) * ks * dot(jump(w, n), avg(grad(t))) * dS + ks("+") * (alpha("+") / avg(h)) * dot(jump(w, n), jump(t, n)) * dS) a_vel = (dot( jump(w), cp * (u1n("+") + u2n("+")) * t("+") - cp * (u1n("-") + u2n("-")) * t("-"), ) * dS + dot(w, cp * (u1n + u2n) * t) * ds) a_bnd = (dot(w, cp * dot(u1 + u2, n) * t) * (ds(INLET1) + ds(INLET2)) + w * t * (ds(INLET1) + ds(INLET2)) - w * tin1 * ds(INLET1) - w * tin2 * ds(INLET2) + alpha / h * ks * w * t * (ds(INLET1) + ds(INLET2)) - ks * dot(grad(w), t * n) * (ds(INLET1) + ds(INLET2)) - ks * dot(grad(t), w * n) * (ds(INLET1) + ds(INLET2))) aT = a_int + a_fac + a_vel + a_bnd LT_bnd = (alpha / h * ks * tin1 * w * ds(INLET1) + alpha / h * ks * tin2 * w * ds(INLET2) - tin1 * ks * dot(grad(w), n) * ds(INLET1) - tin2 * ks * dot(grad(w), n) * ds(INLET2)) problem = fd.LinearVariationalProblem(derivative(aT, t), LT_bnd, t) solver_temp = fd.LinearVariationalSolver( problem, solver_parameters=temperature_parameters, options_prefix="temperature", ) solver_temp.solve() # fd.solve(eT == 0, t, solver_parameters=temperature_parameters) # Cost function: Flux at the cold outlet scale_factor = 4e-4 Jform = fd.assemble( fd.Constant(-scale_factor * cp_value) * inner(t * u1, n) * ds(OUTLET1)) # Constraints: Pressure drop on each fluid power_drop = 1e-2 Power1 = fd.assemble(p1 / power_drop * ds(INLET1)) Power2 = fd.assemble(p2 / power_drop * ds(INLET2)) phi_pvd = fd.File("phi_evolution.pvd") def deriv_cb(phi): with stop_annotating(): phi_pvd.write(phi[0]) c = fda.Control(s) # Reduced Functionals Jhat = LevelSetFunctional(Jform, c, phi, derivative_cb_pre=deriv_cb) P1hat = LevelSetFunctional(Power1, c, phi) P1control = fda.Control(Power1) P2hat = LevelSetFunctional(Power2, c, phi) P2control = fda.Control(Power2) Jhat_v = Jhat(phi) print("Initial cost function value {:.5f}".format(Jhat_v), flush=True) print("Power drop 1 {:.5f}".format(Power1), flush=True) print("Power drop 2 {:.5f}".format(Power2), flush=True) beta_param = 0.08 # Regularize the shape derivatives only in the domain marked with 0 reg_solver = RegularizationSolver(S, mesh, beta=beta_param, gamma=1e5, dx=dx, design_domain=0) tol = 1e-5 dt = 0.05 params = { "alphaC": 1.0, "debug": 5, "alphaJ": 1.0, "dt": dt, "K": 1e-3, "maxit": n_iters, "maxtrials": 5, "itnormalisation": 10, "tol_merit": 5e-3, # new merit can be within 0.5% of the previous merit # "normalize_tol" : -1, "tol": tol, } solver_parameters = { "reinit_solver": { "h_factor": 2.0, } } # Optimization problem problem = InfDimProblem( Jhat, reg_solver, ineqconstraints=[ Constraint(P1hat, 1.0, P1control), Constraint(P2hat, 1.0, P2control), ], solver_parameters=solver_parameters, ) results = nlspace_solve(problem, params) return results
"Line Search": { "Descent Method": { "Type": "Quasi-Newton Step" } } }, "Status Test": { "Gradient Tolerance": 1e-8, "Step Tolerance": 1e-8, "Iteration Limit": args.maxiter, }, } outdir = "./output/annulus/base-%s-cr-%s-weighted-%s-rstar-%.2f/" % ( args.base_inner, args.alpha, args.weighted, args.rstar) out = fd.File(outdir + "domain.pvd") params = ROL.ParameterList(params_dict, "Parameters") problem = ROL.OptimizationProblem(J, q) solver = ROL.OptimizationSolver(problem, params) boundary_derivatives = [] gradient_norms = [] objective_values = [] def cb(*args): out.write(mesh_m.coordinates) gradient_norms.append(solver.getAlgorithmState().gnorm) objective_values.append(solver.getAlgorithmState().value) boundary_derivatives.append(fd.assemble(fd.inner(expr, expr) * fd.ds)**0.5)
# # Now we're ready to solve the variational problem. We define `w` to be a # function to hold the solution on the mixed space. w = fd.Function(W) # solve fd.solve(a == L, w, bcs=[bc0, bc1]) # %% # Post-process and plot interesting fields print('* post-process') # collect fields vel, press = w.split() press.rename('pressure') # Projecting velocity field to a continuous space (visualization purporse) P1 = fd.VectorFunctionSpace(mesh, "CG", 1) vel_proj = fd.project(vel, P1) vel_proj.rename('velocity_proj') # project permeability Kxx kxx = fd.Function(DG) kxx.rename('Kxx') kxx.dat.data[...] = 1 / Kinv.dat.data[:, 0, 0] # print results fd.File("plots/darcy_rt.pvd").write(vel_proj, press, kxx) print('* normal termination')
def test_levelset(dim, inner_t, controlspace_t, use_extension, pytestconfig): verbose = pytestconfig.getoption("verbose") """ Test template for fsz.LevelsetFunctional.""" clscale = 0.1 if dim == 2 else 0.2 # make the mesh a bit coarser if we are using a multigrid control space as # we are refining anyway if controlspace_t == fs.FeMultiGridControlSpace: clscale *= 4 if dim == 2: mesh = fs.DiskMesh(clscale) elif dim == 3: mesh = fs.SphereMesh(clscale) else: raise NotImplementedError if controlspace_t == fs.BsplineControlSpace: if dim == 2: bbox = [(-2, 2), (-2, 2)] orders = [2, 2] levels = [4, 4] else: bbox = [(-3, 3), (-3, 3), (-3, 3)] orders = [2, 2, 2] levels = [3, 3, 3] Q = fs.BsplineControlSpace(mesh, bbox, orders, levels) elif controlspace_t == fs.FeMultiGridControlSpace: Q = fs.FeMultiGridControlSpace(mesh, refinements=1, order=2) else: Q = controlspace_t(mesh) inner = inner_t(Q) # if running with -v or --verbose, then export the shapes if verbose: out = fd.File("domain.pvd") def cb(*args): out.write(Q.mesh_m.coordinates) cb() else: cb = None # levelset test case if dim == 2: (x, y) = fd.SpatialCoordinate(Q.mesh_m) f = (pow(x, 2)) + pow(1.3 * y, 2) - 1. elif dim == 3: (x, y, z) = fd.SpatialCoordinate(Q.mesh_m) f = (pow(x, 2)) + pow(0.8 * y, 2) + pow(1.3 * z, 2) - 1. else: raise NotImplementedError J = fsz.LevelsetFunctional(f, Q, cb=cb, scale=0.1) if use_extension == "w_ext": ext = fs.ElasticityExtension(Q.V_r) if use_extension == "w_ext_fixed_dim": ext = fs.ElasticityExtension(Q.V_r, fixed_dims=[0]) else: ext = None q = fs.ControlVector(Q, inner, boundary_extension=ext) # these tolerances are not very stringent, but solutions are correct with # tighter tolerances, the combination # FeMultiGridControlSpace-ElasticityInnerProduct fails because the mesh # self-intersects (one should probably be more careful with the opt params) grad_tol = 1e-1 itlim = 15 itlimsub = 15 # Volume constraint vol = fsz.LevelsetFunctional(fd.Constant(1.0), Q, scale=1) initial_vol = vol.value(q, None) econ = fs.EqualityConstraint([vol], target_value=[initial_vol]) emul = ROL.StdVector(1) # ROL parameters params_dict = { 'Step': { 'Type': 'Augmented Lagrangian', 'Augmented Lagrangian': { 'Subproblem Step Type': 'Line Search', 'Penalty Parameter Growth Factor': 1.05, 'Print Intermediate Optimization History': True, 'Subproblem Iteration Limit': itlimsub }, 'Line Search': { 'Descent Method': { 'Type': 'Quasi-Newton Step' } }, }, 'General': { 'Secant': { 'Type': 'Limited-Memory BFGS', 'Maximum Storage': 50 } }, 'Status Test': { 'Gradient Tolerance': grad_tol, 'Step Tolerance': 1e-10, 'Iteration Limit': itlim } } params = ROL.ParameterList(params_dict, "Parameters") problem = ROL.OptimizationProblem(J, q, econ=econ, emul=emul) solver = ROL.OptimizationSolver(problem, params) solver.solve() # verify that the norm of the gradient at optimum is small enough # and that the volume has not changed too much state = solver.getAlgorithmState() assert (state.gnorm < grad_tol) assert abs(vol.value(q, None) - initial_vol) < 1e-2
bexpr = 2000.0 * (1 - fd.sqrt(minarg) / rl) b.interpolate(bexpr) alpha = args.alpha theta = 0.5 PD = asQ.paradiag(form_function=form_function, form_mass=form_mass, W=W, w0=w0, dt=dt, theta=theta, alpha=alpha, M=M, solver_parameters=solver_parameters_diag, circ="quasi") PD.solve() # write output: file0 = fd.File("output/output1.pvd") pun = fd.Function(W, name="pun") puns = pun.split() for i in range(M): walls = PD.w_all.split()[2 * i:2 * i + 2] for k in range(2): puns[k].assign(walls[k]) u_out = puns[0] h_out = puns[1] file0.write(u_out, h_out)
# Res. R = F_p + F_s prob = fd.NonlinearVariationalProblem(R, U, bcs=[bc0, bc1, bc3]) solver2ph = fd.NonlinearVariationalSolver(prob) # %% # 4) Solve problem # initialize variables xv, xp, xs = U.split() vel = fd.project(u0, P1) xp.rename('pressure') xs.rename('saturation') vel.rename('velocity') outfile = fd.File(oFile) it = 0 t = 0.0 while t < sim_time: t += dt print("*iteration= {:3d}, dtime= {:8.6f}, time={:8.6f}".format(it, dt, t)) solver2ph.solve() # update solution U0.assign(U) # 5) print results if it % freq_res == 0 or t == sim_time: vel.assign(fd.project(U.sub(0), P1)) xp.assign(U.sub(1))
fd.Constant(0.)) # shock terms # F1 += vshock*fd.dot(fd.grad(w), fd.grad(c_mid))*fd.dx F1 += vshock * np.abs(R) * fd.inner(fd.grad(w), fd.grad(c_mid)) * fd.dx F = F1 prob = fd.NonlinearVariationalProblem(F, c, bcs=t_bc) transport = fd.NonlinearVariationalSolver(prob) # %% # 4) Solve problem c0.assign(0.) t = it = 0 outfile = fd.File("plots/adr_supg_shock.pvd") c0.rename("c") dt = CFL * fd.interpolate(h / vnorm, DG0).dat.data.min() Dt.assign(dt) dt0 = dt Pe = vnorm * h / (2.0 * Diff) print('Peclet = {}; dt = {}'.format( fd.interpolate(Pe, DG0).dat.data.mean(), dt)) D = fd.interpolate(vshock * np.abs(R), DG0) D.rename("visc_shock") while t < sim_time: # move next time step t += np.min([sim_time - t, dt])
shock = fd.interpolate(vshock * np.abs(R), DG0) shock.rename('vshock') F = F1 prob = fd.NonlinearVariationalProblem(F, c, bcs=t_bc) transport = fd.NonlinearVariationalSolver(prob) # %% # 4) Solve problem # ----------------- t = 0.0 it = 0 dt0 = dt cfl_conditional = fd.conditional(fd.lt(np.abs(vnorm), tol), 1 / tol, h / vnorm) outfile = fd.File("plots/sb_t_supg.pvd") sol = fd.Function(W) c0.assign(0.) # initialize timestep while t < sim_time: # move next time step print("* iteration= {:4d}, dtime= {:8.6f}, time={:8.6f}".format(it, dt, t)) # SB idt.assign(1 / dt) fd.solve(a == L, sol, bcs=bcs) vel.assign(sol.sub(0)) Pe = vnorm * h / (2.0 * fd.det(Diff)) numCFL = dt / fd.interpolate(cfl_conditional, DG0).dat.data.min()
if equation == "heat": nu = fd.Constant(0.1) # for heat M = fd.derivative(fd.inner(u, v) * fd.dx, u) R = -(fd.inner(fd.grad(u) * u, v) + nu * fd.inner(fd.grad(u), fd.grad(v))) * fd.dx if equation == "heat": R = -nu * fd.inner(fd.grad(u), fd.grad(v)) * fd.dx F = fd.action(M, u_dot) - R bc = fd.DirichletBC(V, (0.0, 0.0), "on_boundary") t = 0.0 end = 0.1 tspan = (t, end) state_out = fd.File("result/state.pvd") def ts_monitor(ts, steps, time, X): state_out.write(u, time=time) problem = firedrake_ts.DAEProblem(F, u, u_dot, tspan, bcs=bc) solver = firedrake_ts.DAESolver(problem, monitor_callback=ts_monitor) ts = solver.ts ts.setTimeStep(0.01) ts.setExactFinalTime(PETSc.TS.ExactFinalTime.MATCHSTEP) ts.setSaveTrajectory() ts.setType(PETSc.TS.Type.THETA)
V = fire.FunctionSpace(mesh, finite_element_space, 1) bc = fire.DirichletBC(V, fire.Constant(1.0), 1) u = fire.Function(V) # Initialize the transport solver transport = rok.TransportSolver(method=method) transport.setVelocity(v) transport.setDiffusion(D) transport.setSource(q) transport.setBoundaryConditions([bc]) t = 0.0 step = 0 outfile = fire.File("results_demo-transport/u.pvd") outfile.write(u) while step < nsteps: transport.step(u, dt) t += dt step += 1 if step % 1 == 0: outfile.write(u) print("t = {:<15.3f} step = {:<15}".format(t, step))
# "snes_monitor": None, "ksp_monitor": None, } def solve(self): super().solve() self.failed_to_solve = False u_old = self.solution.copy(deepcopy=True) try: fd.solve(self.F == 0, self.solution, bcs=self.bcs, solver_parameters=self.params) except fd.ConvergenceError: self.failed_to_solve = True self.solution.assign(u_old) if __name__ == "__main__": mesh = fd.Mesh("pipe.msh") if mesh.topological_dimension() == 2: # in 2D viscosity = fd.Constant(1. / 400.) elif mesh.topological_dimension() == 3: # in 3D viscosity = fd.Constant(1 / 10.) # simpler problem in 3D else: raise NotImplementedError e = NavierStokesSolver(mesh, viscosity) e.solve() print(e.failed_to_solve) out = fd.File("temp_PDEConstrained_u.pvd") out.write(e.solution.split()[0])
"pc_sc_eliminate_fields": "0, 1", "condensed_field": { "ksp_type": "preonly", "pc_type": "lu", "pc_factor_mat_solver_type": "mumps" } } solver = fd.NonlinearVariationalSolver(problem, solver_parameters=hybrid_solver_params) # ----------------- wave_speed = fd.conditional(fd.lt(np.abs(vnorm), tol), h / tol, h / vnorm) # CFL dt_ = fd.interpolate(wave_speed, DG1).dat.data.min() * cfl outfile = fd.File(f"plots/adr-hdg-n-{refine}-p-{order}.pvd", project_output=True) dt = dt_ # dtime dtc.assign(dt_) # %% # solve problem # initialize timestep t = 0.0 it = 0 p = 0 while t < sim_time: # check dt dt = np.min([sim_time - t, dt])
import ROL n = 30 # mesh = fd.UnitSquareMesh(n, n) mesh = fd.Mesh("UnitSquareCrossed.msh") mesh = fd.MeshHierarchy(mesh, 1)[-1] Q = fs.FeMultiGridControlSpace(mesh, refinements=3, order=2) inner = fs.LaplaceInnerProduct(Q) mesh_m = Q.mesh_m V_m = fd.FunctionSpace(mesh_m, "CG", 1) f_m = fd.Function(V_m) (x, y) = fd.SpatialCoordinate(mesh_m) f = (pow(x - 0.5, 2)) + pow(y - 0.5, 2) - 2. out = fd.File("domain.pvd") J = fsz.LevelsetFunctional(f, Q, cb=lambda: out.write(mesh_m.coordinates)) q = fs.ControlVector(Q, inner) params_dict = { 'General': { 'Secant': { 'Type': 'Limited-Memory BFGS', 'Maximum Storage': 5 } }, 'Step': { 'Type': 'Line Search', 'Line Search': { 'Descent Method': {
Q = fs.FeControlSpace(mesh) inner = fs.LaplaceInnerProduct(Q, fixed_bids=[10, 11, 12]) q = fs.ControlVector(Q, inner) # setup PDE constraint if mesh.topological_dimension() == 2: # in 2D viscosity = fd.Constant(1./400.) elif mesh.topological_dimension() == 3: # in 3D viscosity = fd.Constant(1/10.) # simpler problem in 3D else: raise NotImplementedError e = NavierStokesSolver(Q.mesh_m, viscosity) # save state variable evolution in file u2.pvd or u3.pvd if mesh.topological_dimension() == 2: # in 2D out = fd.File("solution/u2D.pvd") elif mesh.topological_dimension() == 3: # in 3D out = fd.File("solution/u3D.pvd") def cb(): return out.write(e.solution.split()[0]) # create PDEconstrained objective functional J_ = PipeObjective(e, Q, cb=cb) J = fs.ReducedObjective(J_, e) # add regularization to improve mesh quality Jq = fsz.MoYoSpectralConstraint(10, fd.Constant(0.5), Q) J = J + Jq