def regional(f): expr_arr = ["0"] * f.value_size() # Sum all the components to find the mean expr_arr[0] = "1" f_sum = dolfin.dot(f, dolfin_adjoint.Expression(tuple(expr_arr), degree=1)) expr_arr[0] = "0" for i in range(1, f.value_size()): expr_arr[i] = "1" f_sum += dolfin.dot( f, dolfin_adjoint.Expression(tuple(expr_arr), degree=1)) expr_arr[i] = "0" # Compute the mean f_avg = f_sum / f.value_size() # Compute the variance expr_arr[0] = "1" f_reg = (dolfin.dot(f, dolfin_adjoint.Expression( tuple(expr_arr), degree=1)) - f_avg)**2 / f.value_size() expr_arr[0] = "0" for i in range(1, f.value_size()): expr_arr[i] = "1" f_reg += (dolfin.dot( f, dolfin_adjoint.Expression(tuple(expr_arr), degree=1)) - f_avg)**2 / f.value_size() expr_arr[i] = "0" # Create a functional term return f_reg
def target_solution_rc(args, pde): pde.source = da.Expression( "k*100*exp( (-(x[0]-x0)*(x[0]-x0) -(x[1]-x1)*(x[1]-x1)) / (2*0.01*l) )", k=1, l=1, x0=0.1, x1=0.1, degree=3) source_vec = da.interpolate(pde.source, pde.V) save_solution(args, source_vec, 'opt_fem_f') u = pde.solve_problem_variational_form() dof_data = torch.tensor(u.vector()[:], dtype=torch.float).unsqueeze(0) return dof_data, u, source_vec.vector()[:]
def _build_function_space(self): class Exterior(fa.SubDomain): def inside(self, x, on_boundary): return on_boundary and (fa.near(x[1], 1) or fa.near(x[0], 1) or fa.near(x[0], 0) or fa.near(x[1], 0)) class Left(fa.SubDomain): def inside(self, x, on_boundary): return on_boundary and fa.near(x[0], 0) class Right(fa.SubDomain): def inside(self, x, on_boundary): return on_boundary and fa.near(x[0], 1) class Bottom(fa.SubDomain): def inside(self, x, on_boundary): return on_boundary and fa.near(x[1], 0) class Top(fa.SubDomain): def inside(self, x, on_boundary): return on_boundary and fa.near(x[1], 1) class Interior(fa.SubDomain): def inside(self, x, on_boundary): return on_boundary and (x[0] > 0.1 and x[0] < 0.9 and x[1] > 0.1 and x[1] < 0.9) self.exteriors_dic = { 'left': Left(), 'right': Right(), 'bottom': Bottom(), 'top': Top() } self.exterior = Exterior() self.interior = Interior() self.V = fa.FunctionSpace(self.mesh, 'P', 1) self.source = da.Expression(("100*sin(2*pi*x[0])"), degree=3) # self.source = da.Expression("k*100*exp( (-(x[0]-x0)*(x[0]-x0) -(x[1]-x1)*(x[1]-x1)) / (2*0.01*l) )", # k=1, l=1, x0=0.9, x1=0.1, degree=3) # self.source = da.Constant(10) self.source = da.interpolate(self.source, self.V) boundary_fn_ext = da.Constant(1.) boundary_fn_int = da.Constant(1.) boundary_bc_ext = da.DirichletBC(self.V, boundary_fn_ext, self.exterior) boundary_bc_int = da.DirichletBC(self.V, boundary_fn_int, self.interior) self.bcs = [boundary_bc_ext, boundary_bc_int]
def set_bcs_staggered(self): self.upper.mark(self.boundaries, 1) self.presLoad = da.Expression((0, "t"), t=0.0, degree=1) BC_u_lower = da.DirichletBC(self.U, da.Constant((0., 0.)), self.lower) BC_u_upper = da.DirichletBC(self.U, self.presLoad, self.upper) BC_d_middle = fe.DirichletBC(self.W, fe.Constant(1.), self.middle, method='pointwise') self.BC_u = [BC_u_lower, BC_u_upper] self.BC_d = [BC_d_middle]
import fenics as fa import dolfin_adjoint as da import numpy as np import moola n = 64 alpha = da.Constant(0) mesh = da.UnitSquareMesh(n, n) # case_flag = 0 runs the default case by # http://www.dolfin-adjoint.org/en/latest/documentation/poisson-mother/poisson-mother.html # change to any other value runs the other case case_flag = 1 x = fa.SpatialCoordinate(mesh) w = da.Expression("sin(pi*x[0])*sin(pi*x[1])", degree=3) V = fa.FunctionSpace(mesh, "CG", 1) W = fa.FunctionSpace(mesh, "DG", 0) # g is the ground truth for source term # f is the control variable if case_flag == 0: g = da.interpolate( da.Expression("1/(1+alpha*4*pow(pi, 4))*w", w=w, alpha=alpha, degree=3), W) f = da.interpolate( da.Expression("1/(1+alpha*4*pow(pi, 4))*w", w=w, alpha=alpha, degree=3), W) else: g = da.interpolate(da.Expression(("sin(2*pi*x[0])"), degree=3), W)