def check_ass_penaro(bcsd=None, bcssfuns=None, V=None, plot=False): mesh = V.mesh() bcone = bcsd[1] contshfunone = bcssfuns[1] Gammaone = bcone() bparts = dolfin.MeshFunction('size_t', mesh, mesh.topology().dim() - 1) Gammaone.mark(bparts, 0) u = dolfin.TrialFunction(V) v = dolfin.TestFunction(V) # Robin boundary form arob = dolfin.inner(u, v) * dolfin.ds(0) brob = dolfin.inner(v, contshfunone) * dolfin.ds(0) amatrob = dolfin.assemble(arob, exterior_facet_domains=bparts) bmatrob = dolfin.assemble(brob, exterior_facet_domains=bparts) amatrob = dts.mat_dolfin2sparse(amatrob) amatrob.eliminate_zeros() print 'Number of nonzeros in amatrob:', amatrob.nnz bmatrob = bmatrob.array() # [ININDS] if plot: plt.figure(2) plt.spy(amatrob) if plot: plt.figure(1) for x in contshfunone.xs: plt.plot(x[0], x[1], 'bo') plt.show()
def check_ass_penaro(bcsd=None, bcssfuns=None, V=None, plot=False): mesh = V.mesh() bcone = bcsd[1] contshfunone = bcssfuns[1] Gammaone = bcone() bparts = dolfin.MeshFunction('size_t', mesh, mesh.topology().dim() - 1) Gammaone.mark(bparts, 0) u = dolfin.TrialFunction(V) v = dolfin.TestFunction(V) # Robin boundary form arob = dolfin.inner(u, v) * dolfin.ds(0) brob = dolfin.inner(v, contshfunone) * dolfin.ds(0) amatrob = dolfin.assemble(arob, exterior_facet_domains=bparts) bmatrob = dolfin.assemble(brob, exterior_facet_domains=bparts) amatrob = dts.mat_dolfin2sparse(amatrob) amatrob.eliminate_zeros() print('Number of nonzeros in amatrob:', amatrob.nnz) bmatrob = bmatrob.array() # [ININDS] if plot: plt.figure(2) plt.spy(amatrob) if plot: plt.figure(1) for x in contshfunone.xs: plt.plot(x[0], x[1], 'bo') plt.show()
def __init__(self, V, u, v, b, kappa, rho, cp, source, dirichlet_bcs=[], neumann_bcs={}, robin_bcs={}, dx=dx, ds=ds ): super(HeatCylindrical, self).__init__() self.dirichlet_bcs = dirichlet_bcs r = Expression('x[0]', degree=1, domain=V.mesh()) self.V = V self.dx_multiplier = 2*pi*r self.F0 = kappa * r * dot(grad(u), grad(v / (rho * cp))) \ * 2*pi * dx #F -= dot(b, grad(u)) * v * 2*pi*r * dx_workpiece(0) if b: self.F0 += (b[0] * u.dx(0) + b[1] * u.dx(1)) * v * 2*pi*r * dx # Joule heat self.F0 -= 1.0 / (rho * cp) * source * v * 2*pi*r * dx # Neumann boundary conditions for k, nGradT in neumann_bcs.iteritems(): self.F0 -= r * kappa * nGradT * v / (rho * cp) \ * 2 * pi * ds(k) # Robin boundary conditions for k, value in robin_bcs.iteritems(): alpha, u0 = value self.F0 -= r * kappa * alpha * (u - u0) * v / (rho * cp) \ * 2 * pi * ds(k) return
def solve(self, dt): self.u = Function(self.V0) self.w = TestFunction(self.V0) self.du = TrialFunction(self.V0) x = SpatialCoordinate(self.mesh0) L = inner( self.S(), self.eps(self.w) )*dx(degree=4)\ - inner( self.b, self.w )*dx(degree=4)\ - inner( self.h, self.w )*ds(degree=4)\ + inner( 1e-6*self.u, self.w )*ds(degree=4)\ - inner( min_value(x[2]+self.ut[2]+self.u[2], 0) * Constant((0,0,-1.0)), self.w )*ds(degree=4) a = derivative(L, self.u, self.du) problem = NonlinearVariationalProblem(L, self.u, bcs=[], J=a) solver = NonlinearVariationalSolver(problem) solver.solve() self.ut.vector()[:] = self.ut.vector()[:] + self.u.vector()[:] ALE.move(self.mesh, Function(self.V, self.u.vector())) self.v.vector()[:] = self.u.vector()[:] / dt self.n = FacetNormal(self.mesh)
def QoI_FEM(x0,y0,lam1,lam2,gridx,gridy,p): mesh = fn.UnitSquareMesh(gridx, gridy) V = fn.FunctionSpace(mesh, "Lagrange", p) # Define diffusion tensor (here, just a scalar function) and parameters A = fn.Expression((('exp(lam1)','a'), ('a','exp(lam2)')), a = fn.Constant(0.0), lam1 = lam1, lam2 = lam2, degree=3) u_exact = fn.Expression("sin(lam1*pi*x[0])*cos(lam2*pi*x[1])", lam1 = lam1, lam2 = lam2, degree=2+p) # Define the mix of Neumann and Dirichlet BCs class LeftBoundary(fn.SubDomain): def inside(self, x, on_boundary): return (x[0] < fn.DOLFIN_EPS) class RightBoundary(fn.SubDomain): def inside(self, x, on_boundary): return (x[0] > 1.0 - fn.DOLFIN_EPS) class TopBoundary(fn.SubDomain): def inside(self, x, on_boundary): return (x[1] > 1.0 - fn.DOLFIN_EPS) class BottomBoundary(fn.SubDomain): def inside(self, x, on_boundary): return (x[1] < fn.DOLFIN_EPS) # Create a mesh function (mf) assigning an unsigned integer ('uint') # to each edge (which is a "Facet" in 2D) mf = fn.MeshFunction('size_t', mesh, 1) mf.set_all(0) # initialize the function to be zero # Setup the boundary classes that use Neumann boundary conditions NTB = TopBoundary() # instatiate NTB.mark(mf, 1) # set all values of the mf to be 1 on this boundary NBB = BottomBoundary() NBB.mark(mf, 2) # set all values of the mf to be 2 on this boundary NRB = RightBoundary() NRB.mark(mf, 3) # Define Dirichlet boundary conditions Gamma_0 = fn.DirichletBC(V, u_exact, LeftBoundary()) bcs = [Gamma_0] # Define data necessary to approximate exact solution f = ( fn.exp(lam1)*(lam1*fn.pi)**2 + fn.exp(lam2)*(lam2*fn.pi)**2 ) * u_exact g1 = fn.Expression("-exp(lam2)*lam2*pi*sin(lam1*pi*x[0])*sin(lam2*pi*x[1])", lam1=lam1, lam2=lam2, degree=2+p) #pointing outward unit normal vector, pointing upaward (0,1) g2 = fn.Expression("exp(lam2)*lam2*pi*sin(lam1*pi*x[0])*sin(lam2*pi*x[1])", lam1=lam1, lam2=lam2, degree=2+p) #pointing downward (0,1) g3 = fn.Expression("exp(lam1)*lam1*pi*cos(lam1*pi*x[0])*cos(lam2*pi*x[1])", lam1=lam1, lam2=lam2, degree=2+p) fn.ds = fn.ds(subdomain_data=mf) # Define variational problem u = fn.TrialFunction(V) v = fn.TestFunction(V) a = fn.inner(A*fn.grad(u), fn.grad(v))*fn.dx L = f*v*fn.dx + g1*v*fn.ds(1) + g2*v*fn.ds(2) + g3*v*fn.ds(3) #note the 1, 2 and 3 correspond to the mf # Compute solution u = fn.Function(V) fn.solve(a == L, u, bcs) return u(x0,y0)
def conj_coef_fun(derJ, derJ_old, hol_cyl, boundary_faces, mark_in, mark_ex, time_v, cut_end, method, itera, path_to_do): ''' Conjugation coefficient. method = 'PR' (Polak-Ribière) or 'FR' (Fletcher-Reeves). ''' num_v = np.zeros(np.shape(time_v)) den_v = np.zeros(np.shape(time_v)) for count_t_i, t_i in enumerate(time_v): if method == 'PR': #Polak-Ribière method #scalar num_v[count_t_i] = do.assemble( derJ[count_t_i] * (derJ[count_t_i] - derJ_old[count_t_i]) * do.ds(mark_in, domain=hol_cyl, subdomain_data=boundary_faces)) elif method == 'FR': #Fletcher-Reeves method #scalar num_v[count_t_i] = do.assemble( pow(derJ[count_t_i], 2.) * do.ds(mark_in, domain=hol_cyl, subdomain_data=boundary_faces)) #scalar den_v[count_t_i] = do.assemble( pow(derJ_old[count_t_i], 2.) * do.ds(mark_in, domain=hol_cyl, subdomain_data=boundary_faces)) fig_inf = plt.figure(figsize=(20, 10)) ax_inf = fig_inf.add_subplot(211) ax_inf.plot(num_v, 'r.', label='num1') ax_inf.plot(den_v, 'b.', label='den1') ax_inf.legend() ax_inf = fig_inf.add_subplot(223) ax_inf.plot(num_v[:10], 'r.', label='num1') ax_inf.plot(den_v[:10], 'b.', label='den1') ax_inf.legend() ax_inf = fig_inf.add_subplot(224) ax_inf.plot(num_v[-10:], 'r.', label='num1') ax_inf.plot(den_v[-10:], 'b.', label='den1') ax_inf.legend() nam_inf = os.path.join(path_to_do, 'gamma_CG_{}_{}.pdf'.format(itera, method)) fig_inf.savefig(nam_inf, dpi=150) #integration num_gamma_CG = np.trapz(num_v[:cut_end], x=time_v[:cut_end]) den_gamma_CG = np.trapz(den_v[:cut_end], x=time_v[:cut_end]) #https://en.wikipedia.org/wiki/Nonlinear_conjugate_gradient_method gamma_CG = max(0., num_gamma_CG / den_gamma_CG) return gamma_CG
def create_bc(self): #Input G_rhs_inner, G_rhs_outer = self.inhomogeneity() local_bc = 0.0 df.ds = self.my_mesh_cls.ds #<---- Important local_bc += (-0.5 * df.inner(self.v,((self.BC1_rhs-self.BC2_rhs) \ * G_rhs_inner)) ) * df.ds(3000) #RHS-2 local_bc += (-0.5 * df.inner(self.v,((self.BC1_rhs-self.BC2_rhs)\ * G_rhs_outer)) ) * df.ds(3100) #RHS-2 return local_bc
def assemble_lui_stiffness(self, g, f, mesh, robin_boundary): V = FunctionSpace(mesh, "Lagrange", self.p) u = TrialFunction(V) v = TestFunction(V) n = FacetNormal(mesh) robin = MeshFunction('size_t', mesh, mesh.topology().dim() - 1) robin_boundary.mark(robin, 1) ds = Measure('ds', subdomain_data=robin) a = inner(grad(u), grad(v)) * dx b = (1 - g) * (inner(grad(u), n)) * v * ds(1) c = f * u * v * ds(1) k = lhs(a + b - c) K = PETScMatrix() assemble(k, tensor=K) return K, V
def V0constrainedE(self,inverse=False): mesh = self.parameters["mesh"] u = self.parameters["displacement_variable"] ds = dolfin.ds(subdomain_data=self.parameters["facetboundaries"]) dsendo = ds(self.parameters["endoid"], domain = self.parameters["mesh"], subdomain_data = self.parameters["facetboundaries"]) pendo = self.parameters["volconst_variable"] V0= self.parameters["constrained_vol"] X = SpatialCoordinate(mesh) x = u + X F = self.Fmat() N = self.parameters["facet_normal"] n = cofac(F)*N area = assemble(Constant(1.0) * dsendo) if inverse: V_u = - Constant(0.0/3.0) * inner(x, n) Wvol = (Constant(0.0/area) * pendo * V0 * dsendo) - (pendo * V_u *dsendo) else: V_u = - Constant(1.0/3.0) * inner(x, n) Wvol = (Constant(1.0/area) * pendo * V0 * dsendo) - (pendo * V_u *dsendo) return Wvol
def __init__(self, U_m, mesh): """Function spaces and BCs""" V = VectorFunctionSpace(mesh, 'P', 2) Q = FunctionSpace(mesh, 'P', 1) self.mesh = mesh self.vu, self.vp = TestFunction(V), TestFunction(Q) # for integration self.u_, self.p_ = Function(V), Function(Q) # for the solution self.u_1, self.p_1 = Function(V), Function(Q) # for the prev. solution self.u_k, self.p_k = Function(V), Function(Q) # for the prev. solution self.u, self.p = TrialFunction(V), TrialFunction(Q) # unknown! U0_str = "4.*U_m*x[1]*(.41-x[1])/(.41*.41)" x = [0, .41 / 2] # evaluate the Expression at the center of the channel self.U_mean = np.mean(2 / 3 * eval(U0_str)) U0 = Expression((U0_str, "0"), U_m=U_m, degree=2) bc0 = DirichletBC(V, Constant((0, 0)), cylinderwall) bc1 = DirichletBC(V, Constant((0, 0)), topandbottom) bc2 = DirichletBC(V, U0, inlet) bc3 = DirichletBC(Q, Constant(0), outlet) self.bcu = [bc0, bc1, bc2] self.bcp = [bc3] # ds is needed to compute drag and lift. ASD1 = AutoSubDomain(topandbottom) ASD2 = AutoSubDomain(cylinderwall) mf = MeshFunction("size_t", mesh, 1) mf.set_all(0) ASD1.mark(mf, 1) ASD2.mark(mf, 2) self.ds_ = ds(subdomain_data=mf, domain=mesh) return
def main(): fsr = FunctionSubspaceRegistry() deg = 2 mesh = dolfin.UnitSquareMesh(100, 3) muc = mesh.ufl_cell() el_w = dolfin.FiniteElement('DG', muc, deg - 1) el_j = dolfin.FiniteElement('BDM', muc, deg) el_DG0 = dolfin.FiniteElement('DG', muc, 0) el = dolfin.MixedElement([el_w, el_j]) space = dolfin.FunctionSpace(mesh, el) DG0 = dolfin.FunctionSpace(mesh, el_DG0) fsr.register(space) facet_normal = dolfin.FacetNormal(mesh) xyz = dolfin.SpatialCoordinate(mesh) trial = dolfin.Function(space) test = dolfin.TestFunction(space) w, c = dolfin.split(trial) v, phi = dolfin.split(test) sympy_exprs = derive_exprs() exprs = { k: sympy_dolfin_printer.to_ufl(sympy_exprs['R'], mesh, v) for k, v in sympy_exprs['quantities'].items() } f = exprs['f'] w0 = dolfin.project(dolfin.conditional(dolfin.gt(xyz[0], 0.5), 1.0, 0.3), DG0) w_BC = exprs['w'] dx = dolfin.dx() form = (+v * dolfin.div(c) * dx - v * f * dx + dolfin.exp(w + w0) * dolfin.dot(phi, c) * dx + dolfin.div(phi) * w * dx - (w_BC - w0) * dolfin.dot(phi, facet_normal) * dolfin.ds() - (w0('-') - w0('+')) * dolfin.dot(phi('+'), facet_normal('+')) * dolfin.dS()) solver = NewtonSolver(form, trial, [], parameters=dict(relaxation_parameter=1.0, maximum_iterations=15, extra_iterations=10, relative_tolerance=1e-6, absolute_tolerance=1e-7)) solver.solve() with closing(XdmfPlot("out/qflop_test.xdmf", fsr)) as X: CG1 = dolfin.FunctionSpace(mesh, dolfin.FiniteElement('CG', muc, 1)) X.add('w0', 1, w0, CG1) X.add('w_c', 1, w + w0, CG1) X.add('w_e', 1, exprs['w'], CG1) X.add('f', 1, f, CG1) X.add('cx_c', 1, c[0], CG1) X.add('cx_e', 1, exprs['c'][0], CG1)
def test_store_mesh(casedir): pp = PostProcessor(dict(casedir=casedir)) from dolfin import (UnitSquareMesh, CellFunction, FacetFunction, AutoSubDomain, Mesh, HDF5File, assemble, Expression, ds, dx) # Store mesh mesh = UnitSquareMesh(6, 6) celldomains = CellFunction("size_t", mesh) celldomains.set_all(0) AutoSubDomain(lambda x: x[0] < 0.5).mark(celldomains, 1) facetdomains = FacetFunction("size_t", mesh) AutoSubDomain(lambda x, on_boundary: x[0] < 0.5 and on_boundary).mark( facetdomains, 1) pp.store_mesh(mesh, celldomains, facetdomains) # Read mesh back mesh2 = Mesh() f = HDF5File(mpi_comm_world(), os.path.join(pp.get_casedir(), "mesh.hdf5"), 'r') f.read(mesh2, "Mesh", False) celldomains2 = CellFunction("size_t", mesh2) f.read(celldomains2, "CellDomains") facetdomains2 = FacetFunction("size_t", mesh2) f.read(facetdomains2, "FacetDomains") e = Expression("1+x[1]", degree=1) dx1 = dx(1, domain=mesh, subdomain_data=celldomains) dx2 = dx(1, domain=mesh2, subdomain_data=celldomains2) C1 = assemble(e * dx1) C2 = assemble(e * dx2) assert abs(C1 - C2) < 1e-10 ds1 = ds(1, domain=mesh, subdomain_data=facetdomains) ds2 = ds(1, domain=mesh2, subdomain_data=facetdomains2) F1 = assemble(e * ds1) F2 = assemble(e * ds2) assert abs(F1 - F2) < 1e-10
def navier_stokes_IPCS(mesh, dt, parameter): """ fenics code: weak form of the problem. """ mu, rho, nu = parameter V = VectorFunctionSpace(mesh, 'P', 2) Q = FunctionSpace(mesh, 'P', 1) bc0 = DirichletBC(V, Constant((0, 0)), cylinderwall) bc1 = DirichletBC(V, Constant((0, 0)), topandbottom) bc2 = DirichletBC(V, U0, inlet) bc3 = DirichletBC(Q, Constant(1), outlet) bcs = [bc0, bc1, bc2, bc3] # ds is needed to compute drag and lift. Not used here. ASD1 = AutoSubDomain(topandbottom) ASD2 = AutoSubDomain(cylinderwall) mf = MeshFunction("size_t", mesh, 1) mf.set_all(0) ASD1.mark(mf, 1) ASD2.mark(mf, 2) ds_ = ds(subdomain_data=mf, domain=mesh) vu, vp = TestFunction(V), TestFunction(Q) # for integration u_, p_ = Function(V), Function(Q) # for the solution u_1, p_1 = Function(V), Function(Q) # for the prev. solution u, p = TrialFunction(V), TrialFunction(Q) # unknown! bcu = [bcs[0], bcs[1], bcs[2]] bcp = [bcs[3]] n = FacetNormal(mesh) u_mid = (u + u_1) / 2.0 F1 = rho*dot((u - u_1) / dt, vu)*dx \ + rho*dot(dot(u_1, nabla_grad(u_1)), vu)*dx \ + inner(sigma(u_mid, p_1, mu), epsilon(vu))*dx \ + dot(p_1*n, vu)*ds - dot(mu*nabla_grad(u_mid)*n, vu)*ds a1 = lhs(F1) L1 = rhs(F1) # Define variational problem for step 2 a2 = dot(nabla_grad(p), nabla_grad(vp)) * dx L2 = dot(nabla_grad(p_1), nabla_grad(vp)) * dx - ( rho / dt) * div(u_) * vp * dx # rho missing in FEniCS tutorial # Define variational problem for step 3 a3 = dot(u, vu) * dx L3 = dot(u_, vu) * dx - dt * dot(nabla_grad(p_ - p_1), vu) * dx # Assemble matrices A1 = assemble(a1) A2 = assemble(a2) A3 = assemble(a3) # Apply boundary conditions to matrices [bc.apply(A1) for bc in bcu] [bc.apply(A2) for bc in bcp] return u_, p_, u_1, p_1, L1, A1, L2, A2, L3, A3, bcu, bcp
def cavityvol(self): u = self.parameters["displacement_variable"] N = self.parameters["facet_normal"] mesh = self.parameters["mesh"] X = SpatialCoordinate(mesh) ds = dolfin.ds(subdomain_data=self.parameters["facetboundaries"]) F = self.Fmat() vol_form = -Constant(1.0/3.0) * inner(det(F)*dot(inv(F).T, N), X + u)*ds(self.parameters["endoid"]) return assemble(vol_form)
def set_FEM(self): """ Define finite element space of elliptic PDE. """ self.mesh = df.UnitSquareMesh(self.nx, self.ny) self.mpi_comm = self.mesh.mpi_comm() # boundaries self.boundaries = df.FacetFunction("size_t", self.mesh, 0) self.ds = df.ds(subdomain_data=self.boundaries) # 2. Define the finite element spaces and build mixed space try: V_fe = df.FiniteElement("CG", self.mesh.ufl_cell(), 2) L_fe = df.FiniteElement("CG", self.mesh.ufl_cell(), 2) self.V = df.FunctionSpace(self.mesh, V_fe) self.W = df.FunctionSpace(self.mesh, V_fe * L_fe) except TypeError: print('Warning: ' 'MixedFunctionSpace' ' has been deprecated in DOLFIN version 1.7.0.') print('It will be removed from version 2.0.0.') self.V = df.FunctionSpace(self.mesh, 'CG', 2) L = df.FunctionSpace(self.mesh, 'CG', 2) self.W = self.V * L # 3. Define boundary conditions bc_lagrange = df.DirichletBC( self.W.sub(1), df.Constant(0.0), "fabs(x[0])>2.0*DOLFIN_EPS & fabs(x[0]-1.0)>2.0*DOLFIN_EPS & fabs(x[1])>2.0*DOLFIN_EPS & fabs(x[1]-1.0)>2.0*DOLFIN_EPS" ) self.ess_bc = [bc_lagrange] # Create adjoint boundary conditions (homogenized forward BCs) def homogenize(bc): bc_copy = df.DirichletBC(bc) bc_copy.homogenize() return bc_copy self.adj_bcs = [homogenize(bc) for bc in self.ess_bc]
def compute(self, get): u = get("Velocity") mu = get("DynamicViscosity") if isinstance(mu, (float, int)): mu = Constant(mu) n = self._n T = -mu*dot((grad(u) + grad(u).T), n) Tn = dot(T, n) Tt = T - Tn*n tau_form = dot(self.v, Tt)*ds() assemble(tau_form, tensor=self.tau.vector()) #self.b[self._keys] = self.tau.vector()[self._values] # FIXME: This is not safe!!! get_set_vector(self.b, self._keys, self.tau.vector(), self._values, self._temp_array) # Ensure proper scaling self.solver.solve(self.tau_boundary.vector(), self.b) return self.tau_boundary
def compute(self, get): u = get("Velocity") mu = get("DynamicViscosity") if isinstance(mu, (float, int)): mu = Constant(mu) n = self._n T = -mu * dot((grad(u) + grad(u).T), n) Tn = dot(T, n) Tt = T - Tn * n tau_form = dot(self.v, Tt) * ds() assemble(tau_form, tensor=self.tau.vector()) #self.b[self._keys] = self.tau.vector()[self._values] # FIXME: This is not safe!!! get_set_vector(self.b, self._keys, self.tau.vector(), self._values, self._temp_array) # Ensure proper scaling self.solver.solve(self.tau_boundary.vector(), self.b) return self.tau_boundary
def setup_problem(mesh, U0, coupled=True): # Build function space V = VectorFunctionSpace(mesh, 'P', 2) Q = FunctionSpace(mesh, 'P', 1) L = FunctionSpace(mesh, 'P', 1) VQL = (V, Q, L) # bc0 = DirichletBC(V, Constant((0, 0)), cylinderwall) bc1 = DirichletBC(V, Constant((0, 0)), topandbottom) bc2 = DirichletBC(V, U0, inlet) bc3 = DirichletBC(Q, Constant(1), outlet) # bcs = [bc0, bc1, bc2, bc3] bcs = [bc1, bc2, bc3] warnings.warn("no no-slip for cyl-wall!") ASD1 = AutoSubDomain(topandbottom) ASD2 = AutoSubDomain(cylinderwall) mf = MeshFunction("size_t", mesh, 1) mf.set_all(0) ASD1.mark(mf, 1) ASD2.mark(mf, 2) ds_ = ds(subdomain_data=mf, domain=mesh) return VQL, bcs, ds_
def ds(self): """Return the surface measure of exterior facets using self.mesh as domain and self.ffun as subdomain_data """ return dolfin.ds(domain=self.mesh, subdomain_data=self.ffun)
def solve(self): """ Find eigenvalues for transformed mesh. """ self.progress("Building mesh.") # build transformed mesh mesh = self.refineMesh() # dim = mesh.topology().dim() if self.bcLast: mesh = transform_mesh(mesh, self.transformList) Robin, Steklov, shift, bcs = get_bc_parts(mesh, self.bcList) else: Robin, Steklov, shift, bcs = get_bc_parts(mesh, self.bcList) mesh = transform_mesh(mesh, self.transformList) # boundary conditions computed on non-transformed mesh # copy the values to transformed mesh fun = FacetFunction("size_t", mesh, shift) fun.array()[:] = bcs.array()[:] bcs = fun ds = Measure('ds', domain=mesh, subdomain_data=bcs) V = FunctionSpace(mesh, self.method, self.deg) u = TrialFunction(V) v = TestFunction(V) self.progress("Assembling matrices.") wTop = Expression(self.wTop, degree=self.deg) wBottom = Expression(self.wBottom, degree=self.deg) # # build stiffness matrix form # s = dot(grad(u), grad(v))*wTop*dx # add Robin parts for bc in Robin: s += Constant(bc.parValue)*u*v*wTop*ds(bc.value+shift) # # build mass matrix form # if len(Steklov) > 0: m = 0 for bc in Steklov: m += Constant(bc.parValue)*u*v*wBottom*ds(bc.value+shift) else: m = u*v*wBottom*dx # assemble # if USE_EIGEN: # S, M = EigenMatrix(), EigenMatrix() # tempv = EigenVector() # else: S, M = PETScMatrix(), PETScMatrix() # tempv = PETScVector() if not np.any(bcs.array() == shift+1): # no Dirichlet parts assemble(s, tensor=S) assemble(m, tensor=M) else: # # with EIGEN we could # apply Dirichlet condition symmetrically # completely remove rows and columns # # Dirichlet parts are marked with shift+1 # # temp = Constant(0)*v*dx bc = DirichletBC(V, Constant(0.0), bcs, shift+1) # assemble_system(s, temp, bc, A_tensor=S, b_tensor=tempv) # assemble_system(m, temp, bc, A_tensor=M, b_tensor=tempv) assemble(s, tensor=S) bc.apply(S) assemble(m, tensor=M) # bc.zero(M) # if USE_EIGEN: # M = M.sparray() # M.eliminate_zeros() # print M.shape # indices = M.indptr[:-1] - M.indptr[1:] < 0 # M = M[indices, :].tocsc()[:, indices] # S = S.sparray()[indices, :].tocsc()[:, indices] # print M.shape # # solve the eigenvalue problem # self.progress("Solving eigenvalue problem.") eigensolver = SLEPcEigenSolver(S, M) eigensolver.parameters["problem_type"] = "gen_hermitian" eigensolver.parameters["solver"] = "krylov-schur" if self.target is not None: eigensolver.parameters["spectrum"] = "target real" eigensolver.parameters["spectral_shift"] = self.target else: eigensolver.parameters["spectrum"] = "smallest magnitude" eigensolver.parameters["spectral_shift"] = -0.01 eigensolver.parameters["spectral_transform"] = "shift-and-invert" eigensolver.solve(self.number) self.progress("Generating eigenfunctions.") if eigensolver.get_number_converged() == 0: return None eigf = [] eigv = [] if self.deg > 1: mesh = refine(mesh) W = FunctionSpace(mesh, 'CG', 1) for i in range(eigensolver.get_number_converged()): pair = eigensolver.get_eigenpair(i)[::2] eigv.append(pair[0]) u = Function(V) u.vector()[:] = pair[1] eigf.append(interpolate(u, W)) return eigv, eigf
def main(): L = 10.0 H = 10.0 mesh = df.UnitSquare(10,10,'left') mesh.coordinates()[:,0] *= L mesh.coordinates()[:,1] *= H U = df.VectorFunctionSpace(mesh, "Lagrange", 1, dim=2) U_x, U_y = U.split() u = df.TrialFunction(U) v = df.TestFunction(U) E = 2.0E11 nu = 0.3 lmbda = nu*E/((1.0 + nu)*(1.0 - 2.0*nu)) mu = E/(2.0*(1.0 + nu)) # Elastic Modulus C_numpy = np.array([[lmbda + 2.0*mu, lmbda, 0.0], [lmbda, lmbda + 2.0*mu, 0.0], [0.0, 0.0, mu ]]) C = df.as_matrix(C_numpy) from dolfin import dot, dx, grad, inner, ds def eps(u): """ Returns a vector of strains of size (3,1) in the Voigt notation layout {eps_xx, eps_yy, gamma_xy} where gamma_xy = 2*eps_xy""" return df.as_vector([u[i].dx(i) for i in range(2)] + [u[i].dx(j) + u[j].dx(i) for (i,j) in [(0,1)]]) a = inner(eps(v), C*eps(u))*dx A = a # Dirichlet BC class LeftBoundary(df.SubDomain): def inside(self, x, on_boundary): tol = 1E-14 return on_boundary and np.abs(x[0]) < tol class RightBoundary(df.SubDomain): def inside(self, x, on_boundary): tol = 1E-14 return on_boundary and np.abs(x[0] - self.L) < tol class BottomBoundary(df.SubDomain): def inside(self, x, on_boundary): tol = 1E-14 return on_boundary and np.abs(x[1]) < tol left_boundary = LeftBoundary() right_boundary = RightBoundary() right_boundary.L = L bottom_boundary = BottomBoundary() zero = df.Constant(0.0) bc_left_Ux = df.DirichletBC(U_x, zero, left_boundary) bc_bottom_Uy = df.DirichletBC(U_y, zero, bottom_boundary) bcs = [bc_left_Ux, bc_bottom_Uy] # Neumann BCs t = df.Constant(10000.0) boundary_parts = df.EdgeFunction("uint", mesh, 1) right_boundary.mark(boundary_parts, 0) l = inner(t,v[0])*ds(0) u_h = df.Function(U) problem = df.LinearVariationalProblem(A, l, u_h, bcs=bcs) solver = df.LinearVariationalSolver(problem) solver.parameters["linear_solver"] = "direct" solver.solve() u_x, u_y = u_h.split() stress = df.project(C*eps(u_h), df.VectorFunctionSpace(mesh, "Lagrange", 1, dim=3)) df.plot(u_x) df.plot(u_y) df.plot(stress[0]) df.interactive()
def ds(self): """Returns the mesh surface measure using `self.ffun` as `subdomain_data` """ return df.ds(domain=self.mesh, subdomain_data=self.ffun)
def gamma_fun( v, hol_cyl, T_step_d, #from direct pbm boundary_faces, mark_in, mark_ex, T_ex_d, g_d, gamma_reg0, #the old gamma_reg omegac, #contraction factor muc, itera_div, unitNormal, time_v, cut_end, itera, path_to_do): ''' Returns the optimal regularization parameter. T_step from direct problem. ''' num1_v = np.zeros((len(T_step_d), )) num2_v = np.zeros((len(T_step_d), )) num3_v = np.zeros((len(T_step_d), )) den1_v = np.zeros((len(T_step_d), )) for count_it in sorted(T_step_d): #scalar num1_v[count_it] = do.assemble( pow(T_step_d[count_it] - T_ex_d[count_it], 2.) * do.ds(mark_ex, domain=hol_cyl, subdomain_data=boundary_faces)) num2_v[count_it] = do.assemble( pow(T_step_d[count_it], 2.) * do.ds(mark_ex, domain=hol_cyl, subdomain_data=boundary_faces)) num3_v[count_it] = do.assemble( pow(T_ex_d[count_it], 2.) * do.ds(mark_ex, domain=hol_cyl, subdomain_data=boundary_faces)) #scalar den1_v[count_it] = do.assemble( pow(g_d[count_it], 2.) * do.ds(mark_in, domain=hol_cyl, subdomain_data=boundary_faces)) print 'gamma: count_t = {}, num1 = {}'.format(count_it, num1_v[count_it]) print 'gamma: count_t = {}, den1 = {}'.format(count_it, den1_v[count_it]), '\n' fig_inf = plt.figure(figsize=(20, 10)) for i_fig in xrange(12): vari = 1. * num1_v * (i_fig / 3 == 0) + \ 1. * num2_v * (i_fig / 3 == 1) + \ 1. * num3_v * (i_fig / 3 == 2) + \ 1. * den1_v * (i_fig / 3 == 3) ytag = 'num1' * (i_fig / 3 == 0) + \ 'num2' * (i_fig / 3 == 1) + \ 'num3' * (i_fig / 3 == 2) + \ 'den1' * (i_fig / 3 == 3) stai = 0 * (i_fig % 3 == 0) + \ 0 * (i_fig % 3 == 1) + \ -50 * (i_fig % 3 == 2) endi = len(vari) * (i_fig % 3 == 0) + \ 50 * (i_fig % 3 == 1) + \ len(vari) * (i_fig % 3 == 2) ax_inf = fig_inf.add_subplot(4, 3, i_fig + 1) ax_inf.plot(vari[stai:endi]) ax_inf.set_ylabel(ytag) ax_inf.grid() nam_inf = os.path.join(path_to_do, 'gamma_{}.pdf'.format(itera)) fig_inf.savefig(nam_inf, dpi=150) #num1_avg = np.trapz(num1_v[5 : -5], x = time_v[5 : -5]) #den1_avg = np.trapz(den1_v[5 : -5], x = time_v[5 : -5]) num1_avg = np.trapz(num1_v[:cut_end], x=time_v[:cut_end]) num2_avg = np.trapz(num2_v[:cut_end], x=time_v[:cut_end]) num3_avg = np.trapz(num3_v[:cut_end], x=time_v[:cut_end]) den1_avg = np.trapz(den1_v[:cut_end], x=time_v[:cut_end]) if itera > itera_div: #divisions are allowed C_avg = -1. / den1_avg * (num2_avg + gamma_reg0 * den1_avg)**2. T_avg = num2_avg / den1_avg #Eq. (2.10) in Heng's paper aH = 2. * muc * num3_avg bH = +(2. + 4. * muc) * C_avg cH = -(2. + 2. * muc) * C_avg * T_avg x10 = (-bH + (bH**2. - 4. * aH * cH)**.5) / (2. * aH) x20 = (-bH - (bH**2. - 4. * aH * cH)**.5) / (2. * aH) x11 = x10 - T_avg x21 = x20 - T_avg if x11 > 1e-14 and x21 > 1e-14: #Two positive roots #take the smaller one gamma_reg = min(x11, x21) else: #Remark 3.8 in Heng's paper #restart gamma_reg = -omegac * (T_avg + cH / bH + aH / bH * (T_avg + gamma_reg0)**2.) gamma_reg_unused = 2. * num1_avg / den1_avg else: #divisions are not allowed gamma_reg = 1. * gamma_reg0 gamma_reg_unused = 1. * gamma_reg0 return gamma_reg, gamma_reg_unused, \ num1_avg, num2_avg, num3_avg, den1_avg
def nablau_fun( V, v, hol_cyl, A, boundary_faces, mark_in, dg_d, #S_in k_mesh_old, cp_mesh_old, rho_mesh_old, dt, time_v, theta, itera): ''' Sensitivity problem. Solves A u = L. A = dt * theta * k_mesh * do.dot(do.grad(T), do.grad(v)) * do.dx(domain = hol_cyl) + \ rho_mesh * cp_mesh * T * v * do.dx(domain = hol_cyl) Solved after setting dg_in = p^k. ''' #solver parameters #linear solvers from #list_linear_solver_methods() #preconditioners from #do.list_krylov_solver_preconditioners() solver = do.KrylovSolver('gmres', 'ilu') do.info(solver.parameters, False) #prints default values solver.parameters['relative_tolerance'] = 1e-13 solver.parameters['maximum_iterations'] = 200000 solver.parameters['monitor_convergence'] = True #on the screen #http://fenicsproject.org/qa/1124/ #is-there-a-way-to-set-the-inital-guess-in-the-krylov-solver '''solver.parameters['nonzero_initial_guess'] = True''' #solver.parameters['absolute_tolerance'] = 1e-15 #uses whatever in q_v as my initial condition #starts from 0 #u_stept = do.TrialFunction(V) u_step3 = do.Function(V) #starts from 0 u_old = do.Function(V) u_step3_d = {} theta = do.Constant(theta) dt = do.Constant(dt) #A = dt / 2. * k_mesh_old * do.dot(do.grad(u_stept), do.grad(v)) * do.dx(domain = hol_cyl) + \ # rho_mesh_old * cp_mesh_old * u_stept * v * do.dx(domain = hol_cyl) for count_t_i, t_i in enumerate(time_v[1:]): #storage u_step3_d[count_t_i] = do.Function(V) u_step3_d[count_t_i].vector()[:] = u_step3.vector().array() #int_fluxT_ex = 0 int_fluxT_in = dg_d[count_t_i + 1] * v * do.ds( mark_in, domain=hol_cyl, subdomain_data=boundary_faces) int_fluxT_in_old = dg_d[count_t_i] * v * do.ds( mark_in, domain=hol_cyl, subdomain_data=boundary_faces) #L -= (int_fluxT_in + int_fluxT_ex) L_old = -dt * (1. - theta) * k_mesh_old * do.dot(do.grad(u_old), do.grad(v)) * \ do.dx(domain = hol_cyl) + \ rho_mesh_old * cp_mesh_old * u_old * v * do.dx(domain = hol_cyl) L = L_old + (dt * theta * int_fluxT_in + dt * (1. - theta) * int_fluxT_in_old) do.solve(A == L, u_step3) print 'u: count_t = {}, min(dg) = {}'.format( count_t_i, min(dg_d[count_t_i].vector().array())) print 'u: count_t = {}, max(dg) = {}'.format( count_t_i, max(dg_d[count_t_i].vector().array())) print 'u: count_t = {}, min(int_fluxT_in) = {}'.format( count_t_i, min(do.assemble(int_fluxT_in).array())) print 'u: count_t = {}, max(int_fluxT_in) = {}'.format( count_t_i, max(do.assemble(int_fluxT_in).array())) print 'u: count_t = {}, min(L) = {}'.format( count_t_i, min(do.assemble(L).array())) print 'u: count_t = {}, max(L) = {}'.format( count_t_i, max(do.assemble(L).array())) print 'u: count_t = {}, min(u) = {}'.format( count_t_i, min(u_step3.vector().array())) print 'u: count_t = {}, max(u) = {}'.format( count_t_i, max(u_step3.vector().array())), '\n' u_old.assign(u_step3) count_t_i += 1 #storage u_step3_d[count_t_i] = do.Function(V) u_step3_d[count_t_i].vector()[:] = u_step3.vector().array() return u_step3_d
def transport_linear(integrator_type, mesh, subdomains, boundaries, t_start, dt, T, solution0, \ alpha_0, K_0, mu_l_0, lmbda_l_0, Ks_0, \ alpha_1, K_1, mu_l_1, lmbda_l_1, Ks_1, \ alpha, K, mu_l, lmbda_l, Ks, \ cf_0, phi_0, rho_0, mu_0, k_0,\ cf_1, phi_1, rho_1, mu_1, k_1,\ cf, phi, rho, mu, k, \ d_0, d_1, d_t, vel_c, p_con, A_0, Temp, c_extrapolate): # Create mesh and define function space parameters["ghost_mode"] = "shared_facet" # required by dS dx = Measure('dx', domain=mesh, subdomain_data=subdomains) ds = Measure('ds', domain=mesh, subdomain_data=boundaries) dS = Measure('dS', domain=mesh, subdomain_data=boundaries) C_cg = FiniteElement("CG", mesh.ufl_cell(), 1) C_dg = FiniteElement("DG", mesh.ufl_cell(), 0) mini = C_cg + C_dg C = FunctionSpace(mesh, mini) C = BlockFunctionSpace([C]) TM = TensorFunctionSpace(mesh, 'DG', 0) PM = FunctionSpace(mesh, 'DG', 0) n = FacetNormal(mesh) vc = CellVolume(mesh) fc = FacetArea(mesh) h = vc / fc h_avg = (vc('+') + vc('-')) / (2 * avg(fc)) penalty1 = Constant(1.0) tau = Function(PM) tau = tau_cal(tau, phi, -0.5) tuning_para = 0.25 vel_norm = (dot(vel_c, n) + abs(dot(vel_c, n))) / 2.0 cell_size = CellDiameter(mesh) vnorm = sqrt(dot(vel_c, vel_c)) I = Identity(mesh.topology().dim()) d_eff = Function(TM) d_eff = diff_coeff_cal_rev(d_eff, d_0, tau, phi) + tuning_para * cell_size * vnorm * I monitor_dt = dt # Define variational problem dc, = BlockTrialFunction(C) dc_dot, = BlockTrialFunction(C) psic, = BlockTestFunction(C) block_c = BlockFunction(C) c, = block_split(block_c) block_c_dot = BlockFunction(C) c_dot, = block_split(block_c_dot) theta = -1.0 a_time = phi * rho * inner(c_dot, psic) * dx a_dif = dot(rho*d_eff*grad(c),grad(psic))*dx \ - dot(avg_w(rho*d_eff*grad(c),weight_e(rho*d_eff,n)), jump(psic, n))*dS \ + theta*dot(avg_w(rho*d_eff*grad(psic),weight_e(rho*d_eff,n)), jump(c, n))*dS \ + penalty1/h_avg*k_e(rho*d_eff,n)*dot(jump(c, n), jump(psic, n))*dS a_adv = -dot(rho*vel_c*c,grad(psic))*dx \ + dot(jump(psic), rho('+')*vel_norm('+')*c('+') - rho('-')*vel_norm('-')*c('-') )*dS \ + dot(psic, rho*vel_norm*c)*ds(3) R_c = R_c_cal(c_extrapolate, p_con, Temp) c_D1 = Constant(0.5) rhs_c = R_c * A_s_cal(phi, phi_0, A_0) * psic * dx - dot( rho * phi * vel_c, n) * c_D1 * psic * ds(1) r_u = [a_dif + a_adv] j_u = block_derivative(r_u, [c], [dc]) r_u_dot = [a_time] j_u_dot = block_derivative(r_u_dot, [c_dot], [dc_dot]) r = [r_u_dot[0] + r_u[0] - rhs_c] # this part is not applied. exact_solution_expression1 = Expression("1.0", t=0, element=C[0].ufl_element()) def bc(t): p5 = DirichletBC(C.sub(0), exact_solution_expression1, boundaries, 1, method="geometric") return BlockDirichletBC([p5]) # Define problem wrapper class ProblemWrapper(object): def set_time(self, t): pass # Residual and jacobian functions def residual_eval(self, t, solution, solution_dot): return r def jacobian_eval(self, t, solution, solution_dot, solution_dot_coefficient): return [[ Constant(solution_dot_coefficient) * j_u_dot[0, 0] + j_u[0, 0] ]] # Define boundary condition def bc_eval(self, t): pass # Define initial condition def ic_eval(self): return solution0 # Define custom monitor to plot the solution def monitor(self, t, solution, solution_dot): pass problem_wrapper = ProblemWrapper() (solution, solution_dot) = (block_c, block_c_dot) solver = TimeStepping(problem_wrapper, solution, solution_dot) solver.set_parameters({ "initial_time": t_start, "time_step_size": dt, "monitor": { "time_step_size": monitor_dt, }, "final_time": T, "exact_final_time": "stepover", "integrator_type": integrator_type, "problem_type": "linear", "linear_solver": "mumps", "report": True }) export_solution = solver.solve() return export_solution, T
def __ufl_forms(self, nu, f): (w, q, wbar, qbar) = self.__test_functions() (u, p, ubar, pbar) = self.__trial_functions() # Infer geometric dimension zero_vec = np.zeros(self.gdim) ds = self.ds n = self.n he = self.he alpha = self.alpha h_d = self.h_d beta_stab = self.beta_stab facet_integral = self.facet_integral pI = p * Identity( self.mixedL.sub(1).ufl_cell().topological_dimension()) pbI = pbar * \ Identity(self.mixedL.sub(1).ufl_cell().topological_dimension()) # Upper left block # Contribution comes from local momentum balance AB = inner(2*nu*sym(grad(u)), grad(w))*dx \ + facet_integral(dot(-2*nu*sym(grad(u))*n + (2*nu*alpha/he)*u, w)) \ + facet_integral(dot(-2*nu*u, sym(grad(w))*n)) \ - inner(pI, grad(w))*dx # Contribution comes from local mass balance BtF = -dot(q, div(u))*dx - \ facet_integral(beta_stab*he/(nu+1)*dot(p, q)) A_S = AB + BtF # Upper right block # Contribution from local momentum CD = facet_integral(-alpha/he*2*nu*inner(ubar, w)) \ + facet_integral(2*nu*inner(ubar, sym(grad(w))*n)) \ + facet_integral(dot(pbI*n, w)) H = facet_integral(beta_stab * he / (nu + 1) * dot(pbar, q)) G_S = CD + H # Transpose block CDT = facet_integral(- alpha/he*2*nu*inner(wbar, u)) \ + facet_integral(2*nu*inner(wbar, sym(grad(u))*n)) \ + facet_integral(qbar * dot(u, n)) HT = facet_integral(beta_stab * he / (nu + 1) * dot(p, qbar)) G_ST = CDT + HT # Lower right block, penalty on ds(98) approximates free-slip KL = facet_integral(alpha/he * 2 * nu*dot(ubar, wbar)) \ - facet_integral(dot(pbar*n, wbar)) \ + Constant(1E12)/he * inner(outer(ubar, wbar), outer(n, n)) * ds(98) LtP = - facet_integral(dot(ubar, n)*qbar) \ - facet_integral(beta_stab*he/(nu+1) * pbar * qbar) B_S = KL + LtP # Righthandside Q_S = dot(f, w) * dx S_S = facet_integral(dot(Constant(zero_vec), wbar)) S_S += dot(h_d[0], wbar) * ds(99) + dot(h_d[1], wbar) * ds( 100) #Neumann BC return { 'A_S': A_S, 'G_S': G_S, 'G_ST': G_ST, 'B_S': B_S, 'Q_S': Q_S, 'S_S': S_S }
boundary_markers = dolfin.MeshFunction('size_t', mesh, boundary_dim) boundary_markers.set_all(0) # Assign all elements the default value id_subdomain_fix = 1 # Fixed boundary id id_subdomain_msr = 2 # Loaded boundary id id_subdomains_dic = 3 # displacement field measurement boundary id boundary_fix.mark(boundary_markers, id_subdomain_fix) boundary_msr.mark(boundary_markers, id_subdomain_msr) boundary_dic.mark(boundary_markers, id_subdomains_dic) ### Integration measures dx = dolfin.dx(domain=mesh) # for the whole domain ds = dolfin.ds(domain=mesh) # for the entire boundary ds_msr_T = dolfin.Measure('ds', mesh, subdomain_id=id_subdomain_msr, subdomain_data=boundary_markers) ds_msr_u = dolfin.Measure('ds', mesh, subdomain_id=id_subdomains_dic, subdomain_data=boundary_markers) ### Finite element function spaces V = dolfin.VectorFunctionSpace(mesh, 'CG', FINITE_ELEMENT_DEGREE)
dolfin.lt((x[0] - 0.5)**2, 0.35**2), 1.0, 0.0) bcs = [dolfin.DirichletBC(space, lower_boundary_value, lower_boundary)] if not no_side_bc: def _side_bc(subdomain): bcs.append(dolfin.DirichletBC(space, dolfin.Constant(0.0), subdomain)) if theta < np.pi / 2: _side_bc(left_boundary) else: _side_bc(right_boundary) # alpha = dolfin.Constant(1.0) alpha = dolfin.conditional( dolfin.lt((x[0] - 0.5)**2 + (x[1] - 0.5)**2, 0.2**2), 6.0, 1.0) # alpha = dolfin.conditional(dolfin.And(dolfin.gt(x[0], 0.5), dolfin.gt(x[1], 0.5)), 4.0, 1.0) alpha = dolfin.project(alpha, space) # needs to be continuous S = dolfin.Constant(0.0) * x[0] dsf, dxf = make_form(I=u, v=test_function, omega=omega, beta=alpha, S=S) form = dsf * dolfin.ds() + dxf * dolfin.dx() solver = NewtonSolver(form, u, bcs) solver.solve() # dolfin.plot(u) # dolfin.plot(alpha)
MPI.barrier(mpicomm) t0 = time() KV = assemble(weak_V) MPI.barrier(mpicomm) t1 = time() if mpirank == 0: print 'Time to assemble KV = {}'.format(t1-t0) elif myrun == 2: class LeftRight(SubDomain): def inside(self, x, on_boundary): return (x[0] < 1e-16 or x[0] > 1.0 - 1e-16) \ and on_boundary class_bc_abc = LeftRight() abc_boundaryparts = FacetFunction("size_t", mesh) class_bc_abc.mark(abc_boundaryparts, 1) ds = Measure("ds")[abc_boundaryparts] weak_1 = inner(sqrt(lam1*rho1)*nabla_grad(trial), nabla_grad(test))*ds(1) weak_2 = inner(sqrt(lam2*rho2)*nabla_grad(trial), nabla_grad(test))*ds(1) lam1.vector()[:] = 1.0 rho1.vector()[:] = 1.0 print 'Start assembling K2' t0 = time() K2 = assemble(weak_2) t1 = time() print 'Time to assemble K2 = {}'.format(t1-t0) lam2.vector()[:] = 1.0 rho2.vector()[:] = 1.0 print 'Start assembling K1' t0 = time() K1 = assemble(weak_1)
def nablaT_fun( V, v, hol_cyl, A, boundary_faces, mark_in, mark_ex, T_old_v, g_d, #S_in T_sol_d, T_ex, #S_ex unitNormal, k_mesh_old, cp_mesh_old, rho_mesh_old, dt, time_v, theta, itera, mesh_name, savings_do): ''' Direct problem. Solves A T = L. A = dt * theta * k_mesh * do.dot(do.grad(T), do.grad(v)) * do.dx(domain = hol_cyl) + \ rho_mesh * cp_mesh * T * v * do.dx(domain = hol_cyl) int_fluxT_ex = -k_mesh * do.dot(unitNormal, do.grad(T_sol)) * v * \ do.ds(mark_ex, domain = hol_cyl, subdomain_data = boundary_faces) no T_ex on outer boundary. ''' #solver parameters #linear solvers from #list_linear_solver_methods() #preconditioners from #do.list_krylov_solver_preconditioners() solver = do.KrylovSolver('gmres', 'ilu') do.info(solver.parameters, False) #prints default values solver.parameters['relative_tolerance'] = 1e-13 solver.parameters['maximum_iterations'] = 2000000 solver.parameters['monitor_convergence'] = True #on the screen #http://fenicsproject.org/qa/1124/ #is-there-a-way-to-set-the-inital-guess-in-the-krylov-solver solver.parameters['nonzero_initial_guess'] = True #solver.parameters['absolute_tolerance'] = 1e-15 #T_stept = do.TrialFunction(V) T_step1 = do.Function(V) T_old = do.Function(V) #T_old_v is a scalar T_step1.vector()[:] = T_old_v T_old.vector()[:] = T_old_v T_step1_d = {} print 'T: min(g_d[0]) = ', min(g_d[0].vector().array()) print 'T: max(g_d[0]) = ', max(g_d[0].vector().array()) theta = do.Constant(theta) dt = do.Constant(dt) T_step1_f = do.File(os.path.join(savings_do, str(itera), 'dir_IHCP.pvd')) #A = dt / 2. * k_mesh_old * do.dot(do.grad(T_stept), do.grad(v)) * do.dx(domain = hol_cyl) + \ # rho_mesh_old * cp_mesh_old * T_stept * v * do.dx(domain = hol_cyl) for count_t_i, t_i in enumerate(time_v[1:]): #storage T_step1_d[count_t_i] = do.Function(V) T_step1_d[count_t_i].vector()[:] = T_step1.vector().array() #g is a k * dot(grad(T), n) int_fluxT_in = g_d[count_t_i + 1] * v * do.ds( mark_in, domain=hol_cyl, subdomain_data=boundary_faces) int_fluxT_in_old = g_d[count_t_i] * v * do.ds( mark_in, domain=hol_cyl, subdomain_data=boundary_faces) int_fluxT_ex = + k_mesh_old * do.dot(unitNormal, do.grad(T_sol_d[count_t_i + 1])) * \ v * do.ds(mark_ex, domain = hol_cyl, subdomain_data = boundary_faces) int_fluxT_ex_old = + k_mesh_old * do.dot(unitNormal, do.grad(T_sol_d[count_t_i])) * \ v * do.ds(mark_ex, domain = hol_cyl, subdomain_data = boundary_faces) #print 'T: type(int_fluxT_in) = ', type(int_fluxT_in) #print 'T: type(int_fluxT_in_old) = ', type(int_fluxT_in_old) #print 'T: min(int_fluxT_in) = ', min(do.assemble(int_fluxT_in)) #L -= (int_fluxT_in + int_fluxT_ex) L_old = -dt * (1. - theta) * k_mesh_old * do.dot(do.grad(T_old), do.grad(v)) * \ do.dx(domain = hol_cyl) + \ rho_mesh_old * cp_mesh_old * T_old * v * do.dx(domain = hol_cyl) L = L_old + (dt * theta * int_fluxT_in + dt * (1. - theta) * int_fluxT_in_old + dt * theta * int_fluxT_ex + dt * (1. - theta) * int_fluxT_ex_old) do.solve(A == L, T_step1) #, bc_ex) print 'T: count_t = {}, avg(g) = {}'.format( count_t_i, np.mean(g_d[count_t_i + 1].vector().array())) print 'T: count_t = {}, min(L) = {}'.format( count_t_i, min(do.assemble(L).array())) print 'T: count_t = {}, max(L) = {}'.format( count_t_i, max(do.assemble(L).array())) print 'T: count_t = {}, min(T) = {}'.format( count_t_i, min(T_step1.vector().array())) print 'T: count_t = {}, max(T) = {}'.format( count_t_i, max(T_step1.vector().array())) print 'T: count_t = {}, min(T_DHCP) = {}'.format( count_t_i, min(T_sol_d[count_t_i].vector().array())) print 'T: count_t = {}, max(T_DHCP) = {}'.format( count_t_i, max(T_sol_d[count_t_i].vector().array())), '\n' T_old.assign(T_step1) #rename T_step1.rename('IHCP_T', 'temperature from IHCP') T_step1_f << (T_step1, t_i) count_t_i += 1 #storage T_step1_d[count_t_i] = do.Function(V) T_step1_d[count_t_i].vector()[:] = T_step1.vector().array() return T_step1_d
g_v = dolfin.Constant(-2.0) # In[164]: g_h = dolfin.Constant(1.0) # In[165]: L = f * v * dolfin.dx(domain=mesh, subdomain_data=boundary_parts) # In[166]: L += g_v * v * dolfin.ds(0, domain=mesh, subdomain_data=boundary_parts) # In[167]: L += g_h * v * dolfin.ds(1, domain=mesh, subdomain_data=boundary_parts) # In[168]: u_sol = dolfin.Function(V) # In[169]: dolfin.solve(a == L, u_sol, bc)
def nablap_fun( V, v, hol_cyl, A, boundary_faces, mark_ex, T_step_d, T_exp_d, #S_ex k_mesh_oldp, cp_mesh_oldp, rho_mesh_oldp, dt, time_v, theta, itera, mesh_name, savings_do): ''' Adjoint problem. Solves A p = L. A = dt * theta * k_mesh * do.dot(do.grad(p), do.grad(v)) * do.dx(domain = hol_cyl) + \ rho_mesh * cp_mesh * p * v * do.dx(domain = hol_cyl) T_stepp: from T_step flipped. T_exp : from T_ex flipped. ''' #solver parameters #linear solvers from #list_linear_solver_methods() #preconditioners from #do.list_krylov_solver_preconditioners() solver = do.KrylovSolver('gmres', 'ilu') do.info(solver.parameters, False) #prints default values solver.parameters['relative_tolerance'] = 1e-13 solver.parameters['maximum_iterations'] = 2000000 solver.parameters['monitor_convergence'] = True #on the screen #http://fenicsproject.org/qa/1124/ #is-there-a-way-to-set-the-inital-guess-in-the-krylov-solver '''solver.parameters['nonzero_initial_guess'] = True''' #solver.parameters['absolute_tolerance'] = 1e-15 #uses whatever in q_v as my initial condition #p_stept = do.TrialFunction(V) p_step2 = do.Function(V) #starts from 0 p_old = do.Function(V) p_step2_d = {} #e.g., e.g., count_t_i = 100 #storage p_step2_d[len(time_v) - 1] = do.Function(V) p_step2_d[len(time_v) - 1].vector()[:] = p_old.vector().array() theta = do.Constant(theta) dt = do.Constant(dt) p_step2_f = do.File(os.path.join(savings_do, str(itera), 'adj_IHCP.pvd')) #A = dt / 2. * k_mesh_oldp * do.dot(do.grad(p_stept), do.grad(v)) * do.dx(domain = hol_cyl) + \ # rho_mesh_oldp * cp_mesh_oldp * p_stept * v * do.dx(domain = hol_cyl) #runs backwards in time for count_t_i, t_i in reversed(list(enumerate(time_v[:-1]))): #int_fluxT_in = 0 #e.g., count_t_i = 99 int_fluxT_ex = (T_step_d[count_t_i] - T_exp_d[count_t_i]) * v * \ do.ds(mark_ex, domain = hol_cyl, subdomain_data = boundary_faces) #'old' = old tau = new time; e.g., count_t_i + 1 = 100 int_fluxT_ex_old = (T_step_d[count_t_i + 1] - T_exp_d[count_t_i + 1]) * v * \ do.ds(mark_ex, domain = hol_cyl, subdomain_data = boundary_faces) L_oldp = -dt * (1. - theta) * k_mesh_oldp * do.dot(do.grad(p_old), do.grad(v)) * \ do.dx(domain = hol_cyl) + \ rho_mesh_oldp * cp_mesh_oldp * p_old * v * do.dx(domain = hol_cyl) #before: #L = L_oldp - (dt * theta * int_fluxT_ex + dt * (1. - theta) * int_fluxT_ex_old) L = L_oldp + (dt * theta * int_fluxT_ex + dt * (1. - theta) * int_fluxT_ex_old) do.solve(A == L, p_step2) print 'p: count_t = {}, min(T_step_d) = {}'.format( count_t_i, min(T_step_d[count_t_i].vector().array())) print 'p: count_t = {}, max(T_step_d) = {}'.format( count_t_i, max(T_step_d[count_t_i].vector().array())) print 'p: count_t = {}, min(int_fluxT_ex) = {}'.format( count_t_i, min(do.assemble(int_fluxT_ex).array())) print 'p: count_t = {}, max(int_fluxT_ex) = {}'.format( count_t_i, max(do.assemble(int_fluxT_ex).array())) print 'p: count_t = {}, min(L) = {}'.format( count_t_i, min(do.assemble(L).array())) print 'p: count_t = {}, max(L) = {}'.format( count_t_i, max(do.assemble(L).array())) print 'p: count_t = {}, min(p) = {}'.format(count_t_i, min(p_step2.vector())) print 'p: count_t = {}, max(p) = {}'.format( count_t_i, max(p_step2.vector())), '\n' p_old.assign(p_step2) p_step2.rename('dual_T', 'dual temperature') #storage p_step2_d[count_t_i] = do.Function(V) p_step2_d[count_t_i].vector()[:] = p_step2.vector().array() p_step2_f << (p_step2, t_i) return p_step2_d
print 'err: len(keys in T_sol_d2) = ', len(T_sol_d2.keys()) print 'err: len(keys in T_step_d2) = ', len(T_step_d2.keys()) #update variables for count_t_i1, t_i1 in enumerate(time_v1): #heat flux g_d2[count_t_i1].vector()[:] = g_d2[count_t_i1].vector().array() + \ alpha_step2 * p_step_d2[count_t_i1].vector().array() #adjoint variable derJ_step_old_d2[count_t_i1].vector( )[:] = derJ_step_d2[count_t_i1].vector().array() #exit criterion exit_crit_v[count_t_i1] = do.assemble( pow(alpha_step2 * p_step_d2[count_t_i1], 2.) * do.ds( mark_in2, domain=hol_cyl2, subdomain_data=boundary_faces2)) #do.File(os.path.join(savings_dol1, #'{}__T_from_IHCP.pvd'.format(mesh_name1.split('.')[0]))) << T_step11 print 'err: count_t_i1 = ', count_t_i1 #T_sol_d3 instead of T_sol_d2 e11_v[count_t_i1], e21_v[count_t_i1] = err_est_fun( mesh_name2, hol_cyl2, T_sol_d3[count_t_i1], T_step_d2[count_t_i1], deg_choice1, hol_cyl2, count_t_i1) #functional J2 = .5 * obj_f1 + .5 * gamma_reg2 * obj_f2 #store the error err_d2.append( [gamma_reg2_old,
def eta_fun( v, hol_cyl, #k, #conductivity gamma, #regularization T_step_d, #from direct pbm p_step_d, #from adjoint pbm and gamma_CG1 u_step_d, #from sensitivity pbm boundary_faces, mark_in, mark_ex, g_d, dg_d, T_ex_d, unitNormal, time_v, cut_end, itera, path_to_do): ''' Returns the optimal step size. T_step from direct problem. p_step from adjoint problem. u_step from sensitivity problem. ''' num1_v = np.zeros((len(T_step_d), )) num2_v = np.zeros((len(T_step_d), )) den1_v = np.zeros((len(T_step_d), )) den2_v = np.zeros((len(T_step_d), )) for count_it in sorted(T_step_d): #scalar ''' num1_v[count_it] = do.assemble(dg_d[count_it] * p_step_d[count_it] * do.ds(mark_in, domain = hol_cyl, subdomain_data = boundary_faces)) ''' num1_v[count_it] = do.assemble( (T_step_d[count_it] - T_ex_d[count_it]) * u_step_d[count_it] * do.ds(mark_ex, domain=hol_cyl, subdomain_data=boundary_faces)) #scalar num2_v[count_it] = do.assemble( p_step_d[count_it] * g_d[count_it] * do.ds(mark_in, domain=hol_cyl, subdomain_data=boundary_faces)) #scalar den1_v[count_it] = do.assemble( pow(u_step_d[count_it], 2.) * do.ds(mark_ex, domain=hol_cyl, subdomain_data=boundary_faces)) #scalar den2_v[count_it] = do.assemble( pow(p_step_d[count_it], 2.) * do.ds(mark_in, domain=hol_cyl, subdomain_data=boundary_faces)) print 'eta: count_t = {}, num1 = {}'.format(count_it, num1_v[count_it]) print 'eta: count_t = {}, num2 = {}'.format(count_it, num2_v[count_it]) print 'eta: count_t = {}, den1 = {}'.format(count_it, den1_v[count_it]) print 'eta: count_t = {}, den2 = {}'.format(count_it, den2_v[count_it]), '\n' fig_inf = plt.figure(figsize=(20, 10)) for i_fig in xrange(12): vari = 1. * num1_v * (i_fig / 3 == 0) + \ 1. * num2_v * (i_fig / 3 == 1) + \ 1. * den1_v * (i_fig / 3 == 2) + \ 1. * den2_v * (i_fig / 3 == 3) ytag = 'num1' * (i_fig / 3 == 0) + \ 'num2' * (i_fig / 3 == 1) + \ 'den1' * (i_fig / 3 == 2) + \ 'den2' * (i_fig / 3 == 3) stai = 0 * (i_fig % 3 == 0) + \ 0 * (i_fig % 3 == 1) + \ -50 * (i_fig % 3 == 2) endi = len(vari) * (i_fig % 3 == 0) + \ 50 * (i_fig % 3 == 1) + \ len(vari) * (i_fig % 3 == 2) ax_inf = fig_inf.add_subplot(4, 3, i_fig + 1) ax_inf.plot(vari[stai:endi]) ax_inf.set_ylabel(ytag) ax_inf.grid() nam_inf = os.path.join(path_to_do, 'eta_{}.pdf'.format(itera)) fig_inf.savefig(nam_inf, dpi=150) num1_avg = np.trapz(num1_v[:cut_end], x=time_v[:cut_end]) num2_avg = np.trapz(num2_v[:cut_end], x=time_v[:cut_end]) den1_avg = np.trapz(den1_v[:cut_end], x=time_v[:cut_end]) den2_avg = np.trapz(den2_v[:cut_end], x=time_v[:cut_end]) return -(num1_avg + gamma * num2_avg) / (den1_avg + gamma * den2_avg)
import dolfin mesh = dolfin.UnitSquareMesh(50, 20) el = dolfin.FiniteElement("BDM", mesh.ufl_cell(), 1) x = dolfin.SpatialCoordinate(mesh) expr = dolfin.as_vector((dolfin.sin(1 / x[0] + x[1]), 2 * x[1])) W = dolfin.FunctionSpace(mesh, el) w = dolfin.project(expr, W) example_testfunc = dolfin.TestFunction(W) example_form = dolfin.dot(w, example_testfunc) * dolfin.dx() + w[0] * dolfin.ds()
def solve_tr_dir__const_rheo(mesh_name, hol_cyl, deg_choice, T_in_expr, T_inf_expr, HTC, T_old_v, k_mesh, cp_mesh, rho_mesh, k_mesh_old, cp_mesh_old, rho_mesh_old, dt, time_v, theta, bool_plot, bool_solv, savings_do, logger_f): ''' mesh_name: a proper XML file. bool_plot: plots if bool_plot = 1. Solves a direct, steady-state heat conduction problem, and returns A_np, b_np, D_np, T_np, bool_ex, bool_in. A_np: stiffness matrix, ordered by vertices. b_np: integrated volumetric heat sources and surface heat fluxes, ordered by vertices. The surface heat fluxes come from the solution to the direct problem; hence, these terms will not be there in a real IHCP. D_np: integrated Laplacian of T, ordered by vertices. Option 2. The Laplacian of q is properly assembled from D_np. If do.dx(domain = hol_cyl) -> do.Measure('ds')[boundary_faces] and do.Measure('ds')[boundary_faces] -> something representative of Gamma, I would get option 1. T_np: solution to the direct heat conduction problem, ordered by vertices. bool_ex: boolean array declaring which vertices lie on the outer boundary. bool_in: boolean array indicating which vertices lie on the inner boundary. T_sol: solution to the direct heat conduction problem. deg_choice: degree in FunctionSpace. hol_cyl: mesh. ''' #comm1 = MPI.COMM_WORLD #current proc #rank1 = comm1.Get_rank() V = do.FunctionSpace(hol_cyl, 'CG', deg_choice) if 'hollow' in mesh_name and 'cyl' in mesh_name: from hollow_cyl_inv_mesh import geo_fun as geo_fun_hollow_cyl geo_params_d = geo_fun_hollow_cyl()[1] #x_c is a scalar here #y_c is a scalar here elif 'four' in mesh_name and 'cyl' in mesh_name: from four_hole_cyl_inv_mesh import geo_fun as geo_fun_four_hole_cyl geo_params_d = geo_fun_four_hole_cyl()[1] #x_c is an array here #y_c is an array here x_c_l = [geo_params_d['x_0_{}'.format(itera)] for itera in xrange(4)] y_c_l = [geo_params_d['y_0_{}'.format(itera)] for itera in xrange(4)] elif 'one_hole_cir' in mesh_name: from one_hole_cir_adj_mesh import geo_fun as geo_fun_one_hole_cir geo_params_d = geo_fun_one_hole_cir()[1] #x_c is an array here #y_c is an array here x_c_l = [geo_params_d['x_0']] y_c_l = [geo_params_d['y_0']] elif 'reinh_cir' in mesh_name: from reinh_cir_adj_mesh import geo_fun as geo_fun_one_hole_cir geo_params_d = geo_fun_one_hole_cir()[1] #x_c is an array here #y_c is an array here x_c_l = [geo_params_d['x_0']] y_c_l = [geo_params_d['y_0']] elif 'small_circle' in mesh_name: from four_hole_small_cir_adj_mesh import geo_fun as geo_fun_four_hole_cir geo_params_d = geo_fun_four_hole_cir()[1] #x_c is an array here #y_c is an array here x_c_l = [geo_params_d['x_0_{}'.format(itera)] for itera in xrange(4)] y_c_l = [geo_params_d['y_0_{}'.format(itera)] for itera in xrange(4)] #center of the cylinder base x_c = geo_params_d['x_0'] y_c = geo_params_d['y_0'] R_in = geo_params_d['R_in'] R_ex = geo_params_d['R_ex'] #define variational problem T = do.TrialFunction(V) g = do.Function(V) v = do.TestFunction(V) T_old = do.Function(V) T_inf = do.Function(V) #scalar T_old.vector()[:] = T_old_v T_inf.vector()[:] = T_inf_expr #solution T_sol = do.Function(V) #scalar T_sol.vector()[:] = T_old_v # Create boundary markers mark_all = 3 mark_in = 4 mark_ex = 5 #x_c is an array here #y_c is an array here g_in = g_in_mesh(mesh_name, x_c_l, y_c_l, R_in) g_ex = g_ex_mesh(mesh_name, x_c, y_c, R_ex) in_boundary = do.AutoSubDomain(g_in) ex_boundary = do.AutoSubDomain(g_ex) #normal unitNormal = do.FacetNormal(hol_cyl) boundary_faces = do.MeshFunction('size_t', hol_cyl, hol_cyl.topology().dim() - 1) boundary_faces.set_all(mark_all) in_boundary.mark(boundary_faces, mark_in) ex_boundary.mark(boundary_faces, mark_ex) bc_in = do.DirichletBC(V, T_in_expr, boundary_faces, mark_in) #bc_ex = do.DirichletBC(V, T_ex_expr, boundary_faces, mark_ex) bcs = [bc_in] #k = do.Function(V) #W/m/K #k.vector()[:] = k_mesh #A0 = k * do.dot(do.grad(T), do.grad(v)) * do.dx(domain = hol_cyl) A = dt / 2. * k_mesh * do.dot(do.grad(T), do.grad(v)) * do.dx(domain = hol_cyl) + \ rho_mesh * cp_mesh * T * v * do.dx(domain = hol_cyl) A_full = A + dt / 2. * HTC * T * v * do.ds( mark_ex, domain=hol_cyl, subdomain_data=boundary_faces) L = -dt / 2. * k_mesh_old * do.dot(do.grad(T_old), do.grad(v)) * \ do.dx(domain = hol_cyl) + \ rho_mesh_old * cp_mesh_old * T_old * v * do.dx(domain = hol_cyl) - \ dt / 2. * HTC * (T_old) * v * do.ds(mark_ex, domain = hol_cyl, subdomain_data = boundary_faces) + \ dt * HTC * T_inf * v * do.ds(mark_ex, domain = hol_cyl, subdomain_data = boundary_faces) #numpy version of A, T, and (L + int_fluxT) #A_np__not_v2d = do.assemble(A).array() #before applying BCs - needs v2d #L_np__not_v2d = do.assemble(L).array() #before applying BCs - needs v2d #Laplacian of T, without any -1/k int_S q*n*v dS ''' Approximated integral of the Laplacian of T. Option 2. The Laplacian of q is properly assembled from D_np. If do.dx(domain = hol_cyl) -> do.Measure('ds')[boundary_faces] and do.Measure('ds')[boundary_faces] -> something representative of Gamma, I would get option 1. ''' #D_np__not_v2d = do.assemble(-do.dot(do.grad(T), do.grad(v)) * do.dx(domain = hol_cyl) + # do.dot(unitNormal, do.grad(T)) * v * # do.Measure('ds')[boundary_faces]).array() #print np.max(D_np__not_v2d)#, np.max(A_np__not_v2d) #logger_f.warning('shape of D_np = {}, {}'.format(D_np__not_v2d.shape[0], #D_np__not_v2d.shape[1])) #nonzero_entries = [] #for row in D_np__not_v2d: # nonzero_entries += [len(np.where(abs(row) > 1e-16)[0])] #logger_f.warning('max, min, and mean of nonzero_entries = {}, {}, {}'.format( # max(nonzero_entries), min(nonzero_entries), np.mean(nonzero_entries))) #solver parameters #linear solvers from #list_linear_solver_methods() #preconditioners from #do.list_krylov_solver_preconditioners() solver = do.KrylovSolver('gmres', 'ilu') do.info(solver.parameters, True) #prints default values solver.parameters['relative_tolerance'] = 1e-16 solver.parameters['maximum_iterations'] = 20000000 solver.parameters['monitor_convergence'] = True #on the screen #http://fenicsproject.org/qa/1124/is-there-a-way-to-set-the-inital-guess-in-the-krylov-solver '''solver.parameters['nonzero_initial_guess'] = True''' solver.parameters['absolute_tolerance'] = 1e-15 #uses whatever in q_v as my initial condition #the next lines are used for CHECK 3 only #A_sys, b_sys = do.assemble_system(A, L, bcs) do.File( os.path.join(savings_do, '{}__markers.pvd'.format( mesh_name.split('.')[0]))) << boundary_faces if bool_plot: do.plot(boundary_faces, '3D mesh', title='boundary markers') #storage T_sol_d = {} g_d = {} if bool_solv == 1: xdmf_DHCP_T = do.File(os.path.join(savings_do, 'DHCP', 'T.pvd')) xdmf_DHCP_q = do.File(os.path.join(savings_do, 'DHCP', 'q.pvd')) for count_t_i, t_i in enumerate(time_v[1:]): #T_in_expr.ts = t_i #T_ex_expr.ts = t_i #storage T_sol_d[count_t_i] = do.Function(V) T_sol_d[count_t_i].vector()[:] = T_sol.vector().array() do.solve(A_full == L, T_sol, bcs) ''' TO BE UPDATED: rheology is not updated ''' #updates L T_old.assign(T_sol) T_sol.rename('DHCP_T', 'temperature from DHCP') #write solution to file #paraview format xdmf_DHCP_T << (T_sol, t_i) #plot solution if bool_plot: do.plot(T_sol, title='T') #, interactive = True) logger_f.warning('len(T) = {}'.format(len(T_sol.vector().array()))) print 'T: count_t = {}, min(T_DHCP) = {}'.format( count_t_i, min(T_sol_d[count_t_i].vector().array())) print 'T: count_t = {}, max(T_DHCP) = {}'.format( count_t_i, max(T_sol_d[count_t_i].vector().array())), '\n' #save flux - required for solving IHCP #same result if do.ds(mark_ex, subdomain_data = boundary_faces) #instead of do.Measure('ds')[boundary_faces] #Langtangen, p. 37: #either do.dot(do.nabla_grad(T), unitNormal) #or do.dot(unitNormal, do.grad(T)) #int_fluxT = do.assemble(-k * do.dot(unitNormal, do.grad(T_sol)) * v * # do.Measure('ds')[boundary_faces]) fluxT = do.project( -k_mesh * do.grad(T_sol), do.VectorFunctionSpace(hol_cyl, 'CG', deg_choice, dim=2)) if bool_plot: do.plot(fluxT, title='flux at iteration = {}'.format(count_t_i)) fluxT.rename('DHCP_flux', 'flux from DHCP') xdmf_DHCP_q << (fluxT, t_i) print 'DHCP: iteration = {}'.format(count_t_i) #################################################### #full solution #T_sol_full = do.Vector() #T_sol.vector().gather(T_sol_full, np.array(range(V.dim()), 'intc')) #################################################### count_t_i += 1 #copy previous lines #storage T_sol_d[count_t_i] = do.Function(V) T_sol_d[count_t_i].vector()[:] = T_sol.vector().array() for count_t_i, t_i in enumerate(time_v): #storage g_d[count_t_i] = do.Function(V) g_d[count_t_i].vector()[:] = g.vector().array() gdim = hol_cyl.geometry().dim() dofmap = V.dofmap() dofs = dofmap.dofs() #Get coordinates as len(dofs) x gdim array dofs_x = V.tabulate_dof_coordinates().reshape((-1, gdim)) #booleans corresponding to the outer boundary -> ints since they are sent to root = 0 bool_ex = 1. * np.array([g_ex(dof_x) for dof_x in dofs_x]) #booleans corresponding to the inner boundary -> ints since they are sent to root = 0 bool_in = 1. * np.array([g_in(dof_x) for dof_x in dofs_x]) T_np_ex = [] T_np_in = [] for i_coor, coor in enumerate(dofs_x): if g_ex(coor): T_np_ex += [T_sol.vector().array()[i_coor]] if g_in(coor): T_np_in += [T_sol.vector().array()[i_coor]] print 'CHECK: mean(T) on the outer boundary = ', np.mean(np.array(T_np_ex)) print 'CHECK: mean(T) on the inner boundary = ', np.mean(np.array(T_np_in)) print 'CHECK: mean(HTC) = ', np.mean(do.project(HTC, V).vector().array()) #v2d = do.vertex_to_dof_map(V) #orders by hol_cyl.coordinates() if deg_choice == 1: print 'len(dof_to_vertex_map) = ', len(do.dof_to_vertex_map(V)) print 'min(dofs) = ', min(dofs), ', max(dofs) = ', max(dofs) print 'len(bool ex) = ', len(bool_ex) print 'len(bool in) = ', len(bool_in) print 'bool ex[:10] = ', repr(bool_ex[:10]) print 'type(T) = ', type(T_sol.vector().array()) #first global results, then local results return A, L, g_d, \ V, v, k_mesh, \ mark_in, mark_ex, \ boundary_faces, bool_ex, \ R_in, R_ex, T_sol_d, deg_choice, hol_cyl, \ unitNormal, dofs_x
def femsolve(): ''' Bilineaarinen muoto: a(u,v) = L(v) a(u,v) = (inner(grad(u), grad(v)) + u*v)*dx L(v) = f*v*dx - g*v*ds g(x) = -du/dx = -u1, x = x1 u(x0) = u0 Omega = {xeR|x0<=x<=x1} ''' from dolfin import UnitInterval, FunctionSpace, DirichletBC, TrialFunction from dolfin import TestFunction, grad, Constant, Function, solve, inner, dx, ds from dolfin import MeshFunction, assemble import dolfin # from dolfin import set_log_level, PROCESS # Create mesh and define function space mesh = UnitInterval(30) V = FunctionSpace(mesh, 'Lagrange', 2) boundaries = MeshFunction('uint', mesh, mesh.topology().dim()-1) boundaries.set_all(0) class Left(dolfin.SubDomain): def inside(self, x, on_boundary): tol = 1E-14 # tolerance for coordinate comparisons return on_boundary and abs(x[0]) < tol class Right(dolfin.SubDomain): def inside(self, x, on_boundary): return dolfin.near(x[0], 1.0) left = Left() right = Right() left.mark(boundaries, 1) right.mark(boundaries, 2) # def u0_boundary(x): # return abs(x[0]) < tol # # bc = DirichletBC(V, Constant(u0), lambda x: abs(x[0]) < tol) bcs = [DirichletBC(V, Constant(u0), boundaries, 1)] # Define variational problem u = TrialFunction(V) v = TestFunction(V) a = (inner(grad(u), grad(v)) + u*v)*dx g = Constant(-u1) L = Constant(f)*v*dx - g*v*ds(2) # set_log_level(PROCESS) # Compute solution A = assemble(a, exterior_facet_domains=boundaries) b = assemble(L, exterior_facet_domains=boundaries) for bc in bcs: bc.apply(A, b) u = Function(V) solve(A, u.vector(), b, 'lu') coor = mesh.coordinates() u_array = u.vector().array() a = [] b = [] for i in range(mesh.num_vertices()): a.append(coor[i]) b.append(u_array[i]) print('u(%3.2f) = %0.14E'%(coor[i],u_array[i])) import numpy as np np.savez('fem',a,b)