import dolfin as df mesh1 = df.UnitSquareMesh(2, 2) mesh2 = df.UnitSquareMesh(2, 2) V1 = df.FunctionSpace(mesh1, "CG", 1) V2 = df.FunctionSpace(mesh2, "CG", 1) u1 = df.Function(V1) v1 = df.TestFunction(V1) u2 = df.Function(V2) v2 = df.TestFunction(V2) u3 = df.Function(V2) u1.vector()[0] = 1 u3.vector()[:] = u1.vector()[:] u1.vector()[0] = 2 print(u1.vector()[0], u3.vector()[0]) df.assemble(-1.0 * df.inner(df.grad(u1), df.grad(v1)) * df.dx) df.assemble(-1.0 * df.inner(df.grad(u2), df.grad(v2)) * df.dx) df.assemble(-1.0 * df.inner(df.grad(u3), df.grad(v2)) * df.dx)
def dolfin_fiberrules( mesh, fiber_space=None, fiber_rotation_epi=50, # 50 fiber_rotation_endo=40, # 40 sheet_rotation_epi=65, # 65 sheet_rotation_endo=25, # 25 alpha_noise=0.0, beta_noise=0.0): """ Create fiber, cross fibers and sheet directions Arguments --------- mesh : dolfin.Mesh A dolfin mesh with marked boundaries: base = 10, rv = 20, lv = 30, epi = 40 The base is assumed placed at x=0 fiber_space : dolfin.FunctionSpace (optional) Determines for what space the fibers should be calculated for. fiber_rotation_epi : float (optional) Fiber rotation angle on the endocardial surfaces. fiber_rotation_endo : float (optional) Fiber rotation angle on the epicardial surfaces. sheet_rotation_epi : float (optional) Sheet rotation angle on the endocardial surfaces. sheet_rotation_endo : float (optional) Sheet rotation angle on the epicardial surfaces. """ #import cpp if not isinstance(mesh, d.Mesh): raise TypeError("Expected a dolfin.Mesh as the mesh argument.") # Default fiber space is P1 fiber_space = fiber_space or d.FunctionSpace(mesh, "P", 1) # Create scalar laplacian solutions d.info("Calculating scalar fields") scalar_solutions = scalar_laplacians(mesh) # Create gradients d.info("\nCalculating gradients") data = project_gradients(mesh, fiber_space, scalar_solutions) # Assign the fiber and sheet rotations data.fiber_rotation_epi = fiber_rotation_epi data.fiber_rotation_endo = fiber_rotation_endo data.sheet_rotation_epi = sheet_rotation_epi data.sheet_rotation_endo = sheet_rotation_endo #Gaussian field with correlation length l #p , l = np.inf, 2 #number of terms in expansion #k = 10 #kernel = Matern(p = p,l = l) #0,1Exponential covariance kernel #kle = KLE(mesh, kernel, verbose = True) #kle.compute_eigendecomposition(k = k)#20 by default #Generate realizations #noise = kle.realizations() #x = np.zeros(len(noise)) #noise = np.array(x) #noise[0:len(noise)/2] = 30 ##print y #print "noise array", noise #V = d.FunctionSpace(mesh, "CG", 1) #random_field =d.Function(V) #random_f = np.zeros((mesh.num_vertices()),dtype =float) #random_f = noise #random_field.vector()[:] = random_f[d.dof_to_vertex_map(V)] #d.plot(random_field, mesh, interactive =True) ##random_f = noise #x = np.zeros(len(noise)) #y = np.array(x) #y[0:len(noise)/2] = 30 ##print y #print "noise array", y # Check noise if np.isscalar(alpha_noise): alpha_noise = np.zeros(mesh.num_vertices(), dtype=float) if np.isscalar(beta_noise): beta_noise = np.zeros(mesh.num_vertices(), dtype=float) # Call the fiber sheet generation cpp.computeFiberSheetSystem(data, alpha_noise[d.dof_to_vertex_map(fiber_space)], beta_noise[d.dof_to_vertex_map(fiber_space)]) #cpp.computeFiberSheetSystem(data,noise) # Create output Functions Vv = d.VectorFunctionSpace(mesh, fiber_space.ufl_element().family(), \ fiber_space.ufl_element().degree()) V = fiber_space fiber_sheet_tensor = data.fiber_sheet_tensor fiber_components = [] scalar_size = fiber_sheet_tensor.size / 9 indices = np.zeros(scalar_size * 3, dtype="L") indices[0::3] = np.arange(scalar_size, dtype="L") * 9 # x indices[1::3] = np.arange(scalar_size, dtype="L") * 9 + 3 # y indices[2::3] = np.arange(scalar_size, dtype="L") * 9 + 6 # z for ind, name in enumerate(["f0", "n0", "s0"]): component = d.Function(Vv, name=name) # Sort the fibers and sheets in dolfin degrees of freedom (dofs) component.vector()[:] = fiber_sheet_tensor[indices] fiber_components.append(component) indices += 1 # Make sheet the last component fiber_components = [fiber_components[0]] + fiber_components[-1:0:-1] return fiber_components
def test1(): """ Test whether SingleRegularization returns same output as underlying regularization """ mesh = dl.UnitSquareMesh(40, 40) Vm = dl.FunctionSpace(mesh, 'CG', 1) VmVm = createMixedFS(Vm, Vm) ab = dl.Function(VmVm) xab = dl.Function(VmVm) x = dl.Function(Vm) regul = LaplacianPrior({'Vm': Vm, 'gamma': 1e-4, 'beta': 1e-4}) regula = LaplacianPrior({'Vm': Vm, 'gamma': 1e-4, 'beta': 1e-4}) jointregula = SingleRegularization(regula, 'a') regulb = LaplacianPrior({'Vm': Vm, 'gamma': 1e-4, 'beta': 1e-4}) jointregulb = SingleRegularization(regulb, 'b') for ii in range(4): #ab.vector()[:] = (ii+1.0)*np.random.randn(2*Vm.dim()) ab = dl.interpolate(dl.Expression(('sin(nn*pi*x[0])*sin(nn*pi*x[1])', 'sin(nn*pi*x[0])*sin(nn*pi*x[1])'),\ nn=ii+1, degree=10), VmVm) a, b = ab.split(deepcopy=True) print '\nTest a' costregul = regul.cost(a) costjoint = jointregula.costab(a, b) print 'cost={}, diff={}'.format(costregul, np.abs(costregul - costjoint)) gradregul = regul.grad(a) gradjoint = jointregula.gradab(a, b) xab.vector().zero() xab.vector().axpy(1.0, gradjoint) ga, gb = xab.split(deepcopy=True) gan = ga.vector().norm('l2') gbn = gb.vector().norm('l2') diffn = (gradregul - ga.vector()).norm('l2') print '|ga|={}, diff={}, |gb|={}'.format(gan, diffn, gbn) regul.assemble_hessian(a) jointregula.assemble_hessianab(a, b) Hvregul = regul.hessian(a.vector()) Hvjoint = jointregula.hessianab(a.vector(), b.vector()) xab.vector().zero() xab.vector().axpy(1.0, Hvjoint) Ha, Hb = xab.split(deepcopy=True) Han = Ha.vector().norm('l2') Hbn = Hb.vector().norm('l2') diffn = (Hvregul - Ha.vector()).norm('l2') print '|Ha|={}, diff={}, |Hb|={}'.format(Han, diffn, Hbn) solvera = regul.getprecond() solveraiter = solvera.solve(x.vector(), a.vector()) solverab = jointregula.getprecond() solverabiter = solverab.solve(xab.vector(), ab.vector()) xa, xb = xab.split(deepcopy=True) diffn = (x.vector() - xa.vector()).norm('l2') diffbn = (b.vector() - xb.vector()).norm('l2') xan = xa.vector().norm('l2') xbn = xb.vector().norm('l2') print '|xa|={}, diff={}'.format(xan, diffn) print '|xb|={}, diff={}'.format(xbn, diffbn) print 'iter={}, diff={}'.format(solveraiter, np.abs(solveraiter - solverabiter)) print 'Test b' costregul = regul.cost(b) costjoint = jointregulb.costab(a, b) print 'cost={}, diff={}'.format(costregul, np.abs(costregul - costjoint)) gradregul = regul.grad(b) gradjoint = jointregulb.gradab(a, b) xab.vector().zero() xab.vector().axpy(1.0, gradjoint) ga, gb = xab.split(deepcopy=True) gan = ga.vector().norm('l2') gbn = gb.vector().norm('l2') diffn = (gradregul - gb.vector()).norm('l2') print '|gb|={}, diff={}, |ga|={}'.format(gbn, diffn, gan) regul.assemble_hessian(b) jointregulb.assemble_hessianab(a, b) Hvregul = regul.hessian(b.vector()) Hvjoint = jointregulb.hessianab(a.vector(), b.vector()) xab.vector().zero() xab.vector().axpy(1.0, Hvjoint) Ha, Hb = xab.split(deepcopy=True) Han = Ha.vector().norm('l2') Hbn = Hb.vector().norm('l2') diffn = (Hvregul - Hb.vector()).norm('l2') print '|Hb|={}, diff={}, |Ha|={}'.format(Hbn, diffn, Han) solverb = regul.getprecond() solverbiter = solverb.solve(x.vector(), b.vector()) solverab = jointregulb.getprecond() solverabiter = solverab.solve(xab.vector(), ab.vector()) xa, xb = xab.split(deepcopy=True) diffn = (x.vector() - xb.vector()).norm('l2') diffan = (a.vector() - xa.vector()).norm('l2') xan = xa.vector().norm('l2') xbn = xb.vector().norm('l2') print '|xb|={}, diff={}'.format(xbn, diffn) print '|xa|={}, diff={}'.format(xan, diffan) print 'iter={}, diff={}'.format(solverbiter, np.abs(solverbiter - solverabiter))
try: f_read = pickle.load(f) except: f_read = pickle.load(f, encoding='bytes') gLIS_eigv, gLIS_eigf = f_read[-2:] f.close() found = True except: print('pickle file broken! global LIS not read!') if found: # read samples fnames = [f for f in os.listdir(folder) if f.endswith('.h5')] num_samp = 10000 prj_samp = np.zeros((num_samp, len(gLIS_eigv))) found = False samp_f = df.Function(elliptic.pde.V, name="parameter") bad_idx = [] prog = np.ceil(num_samp * (.1 + np.arange(0, 1, .1))) for f_i in fnames: if '_' + algs[i] + '_' in f_i: try: f = df.HDF5File(elliptic.pde.mpi_comm, os.path.join(folder, f_i), "r") for s in xrange(num_samp): try: f.read(samp_f, 'sample_{0}'.format(s)) except: bad_idx.append(s) prj_samp[s, ] = gLIS_eigf.T.dot(elliptic.prior.M * samp_f.vector()) if s + 1 in prog:
fid << vector2Function(post_pw_variance, Vh, name="Posterior") fid << vector2Function(pr_pw_variance, Vh, name="Prior") fid << vector2Function(corr_pw_variance, Vh, name="Correction") U.export(Vh, "hmisfit/evect.pvd", varname="gen_evect", normalize=True) if rank == 0: np.savetxt("hmisfit/eigevalues.dat", d) if rank == 0: print sep, "Generate samples from Prior and Posterior", sep fid_prior = dl.File("samples/sample_prior.pvd") fid_post = dl.File("samples/sample_post.pvd") nsamples = 50 noise = dl.Vector() posterior.init_vector(noise, "noise") s_prior = dl.Function(Vh, name="sample_prior") s_post = dl.Function(Vh, name="sample_post") for i in range(nsamples): parRandom.normal(1., noise) posterior.sample(noise, s_prior.vector(), s_post.vector()) fid_prior << s_prior fid_post << s_post if rank == 0: print sep, "Visualize results", sep plt.figure() plt.plot(range(0, k), d, 'b*', range(0, k), np.ones(k), '-r') plt.yscale('log') plt.show() if nproc == 1:
def set_D_with_protein(setup): meshp = setup.geo.mesh # mesh WITH protein x0 = np.array(setup.geop.x0) dim = setup.phys.dim x0 = x0 if dim == 3 else x0[::2] r0 = setup.geop.rMolecule rion = 0.11 # load diffusivity on mesh without protein functions, mesh = fields.get_functions(**setup.solverp.diffusivity_data) dist = functions["dist"] D0 = functions["D"] # evaluate dist, D on meshp nodes Vp = dolfin.FunctionSpace(meshp, "CG", 1) VVp = dolfin.VectorFunctionSpace(meshp, "CG", 1) distp_ = dolfin.interpolate(dist, Vp) D0p_ = dolfin.interpolate(D0, VVp) distp = distp_.vector()[dolfin.vertex_to_dof_map(Vp)] D0p = D0p_.vector()[dolfin.vertex_to_dof_map(VVp)] D0p = np.column_stack([D0p[i::dim] for i in range(dim)]) x = meshp.coordinates() # probes = Probes(x.flatten(), V) # probes(dist) # distp = probes.array(0) # # probes_ = Probes(x.flatten(), VV) # probes_(D0) # D0p = probes_.array(0) # first create (N,3,3) array from D0 (N,3) N = len(D0p) Da = np.zeros((N, dim, dim)) i3 = np.array(range(dim)) Da[:, i3, i3] = D0p # modify (N,3,3) array to include protein interaction R = x - x0 r = np.sqrt(np.sum(R**2, 1)) overlap = r < rion + r0 near = ~overlap & (r - r0 < distp) h = np.maximum(r[near] - r0, rion) eps = 1e-2 D00 = setup.phys.D Dt = np.zeros_like(r) Dn = np.zeros_like(r) Dt[overlap] = eps Dn[overlap] = eps Dt[near] = diff.Dt_plane(h, rion) Dn[near] = diff.Dn_plane(h, rion, N=20) # D(R) = Dn(h) RR^T + Dt(h) (I - RR^T) where R is normalized R0 = R / (r[:, None] + 1e-100) RR = (R0[:, :, None] * R0[:, None, :]) I = np.zeros((N, dim, dim)) I[:, i3, i3] = 1. Dpp = Dn[:, None, None] * RR + Dt[:, None, None] * (I - RR) Da[overlap | near] = D00 * Dpp[overlap | near] # assign final result to dolfin P1 TensorFunction VVV = dolfin.TensorFunctionSpace(meshp, "CG", 1, shape=(dim, dim)) D = dolfin.Function(VVV) v2d = dolfin.vertex_to_dof_map(VVV) Dv = D.vector() for k, (i, j) in enumerate(product(i3, i3)): Dv[np.ascontiguousarray(v2d[k::dim**2])] = np.ascontiguousarray(Da[:, i, j]) setup.phys.update(Dp=D, Dm=D) #embed() return D
def _load_function(FILE, mesh, rank): V = _space(mesh, rank) return dolfin.Function(V, str(os.path.join(DIR, FILE)))
def initiate_solution_diffusion(mod,rho_solute=const.rhom): """ Before the equations can be solved for the liquid solution: initial conditions and solution properties need to be setup update domain time array and ethanol source timing initial conditions variational problem solution properties boundary conditions To be run once after get_initial_conditions() and get_boundary_conditions() """ # --- Get new domain --- # mod.sol_mesh = dolfin.IntervalMesh(mod.n,mod.Rstar_center,mod.Rstar) mod.sol_V = dolfin.FunctionSpace(mod.sol_mesh,'CG',1) mod.sol_mesh.coordinates()[:] = np.log(mod.sol_mesh.coordinates()) mod.sol_coords = mod.sol_V.tabulate_dof_coordinates().copy() mod.sol_idx_wall = np.argmax(mod.sol_coords) # --- Time array --- # # Now that we have the melt-out time, we can define the time array mod.ts = np.arange(mod.t_init,mod.t_final+mod.dt,mod.dt)/mod.t0 mod.dt /= mod.t0 # Define the ethanol source mod.source_timing = mod.source_timing/mod.t0 mod.source_duration /= mod.t0 mod.source = mod.source_mass_final/(mod.source_duration*np.sqrt(np.pi))*np.exp(-((mod.ts-mod.source_timing)/mod.source_duration)**2.) # --- Set initial conditions --- # # solution temperature mod.u0_s = dolfin.Function(mod.sol_V) mod.u0_s.vector()[:] = mod.Tf_wall # solution concentration mod.u0_c = dolfin.project(dolfin.Constant(mod.C),mod.sol_V) # --- Set up the variational Problem --- # mod.u_s = dolfin.TrialFunction(mod.sol_V) mod.v_s = dolfin.TestFunction(mod.sol_V) mod.T_s = dolfin.Function(mod.sol_V) mod.C = dolfin.project(dolfin.Constant(mod.C),mod.sol_V) mod.Tf = Tf_depression(mod.C,linear=True)/abs(mod.T_inf) mod.Tf_wall = dolfin.project(mod.Tf,mod.sol_V).vector()[mod.sol_idx_wall] # --- Get the solution properties --- # mod.rhos = dolfin.project(dolfin.Expression('C + rhow*(1.-C/rho_solute)',degree=1,C=mod.C,rhow=const.rhow,rho_solute=rho_solute),mod.sol_V) mod.cs = dolfin.project(dolfin.Expression('ce*(C/rho_solute) + cw*(1.-C/rho_solute)',degree=1,C=mod.C,cw=const.cw,ce=const.ce,rho_solute=rho_solute),mod.sol_V) mod.ks = dolfin.project(dolfin.Expression('ke*(C/rho_solute) + kw*(1.-C/rho_solute)',degree=1,C=mod.C,kw=const.kw,ke=const.ke,rho_solute=rho_solute),mod.sol_V) mod.rhos_wall = mod.rhos.vector()[mod.sol_idx_wall] mod.cs_wall = mod.cs.vector()[mod.sol_idx_wall] mod.ks_wall = mod.ks.vector()[mod.sol_idx_wall] # --- Boundary Conditions --- # # Liquid boundary condition at hole wall (same temperature as ice) class sWall(dolfin.SubDomain): def inside(self, x, on_boundary): return on_boundary and x[0] > mod.sol_coords[mod.sol_idx_wall] - const.tol # center flux class center(dolfin.SubDomain): def inside(self, x, on_boundary): return on_boundary and x[0] < mod.w_center + const.tol # Initialize boundary classes mod.sWall = sWall() mod.center = center() # This will be used in the boundary condition for mass diffusion mod.boundaries = dolfin.MeshFunction("size_t", mod.sol_mesh, 0) # this index 0 is an alternative to the command boundaries.set_all(0) mod.sWall.mark(mod.boundaries, 1) mod.center.mark(mod.boundaries, 2) mod.sds = dolfin.Measure("ds")(subdomain_data=mod.boundaries)
def __init__(self, simulation, field_inp): """ A scalar field """ self.simulation = simulation self.read_input(field_inp) # Show the input data simulation.log.info('Creating a sharp field %r' % self.name) simulation.log.info(' Variable: %r' % self.var_name) simulation.log.info(' Local proj: %r' % self.local_projection) simulation.log.info(' Proj. degree: %r' % self.projection_degree) simulation.log.info(' Poly. degree: %r' % self.polynomial_degree) mesh = simulation.data['mesh'] self.V = dolfin.FunctionSpace(mesh, 'DG', self.polynomial_degree) self.func = dolfin.Function(self.V) if self.local_projection: # Represent the jump using a quadrature element quad_elem = dolfin.FiniteElement( 'Quadrature', mesh.ufl_cell(), self.projection_degree, quad_scheme="default", ) xpos, ypos, zpos = self.xpos, self.ypos, self.zpos if simulation.ndim == 2: cpp0 = 'x[0] < %r and x[1] < %r' % (xpos, ypos) else: cpp0 = 'x[0] < %r and x[1] < %r and x[2] < %r' % (xpos, ypos, zpos) cpp = '(%s) ? %r : %r' % (cpp0, self.val_below, self.val_above) e = dolfin.Expression(cpp, element=quad_elem) dx = dolfin.dx(metadata={'quadrature_degree': self.projection_degree}) # Perform the local projection u, v = dolfin.TrialFunction(self.V), dolfin.TestFunction(self.V) a = u * v * dolfin.dx L = e * v * dx ls = dolfin.LocalSolver(a, L) ls.solve_local_rhs(self.func) # Clip values to allowable bounds arr = self.func.vector().get_local() val_min = min(self.val_below, self.val_above) val_max = max(self.val_below, self.val_above) clipped_arr = numpy.clip(arr, val_min, val_max) self.func.vector().set_local(clipped_arr) self.func.vector().apply('insert') else: # Initialise the sharp static field dm = self.V.dofmap() arr = self.func.vector().get_local() above, below = self.val_above, self.val_below xpos, ypos, zpos = self.xpos, self.ypos, self.zpos for cell in dolfin.cells(simulation.data['mesh']): mp = cell.midpoint()[:] dof, = dm.cell_dofs(cell.index()) if ( mp[0] < xpos and mp[1] < ypos and (simulation.ndim == 2 or mp[2] < zpos) ): arr[dof] = below else: arr[dof] = above self.func.vector().set_local(arr) self.func.vector().apply('insert')
def generate_parameter(self): """ return a vector in the shape of the parameter """ return dl.Function(self.Vh[PARAMETER]).vector()
def QoI_FEM(lam1,lam2,pointa,pointb,gridx,gridy,p): aa = pointa[0] bb = pointb[0] cc = pointa[1] dd = pointb[1] 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:#pointing outward unit normal vector, pointing upaward (0,1) g1 = fn.Expression("-exp(lam2)*lam2*pi*sin(lam1*pi*x[0])*sin(lam2*pi*x[1])", lam1=lam1, lam2=lam2, degree=2+p) #g2:pointing downward (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) 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) psi = AvgCharFunc([aa, bb, cc, dd], degree=0) Q = fn.assemble(fn.project(psi * u, V) * fn.dx) return Q
def generate_state(self): """ return a vector in the shape of the state """ return dl.Function(self.Vh[STATE]).vector()
VV = createMixedFS(V, V) cg = normalizedcrossgradient(VV) print '\nsinusoidal cross-gradients' for ii in range(5): a = dl.interpolate(dl.Expression('1.0 + sin(n*pi*x[0])*sin(n*pi*x[1])',\ n=ii, degree=10), V) for jj in range(5): b = dl.interpolate(dl.Expression('1.0 + sin(n*pi*x[0])*sin(n*pi*x[1])',\ n=jj, degree=10), V) print cg.costab(a, b), print '' ############################################################# print '\ncheck gradient' ak, bk = dl.Function(V), dl.Function(V) directab = dl.Function(VV) H = [1e-6, 1e-7, 1e-5] for ii in range(5): print 'ii={}'.format(ii) a = dl.interpolate(dl.Expression('1.0 + sin(n*pi*x[0])*sin(n*pi*x[1])',\ n=ii, degree=10), V) b = dl.interpolate(dl.Expression('pow(x[0], n)*pow(x[1], n)',\ n=ii, degree=10), V) grad = cg.gradab(a, b) for jj in range(5): directa = dl.interpolate(dl.Expression('pow(x[0], n)*pow(x[1], n)',\ n=jj+1, degree=10), V) directb = dl.interpolate(dl.Expression('1.0 + sin(n*pi*x[0])*sin(n*pi*x[1])',\ n=jj+1, degree=10), V) dl.assign(directab.sub(0), directa)
def __init__(self, V, bcs=None, objects=None, circuit=None, remove_null_space=False, eps0=1, linalg_solver='gmres', linalg_precond='hypre_amg'): if bcs == None: bcs = [] if objects == None: objects = [] if not isinstance(bcs, list): bcs = [bcs] if not isinstance(objects, list): objects = [objects] self.V = V self.bcs = bcs self.objects = objects self.circuit = circuit self.remove_null_space = remove_null_space """ One could perhaps identify the cases in which different solvers and preconditioners should be used, and by default choose the best suited for the problem. """ self.solver = df.PETScKrylovSolver(linalg_solver, linalg_precond) self.solver.parameters['absolute_tolerance'] = 1e-14 self.solver.parameters['relative_tolerance'] = 1e-12 self.solver.parameters['maximum_iterations'] = 1000 self.solver.parameters['nonzero_initial_guess'] = True phi = df.TrialFunction(V) phi_ = df.TestFunction(V) self.a = df.Constant(eps0) * df.inner(df.grad(phi), df.grad(phi_)) * df.dx A = df.assemble(self.a) for bc in bcs: bc.apply(A) for o in objects: o.apply(A) if circuit != None: A, = circuit.apply(A) if remove_null_space: phi = df.Function(V) null_vec = df.Vector(phi.vector()) V.dofmap().set(null_vec, 1.0) null_vec *= 1.0 / null_vec.norm("l2") self.null_space = df.VectorSpaceBasis([null_vec]) df.as_backend_type(A).set_nullspace(self.null_space) self.A = A self.phi_ = phi_
def __init__(self, fileName, timeEnd, timeStep): self.times = [] self.BB = [] self.HH = [] self.TD = [] self.TB = [] self.TX = [] self.TY = [] self.TZ = [] self.us = [] self.ub = [] ########################################################## ################ MESH ################# ########################################################## # TODO: Probably do not have to save then open mesh self.mesh = df.Mesh() self.inFile = fc.HDF5File(self.mesh.mpi_comm(), fileName, "r") self.inFile.read(self.mesh, "/mesh", False) ######################################################### ################# FUNCTION SPACES ##################### ######################################################### self.E_Q = df.FiniteElement("CG", self.mesh.ufl_cell(), 1) self.Q = df.FunctionSpace(self.mesh, self.E_Q) self.E_V = df.MixedElement(self.E_Q, self.E_Q, self.E_Q) self.V = df.FunctionSpace(self.mesh, self.E_V) self.assigner_inv = fc.FunctionAssigner([self.Q, self.Q, self.Q], self.V) self.assigner = fc.FunctionAssigner(self.V, [self.Q, self.Q, self.Q]) self.U = df.Function(self.V) self.dU = df.TrialFunction(self.V) self.Phi = df.TestFunction(self.V) self.u, self.u2, self.H = df.split(self.U) self.phi, self.phi1, self.xsi = df.split(self.Phi) self.un = df.Function(self.Q) self.u2n = df.Function(self.Q) self.zero_sol = df.Function(self.Q) self.S0 = df.Function(self.Q) self.B = df.Function(self.Q) self.H0 = df.Function(self.Q) self.A = df.Function(self.Q) self.inFile.read(self.S0.vector(), "/surface", True) self.inFile.read(self.B.vector(), "/bed", True) self.inFile.read(self.A.vector(), "/smb", True) self.H0.assign(self.S0 - self.B) self.Hmid = theta * self.H + (1 - theta) * self.H0 self.S = self.B + self.Hmid self.width = df.interpolate(Width(degree=2), self.Q) self.strs = Stresses(self.U, self.Hmid, self.H0, self.H, self.width, self.B, self.S, self.Phi) self.R = -(self.strs.tau_xx + self.strs.tau_xz + self.strs.tau_b + self.strs.tau_d + self.strs.tau_xy) * df.dx ############################################################################# ######################## MASS CONSERVATION ################################ ############################################################################# self.h = df.CellSize(self.mesh) self.D = self.h * abs(self.U[0]) / 2. self.area = self.Hmid * self.width self.mesh_min = self.mesh.coordinates().min() self.mesh_max = self.mesh.coordinates().max() # Define boundaries self.ocean = df.FacetFunctionSizet(self.mesh, 0) self.ds = fc.ds(subdomain_data=self.ocean ) # THIS DS IS FROM FENICS! border integral for f in df.facets(self.mesh): if df.near(f.midpoint().x(), self.mesh_max): self.ocean[f] = 1 if df.near(f.midpoint().x(), self.mesh_min): self.ocean[f] = 2 self.R += ((self.H - self.H0) / dt * self.xsi - self.xsi.dx(0) * self.U[0] * self.Hmid + self.D * self.xsi.dx(0) * self.Hmid.dx(0) - (self.A - self.U[0] * self.H / self.width * self.width.dx(0)) * self.xsi) * df.dx + self.U[0] * self.area * self.xsi * self.ds(1) \ - self.U[0] * self.area * self.xsi * self.ds(0) ##################################################################### ######################### SOLVER SETUP ########################### ##################################################################### # Bounds self.l_thick_bound = df.project(Constant(thklim), self.Q) self.u_thick_bound = df.project(Constant(1e4), self.Q) self.l_v_bound = df.project(-10000.0, self.Q) self.u_v_bound = df.project(10000.0, self.Q) self.l_bound = df.Function(self.V) self.u_bound = df.Function(self.V) self.assigner.assign(self.l_bound, [self.l_v_bound] * 2 + [self.l_thick_bound]) self.assigner.assign(self.u_bound, [self.u_v_bound] * 2 + [self.u_thick_bound]) # This should set the velocity at the divide (left) to zero self.dbc0 = df.DirichletBC( self.V.sub(0), 0, lambda x, o: df.near(x[0], self.mesh_min) and o) # Set the velocity on the right terminus to zero self.dbc1 = df.DirichletBC( self.V.sub(0), 0, lambda x, o: df.near(x[0], self.mesh_max) and o) # overkill? self.dbc2 = df.DirichletBC( self.V.sub(1), 0, lambda x, o: df.near(x[0], self.mesh_max) and o) # set the thickness on the right edge to thklim self.dbc3 = df.DirichletBC( self.V.sub(2), thklim, lambda x, o: df.near(x[0], self.mesh_max) and o) # Define variational solver for the mass-momentum coupled problem self.J = df.derivative(self.R, self.U, self.dU) self.coupled_problem = df.NonlinearVariationalProblem(self.R, self.U, bcs=[self.dbc0, self.dbc1, self.dbc3], \ J=self.J) self.coupled_problem.set_bounds(self.l_bound, self.u_bound) self.coupled_solver = df.NonlinearVariationalSolver( self.coupled_problem) # Acquire the optimizations in fenics optimizations set_solver_options(self.coupled_solver) self.t = 0 self.timeEnd = float(timeEnd) self.dtFloat = float(timeStep) self.inFile.close()
def general_solver(parameters, advanced_parameters): print 'TESTING THREAD1' setup_general_parameters() patient = parameters['patient'] mesh = patient.mesh mesh_name = parameters['mesh_name'] marked_mesh = patient.ffun N = df.FacetNormal(mesh) fibers = patient.fiber # Getting BC BC_type = parameters['BC_type'] def make_dirichlet_bcs(W): V = W if W.sub(0).num_sub_spaces() == 0 else W.sub(0) if BC_type == 'fix_x': no_base_x_tran_bc = df.DirichletBC(V.sub(0), df.Constant(0.0), marked_mesh, patient.markers["BASE"][0]) elif BC_type == 'fixed': no_base_x_tran_bc = df.DirichletBC(V, df.Constant( (0.0, 0.0, 0.0)), marked_mesh, patient.markers["BASE"][0]) return no_base_x_tran_bc # Contraction parameter # gamma = Constant(0.0) #gamma = df.Function(df.FunctionSpace(mesh, "R", 0)) gamma = RegionalParameter(patient.sfun) gamma_values = parameters['gamma'] gamma_base = gamma_values['gamma_base'] gamma_mid = gamma_values['gamma_mid'] gamma_apical = gamma_values['gamma_apical'] gamma_apex = gamma_values['gamma_apex'] gamma_arr = np.array(gamma_base + gamma_mid + gamma_apical + gamma_apex) G = RegionalParameter(patient.sfun) G.vector()[:] = gamma_arr G_ = df.project(G.get_function(), G.get_ind_space()) f_gamma = df.XDMFFile(df.mpi_comm_world(), "activation.xdmf") f_gamma.write(G_) # Pressure pressure = df.Constant(0.0) lv_pressure = df.Constant(0.0) rv_pressure = df.Constant(0.0) #lv_pressure = df.Constant(0.0) #rv_pressure = df.Constant(0.0) # Spring spring_constant = advanced_parameters['spring_constant'] spring = df.Constant(spring_constant) spring_area = advanced_parameters['spring_area'] # Set up material model material_model = advanced_parameters['material_model'] active_model = advanced_parameters['active_model'] T_ref = advanced_parameters['T_ref'] matparams = advanced_parameters['mat_params'] #matparams=setup_material_parameters(material_model) if material_model == 'guccione': try: args = (fibers, gamma, matparams, active_model, patient.sheet, patient.sheet_normal, T_ref) except AttributeError: print 'Mesh does not have "sheet" attribute, choose another material model.' return else: args = ( fibers, gamma, matparams, active_model, #patient.sheet, #patient.sheet_normal, T_ref) if material_model == 'holzapfel_ogden': material = mat.HolzapfelOgden(*args) elif material_model == 'guccione': material = mat.Guccione(*args) elif material_model == 'neo_hookean': material = mat.NeoHookean(*args) # Create parameters for the solver if mesh_name == 'biv_ellipsoid.h5': params = { "mesh": mesh, "facet_function": marked_mesh, "facet_normal": N, "state_space": "P_2:P_1", "compressibility": { "type": "incompressible", "lambda": 0.0 }, "material": material, "bc": { "dirichlet": make_dirichlet_bcs, "neumann": [[lv_pressure, patient.markers["ENDO_LV"][0]], [rv_pressure, patient.markers["ENDO_RV"][0]]], "robin": [[spring, patient.markers[spring_area][0]]] } } else: params = { "mesh": mesh, "facet_function": marked_mesh, "facet_normal": N, "state_space": "P_2:P_1", "compressibility": { "type": "incompressible", "lambda": 0.0 }, "material": material, "bc": { "dirichlet": make_dirichlet_bcs, "neumann": [[pressure, patient.markers["ENDO"][0]]], "robin": [[spring, patient.markers[spring_area][0]]] } } df.parameters["adjoint"]["stop_annotating"] = True # Initialize solver solver = LVSolver(params) print 'TESTING THREAD2' # Solve for the initial state folder_path = parameters['folder_path'] u, p = solver.get_state().split(deepcopy=True) U = df.Function(u.function_space(), name="displacement") f = df.XDMFFile(df.mpi_comm_world(), folder_path + "/displacement.xdmf") sigma_f = solver.postprocess().cauchy_stress_component(fibers) V = df.FunctionSpace(mesh, 'DG', 1) sf = df.project(sigma_f, V) SF = df.Function(sf.function_space(), name='stress') g = df.XDMFFile(df.mpi_comm_world(), folder_path + "/stress.xdmf") solver.solve() u1, p1 = solver.get_state().split(deepcopy=True) U.assign(u1) f.write(U) sigma_f1 = solver.postprocess().cauchy_stress_component(fibers) sf1 = df.project(sigma_f1, V) SF.assign(sf1) g.write(SF) # Put on some pressure and solve plv = parameters['lv_pressure'] prv = parameters['rv_pressure'] if mesh_name == 'biv_ellipsoid.h5': iterate("pressure", solver, (plv, prv), { "p_lv": lv_pressure, "p_rv": rv_pressure }) else: iterate("pressure", solver, plv, {"p_lv": pressure}) u2, p2 = solver.get_state().split(deepcopy=True) U.assign(u2) f.write(U) sigma_f2 = solver.postprocess().cauchy_stress_component(fibers) sf2 = df.project(sigma_f2, V) SF.assign(sf2) g.write(SF) # Put on some active contraction and solve cont_mult = parameters['contraction_multiplier'] g_ = cont_mult * gamma_arr iterate("gamma", solver, g_, gamma, max_nr_crash=100, max_iters=100) u3, p3 = solver.get_state().split(deepcopy=True) U.assign(u3) f.write(U) sigma_f3 = solver.postprocess().cauchy_stress_component(fibers) sf3 = df.project(sigma_f3, V) SF.assign(sf3) g.write(SF) fname_u = "output_u.h5" if os.path.isfile(fname_u): os.remove(fname_u) u1.rename("u1", "displacement") u2.rename("u2", "displacement") u3.rename("u3", "displacement") fname_sf = "output_sf.h5" if os.path.isfile(fname_sf): os.remove(fname_sf) sf1.rename("sf1", "stress") sf2.rename("sf2", "stress") sf3.rename("sf3", "stress") save_to_h5(fname_u, mesh, u1, u2, u3) save_to_h5(fname_sf, mesh, sf1, sf2, sf3) return u1, u2, u3, sf1, sf2, sf3
return sum(wq * f(*xq) for xq, wq in zip(pts, weights)) / l # Get the MEAN mesh = df.BoxMesh(df.Point(-1, -1, -1), df.Point(1, 1, 1), 16, 16, 16) # Make 1d f = df.MeshFunction('size_t', mesh, 1, 0) # df.CompiledSubDomain('near(x[0], x[1]) && near(x[1], x[2])').mark(f, 1) df.CompiledSubDomain('near(x[0], 0.) && near(x[1], 0.)').mark(f, 1) line_mesh = EmbeddedMesh(f, 1) # Circle --------------------------------------------------------- size = 0.125 ci = Circle(radius=lambda x0: size, degree=12) u = df.Function(df.FunctionSpace(mesh, 'CG', 1)) op = Average(u, line_mesh, ci) surface = render_avg_surface(op) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') x0 = np.array([0, 0, 0.5]) n = np.array([0, 0, 1]) ci_integrate = lambda f, shape=ci, n=n, x0=x0: shape_integrate( f, shape, x0, n) # Sanity f = lambda x, y, z: 1 value = ci_integrate(f)
def main(): parser = argparse.ArgumentParser(description="Average various files") parser.add_argument("-l", "--list", nargs="+", help="List of folders", required=True) parser.add_argument("-f", "--fields", nargs="+", default=None, help="Sought fields") parser.add_argument("-t", "--time", type=float, default=0, help="Time") parser.add_argument("--show", action="store_true", help="Show") parser.add_argument("-R", "--radius", type=float, default=None, help="Radial distance") args = parser.parse_args() tss = [] for folder in args.list: ts = InterpolatedTimeSeries(folder, sought_fields=args.fields) tss.append(ts) Ntss = len(tss) all_fields_ = [] for ts in tss: all_fields_.append(set(ts.fields)) all_fields = list(set.intersection(*all_fields_)) if args.fields is None: fields = all_fields else: fields = list(set.intersection(set(args.fields), set(all_fields))) f_in = [] for ts in tss: f_in.append(ts.functions()) # Using the first timeseries to define the spaces # Could be redone to e.g. a finer, structured mesh. # ref_mesh = tss[0].mesh ref_spaces = dict([(field, f.function_space()) for field, f in f_in[0].items()]) if "psi" not in fields: exit("No psi") var_names = ["t", "s"] index_names = ["tt", "st", "ss"] index_numbers = [0, 1, 4] dim_names = ["x", "y", "z"] # Loading geometry rad_t = [] rad_s = [] g_ab = [] gab = [] for ts in tss: # Should compute these from the curvature tensor rad_t.append( df.interpolate(df.Expression("x[0]", degree=2), ts.function_space)) rad_s.append( df.interpolate(df.Expression("x[1]", degree=2), ts.function_space)) # g_loc = [ts.function(name) for name in ["gtt", "gst", "gss"]] # g_inv_loc = [ts.function(name) for name in ["g_tt", "g_st", "g_ss"]] gab_loc = dict([(idx, ts.function("g{}".format(idx))) for idx in index_names]) g_ab_loc = dict([(idx, ts.function("g_{}".format(idx))) for idx in index_names]) for idx, ij in zip(index_names, index_numbers): # for ij in range(3): # ts.set_val(g_loc[ij], ts.g[:, ij]) # ts.set_val(g_inv_loc[ij], ts.g_inv[:, ij]) ts.set_val(g_ab_loc[idx], ts.g_ab[:, ij]) # Could compute the gab locally instead of loading ts.set_val(gab_loc[idx], ts.gab[:, ij]) g_ab_loc["ts"] = g_ab_loc["st"] gab_loc["ts"] = gab_loc["st"] g_ab.append(g_ab_loc) gab.append(gab_loc) costheta = df.Function(ref_spaces["psi"], name="costheta") for its, (ts, g_ab_loc, gab_loc) in enumerate(zip(tss, g_ab, gab)): if args.time is not None: step, time = get_step_and_info(ts, args.time) g_ab_ = to_vector(g_ab_loc) gab_ = to_vector(gab_loc) ts.update(f_in[its]["psi"], "psi", step) psi = f_in[its]["psi"] psi_t = df.project(psi.dx(0), ts.function_space) psi_s = df.project(psi.dx(1), ts.function_space) gp_t = psi_t.vector().get_local() gp_s = psi_s.vector().get_local() # gtt, gst, gss = [g_ij.vector().get_local() for g_ij in g[its]] # g_tt, g_st, g_ss = [g_ij.vector().get_local() for g_ij in g_inv[its]] gtt = gab_["tt"] gst = gab_["ts"] gss = gab_["ss"] g_tt = g_ab_["tt"] g_st = g_ab_["ts"] g_ss = g_ab_["ss"] rht = rad_t[its].vector().get_local() rhs = rad_s[its].vector().get_local() rh_norm = np.sqrt(g_tt * rht**2 + g_ss * rhs**2 + 2 * g_st * rht * rhs) gp_norm = np.sqrt(gtt * gp_t**2 + gss * gp_s**2 + 2 * gst * gp_t * gp_s) costheta_loc = ts.function("costheta") # abs(cos(theta)): costheta_loc.vector()[:] = abs( (rht * gp_t + rhs * gp_s) / (rh_norm * gp_norm + 1e-8)) # cos(theta)**2: #costheta_loc.vector()[:] = ((rht*gp_t + rhs*gp_s)/(rh_norm*gp_norm+1e-8))**2 # sin(theta): #costheta_loc.vector()[:] = np.sin(np.arccos((rht*gp_t + rhs*gp_s)/(rh_norm*gp_norm+1e-8))) # sin(theta)**2: # costheta_loc.vector()[:] = np.sin(np.arccos((rht*gp_t + rhs*gp_s)/(rh_norm*gp_norm+1e-8)))**2 # abs(theta): #costheta_loc.vector()[:] = abs(np.arccos((rht*gp_t + rhs*gp_s)/(rh_norm*gp_norm+1e-8))) costheta_intp = interpolate_nonmatching_mesh(costheta_loc, ref_spaces["psi"]) costheta.vector()[:] += costheta_intp.vector().get_local() / Ntss dump_xdmf(costheta) if args.show: JET = plt.get_cmap('jet') RYB = plt.get_cmap('RdYlBu') RYB_r = plt.get_cmap('RdYlBu_r') mgm = plt.get_cmap('magma') fig, ax = plt.subplots() fig.set_size_inches(4.7, 4.7) rc('text', usetex=True) rc('font', **{'family': 'serif', 'serif': ['Palatino']}) # First, dump a hires PNG version of the data: plot = df.plot(costheta, cmap=mgm) plt.axis('off') plt.savefig('anglogram_hires.png', format="png", bbox_inches='tight', pad_inches=0, dpi=500) mainfs = 10 # Fontsize titlefs = 12 # Fontsize #plt.set_cmap('jet') #cbar = fig.colorbar(plot, ticks=[0, 0.5, 1], orientation='vertical') #cbar.ax.set_yticklabels(['Radial', 'Intermediate', 'Azimuthal']) #cbar = fig.colorbar(plot, ticks=[0, 0.5, 0.95], orientation='horizontal', fraction=0.046, pad=0.04) #cbar = fig.colorbar(plot, ticks=[0, 0.5, 0.995], orientation='horizontal', fraction=0.046, pad=0.04) cbar = fig.colorbar(plot, ticks=[0, 0.5, 0.9995], orientation='horizontal', fraction=0.046, pad=0.04) cbar.ax.set_xticklabels(['Radial', 'Intermediate', 'Azimuthal']) #ax.set_title('Stripe orientation -- $\\cos^2(\\theta)$', fontsize=mainfs) #ax.set_title(r'Stripe orientation -- $\cos^2(\theta)$') plt.text(0.5, 1.05, r'Stripe orientation -- $\left\vert\cos(\theta)\right\vert$', fontsize=titlefs, horizontalalignment='center', transform=ax.transAxes) #ax.set_title('Stripe orientation', fontsize=mainfs) #plt.text(0.2, 0.2, '$\\textcolor{red}{\\mathbf{p}(u,w,\\xi)}=\\textcolor{blue}{\\tilde{\\mathbf{p}}(u,w)} + \\xi \\tilde{\\mathbf{n}}(u,w)$', fontsize=mainfs) ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) #plt.show() plt.savefig('anglogram.pdf', format="pdf", bbox_inches='tight', pad_inches=0) #plt.axis('on') #ax.get_xaxis().set_visible(True) #ax.get_yaxis().set_visible(True) #plt.colorbar(plot) #plt.show() if args.radius is not None and args.radius > 0: Nr, Nphi = 256, 256 r_lin = np.linspace(0., args.radius, Nr) phi_lin = np.linspace(0, 2 * np.pi, Nphi, endpoint=False) R, Phi = np.meshgrid(r_lin, phi_lin) r = R.reshape((Nr * Nphi, 1)) phi = Phi.reshape((Nr * Nphi, 1)) xy = np.hstack((r * np.cos(phi), r * np.sin(phi))) pts = xy.flatten() probes = Probes(pts, ref_spaces["psi"]) probes(costheta) ct = probes.array() CT = ct.reshape(R.shape) g_r = CT.mean(axis=0) g_phi = CT.mean(axis=1) plt.figure() plt.plot(r_lin, g_r) plt.ylabel("g(r)") plt.xlabel("r") plt.figure() plt.plot(phi_lin, g_phi) plt.xlabel("phi") plt.ylabel("g(phi)") plt.show()
def _setup_problem(self): """ Method setting up solver objects of the stationary problem. """ assert hasattr(self, "_mesh") assert hasattr(self, "_boundary_markers") self._setup_function_spaces() self._setup_boundary_conditions() # creating test function self._v = dlfn.TestFunction(self._Vh) self._u = dlfn.TrialFunction(self._Vh) # solution self._solution = dlfn.Function(self._Vh) # volume element self._dV = dlfn.Measure("dx", domain=self._mesh) self._dA = dlfn.Measure("ds", domain=self._mesh, subdomain_data=self._boundary_markers) # setup the parameters for the elastic law self._elastic_law.set_parameters(self._mesh, self._C) # virtual work if self._elastic_law.linearity_type == "Linear": self._dw_int = self._elastic_law.dw_int(self._u, self._v) * self._dV elif self._elastic_law.linearity_type == "Nonlinear": self._dw_int = self._elastic_law.dw_int(self._solution, self._v) * self._dV # virtual work of external forces self._dw_ext = dlfn.dot(self._null_vector, self._v) * self._dV # add body force term if hasattr(self, "_body_force"): assert hasattr(self, "_D"), "Dimensionless parameter related to" + \ "the body forces is not specified." self._dw_ext += self._D * dot(self._body_force, self._v) * self._dV # add boundary tractions if hasattr(self, "_traction_bcs"): for bc in self._traction_bcs: # unpack values if len(bc) == 3: bc_type, bndry_id, traction = bc elif len(bc) == 4: bc_type, bndry_id, component_index, traction = bc if bc_type is TractionBCType.constant: assert isinstance(traction, (tuple, list)) const_function = dlfn.Constant(traction) self._dw_ext += dot(const_function, self._v) * self._dA(bndry_id) elif bc_type is TractionBCType.constant_component: assert isinstance(traction, float) const_function = dlfn.Constant(traction) self._dw_ext += const_function * self._v[ component_index] * self._dA(bndry_id) elif bc_type is TractionBCType.function: assert isinstance(traction, dlfn.Expression) self._dw_ext += dot(traction, self._v) * self._dA(bndry_id) elif bc_type is TractionBCType.function_component: assert isinstance(traction, dlfn.Expression) self._dw_ext += traction * self._v[ component_index] * self._dA(bndry_id) if self._elastic_law.linearity_type == "Linear": # linear variational problem self._problem = dlfn.LinearVariationalProblem( self._dw_int, self._dw_ext, self._solution, self._dirichlet_bcs) # setup linear variational solver self._solver = dlfn.LinearVariationalSolver(self._problem) elif self._elastic_law.linearity_type == "Nonlinear": self._Form = self._dw_int - self._dw_ext self._J_newton = dlfn.derivative(self._Form, self._solution) self._problem = dlfn.NonlinearVariationalProblem( self._Form, self._solution, self._dirichlet_bcs, J=self._J_newton) # setup linear variational solver self._solver = dlfn.NonlinearVariationalSolver(self._problem)
def solver(interval, dt=0.1, theta=1): t0, t1 = interval mesh = get_mesh(10) cell_function = get_cell_function(mesh) model = get_models(cell_function) num_global_states = model.num_states() # Create time keepers and time step const_dt = df.Constant(dt) current_time = df.Constant(0) t = t0 + theta*(t1 - t0) current_time.assign(t) # Create stimulus stimulus = df.Constant(0) # Make shared function pace mixed_vector_function_space = df.VectorFunctionSpace( mesh, "DG", 0, dim=num_global_states + 1 ) # Create previous solution and assign initial conditions previous_solution = df.Function(mixed_vector_function_space) # _model = xb.cellmodels.Cressman() # previous_solution.assign(_model.initial_conditions()) # Initial condition previous_solution.assign(model.initial_conditions()) # Initial condition v_previous, s_previous = splat(previous_solution, num_global_states + 1) # Create current solution current_solution = df.Function(mixed_vector_function_space) v_current, s_current = splat(current_solution, num_global_states + 1) # Create test functions test_functions = df.TestFunction(mixed_vector_function_space) test_v, test_s = splat(test_functions, num_global_states + 1) # Crate time derivatives Dt_v = (v_current - v_previous)/const_dt Dt_s = (s_current - s_previous)/const_dt # Create midpoint evaluations following theta rule v_mid = theta*v_current + (1.0 - theta)*v_previous s_mid = theta*s_current + (1.0 - theta)*s_previous if isinstance(model, xb.MultiCellModel): # model = xb.cellmodels.Cressman() # dy = df.Measure("dx", domain=mesh) # F_theta = model.F(v_mid, s_mid, time=current_time) # I_theta = -model.I(v_mid, s_mid, time=current_time) # lhs = (Dt_v - I_theta)*test_v # lhs += df.inner(Dt_s - F_theta, test_s) # lhs *= dy() dy = df.Measure("dx", domain=mesh, subdomain_data=model.markers()) domain_indices = model.keys() lhs_list = list() for k, model_k in enumerate(model.models()): domain_index_k = domain_indices[k] F_theta = model.F(v_mid, s_mid, time=current_time, index=domain_index_k) I_theta = -model.I(v_mid, s_mid, time=current_time, index=domain_index_k) a = (Dt_v - I_theta)*test_v a += df.inner(Dt_s - F_theta, test_s) a *= dy(domain_index_k) lhs_list.append(a) # Sum the form lhs = sum(lhs_list) else: # Evaluate currents at averaged v and s. Note sign for I_theta model = xb.cellmodels.Cressman() dy = df.Measure("dx", domain=mesh) F_theta = model.F(v_mid, s_mid, time=current_time) I_theta = -model.I(v_mid, s_mid, time=current_time) lhs = (Dt_v - I_theta)*test_v lhs += df.inner(Dt_s - F_theta, test_s) lhs *= dy() rhs = stimulus*test_v*dy() G = lhs - rhs # Solve system current_solution.assign(previous_solution) pde = df.NonlinearVariationalProblem( G, current_solution, J=df.derivative(G, current_solution) ) solver = df.NonlinearVariationalSolver(pde) solver.solve()
parRandom.normal(1., noise) # use the same noise across processors if rank == 0: noise_array = noise.get_local() else: noise_array = None noise_array = comm.bcast(noise_array, root=0) noise.set_local(noise_array) mtrue = dl.Vector() prior.init_vector(mtrue, 0) prior.sample(noise, mtrue) if rank == 0: filename = 'data/particle_true.xdmf' particle_fun = dl.Function(Vh[PARAMETER], name='particle') particle_fun.vector().axpy(1.0, mtrue) if dlversion() <= (1, 6, 0): dl.File(mesh.mpi_comm(), filename) << particle_fun else: xf = dl.XDMFFile(mesh.mpi_comm(), filename) xf.write(particle_fun) utrue = pde.generate_state() x = [utrue, mtrue, None] pde.solveFwd(x[STATE], x, 1e-9) misfit.B.mult(x[STATE], misfit.d) rel_noise = 0.01 MAX = misfit.d.norm("linf") noise_std_dev = rel_noise * MAX parRandom.normal_perturb(noise_std_dev, misfit.d)
def get_residual_form(u, v, rho_e, V_density, tractionBC, T, iteration_number, additive='strain', k=8., method='RAMP'): df.dx = df.dx(metadata={"quadrature_degree": 4}) # stiffness = rho_e/(1 + 8. * (1. - rho_e)) if method == 'SIMP': stiffness = rho_e**3 else: stiffness = rho_e / (1 + 8. * (1. - rho_e)) # print('the value of stiffness is:', rho_e.vector().get_local()) # Kinematics d = len(u) I = df.Identity(d) # Identity tensor F = I + df.grad(u) # Deformation gradient C = F.T * F # Right Cauchy-Green tensor # Invariants of deformation tensors Ic = df.tr(C) J = df.det(F) stiffen_pow = 1. threshold_vol = 1. eps_star = 0.05 # print("eps_star--------") if additive == 'strain': print("additive == strain") if iteration_number == 1: print('iteration_number == 1') eps = df.sym(df.grad(u)) eps_dev = eps - 1 / 3 * df.tr(eps) * df.Identity(2) eps_eq = df.sqrt(2.0 / 3.0 * df.inner(eps_dev, eps_dev)) # eps_eq_proj = df.project(eps_eq, density_function_space) ratio = eps_eq / eps_star ratio_proj = df.project(ratio, V_density) c1_e = k * (5.e-2) / (1 + 8. * (1. - (5.e-2))) / 6 c2_e = df.Function(V_density) c2_e.vector().set_local(5e-4 * np.ones(V_density.dim())) fFile = df.HDF5File(df.MPI.comm_world, "c2_e_proj.h5", "w") fFile.write(c2_e, "/f") fFile.close() fFile = df.HDF5File(df.MPI.comm_world, "ratio_proj.h5", "w") fFile.write(ratio_proj, "/f") fFile.close() iteration_number += 1 E = k * stiffness phi_add = (1 - stiffness) * ((c1_e * (Ic - 3)) + (c2_e * (Ic - 3))**2) else: ratio_proj = df.Function(V_density) fFile = df.HDF5File(df.MPI.comm_world, "ratio_proj.h5", "r") fFile.read(ratio_proj, "/f") fFile.close() c2_e = df.Function(V_density) fFile = df.HDF5File(df.MPI.comm_world, "c2_e_proj.h5", "r") fFile.read(c2_e, "/f") fFile.close() c1_e = k * (5.e-2) / (1 + 8. * (1. - (5.e-2))) / 6 c2_e = df.conditional(df.le(ratio_proj, eps_star), c2_e * df.sqrt(ratio_proj), c2_e * (ratio_proj**3)) phi_add = (1 - stiffness) * ((c1_e * (Ic - 3)) + (c2_e * (Ic - 3))**2) E = k * stiffness c2_e_proj = df.project(c2_e, V_density) print('c2_e projected -------------') eps = df.sym(df.grad(u)) eps_dev = eps - 1 / 3 * df.tr(eps) * df.Identity(2) eps_eq = df.sqrt(2.0 / 3.0 * df.inner(eps_dev, eps_dev)) # eps_eq_proj = df.project(eps_eq, V_density) ratio = eps_eq / eps_star ratio_proj = df.project(ratio, V_density) fFile = df.HDF5File(df.MPI.comm_world, "c2_e_proj.h5", "w") fFile.write(c2_e_proj, "/f") fFile.close() fFile = df.HDF5File(df.MPI.comm_world, "ratio_proj.h5", "w") fFile.write(ratio_proj, "/f") fFile.close() elif additive == 'vol': print("additive == vol") stiffness = stiffness / (df.det(F)**stiffen_pow) # stiffness = df.conditional(df.le(df.det(F),threshold_vol), (stiffness/(df.det(F)/threshold_vol))**stiffen_pow, stiffness) E = k * stiffness elif additive == 'False': print("additive == False") E = k * stiffness # rho_e is the design variable, its values is from 0 to 1 nu = 0.4 # Poisson's ratio lambda_ = E * nu / (1. + nu) / (1 - 2 * nu) mu = E / 2 / (1 + nu) #lame's parameters # Stored strain energy density (compressible neo-Hookean model) psi = (mu / 2) * (Ic - 3) - mu * df.ln(J) + (lambda_ / 2) * (df.ln(J))**2 # print('the length of psi is:',len(psi.vector())) if additive == 'strain': psi += phi_add B = df.Constant((0.0, 0.0)) # Total potential energy '''The first term in this equation provided this error''' Pi = psi * df.dx - df.dot(B, u) * df.dx - df.dot(T, u) * tractionBC res = df.derivative(Pi, u, v) return res
def ii_derivative(f, x): '''DOLFIN's derivative df/dx extended to handle trace stuff''' test_f = is_okay_functional(f) # FIXME: for now don't allow diffing wrt compound expressions, in particular # restricted args. assert isinstance(x, ufl.Coefficient) and not is_restricted(x) # So now we have L(arg, v) where arg = (u, ..., T[u], Pi[u], ...) and the idea # is to define derivative w.r.t to x by doing # J = sum_{arg} (partial L / partial arg){arg=T[u]}(partial arg / partial x). J = 0 # NOTE: in the following I try to avoid assembly of zero forms because # these might not be well-defined for xii assembler. Also, assembling # zeros is useless for fi in [c for c in f.coefficients() if not isinstance(c, df.Constant)]: # Short circuit if (partial fi)/(partial x) is 0 if not ((fi == x) or fi.vector().id() == x.vector().id()): continue if is_restricted(fi): rtype = restriction_type(fi) attributes = (rtype, ) else: rtype = '' attributes = None fi_sub = df.Function(fi.function_space()) # To recreate the form for partial we sub in every integral of f sub_form_integrals = [] for integral in f.integrals(): integrand = ii_replace(integral.integrand(), fi, fi_sub, attributes) # If the substitution is do nothing then there's no need to diff if integrand != integral.integrand(): sub_form_integrals.append( integral.reconstruct(integrand=integrand)) sub_form = ufl.Form(sub_form_integrals) # Partial wrt to substituated argument df_dfi = df.derivative(sub_form, fi_sub) # Substitue back the original form argument sub_form_integrals = [] for integral in df_dfi.integrals(): integrand = ii_replace(integral.integrand(), fi_sub, fi) assert integrand != integral.integrand() sub_form_integrals.append( integral.reconstruct(integrand=integrand)) df_dfi = ufl.Form(sub_form_integrals) # As d Tu / dx = T(x) we now need to restrict the trial function if rtype: trial_f = get_trialfunction(df_dfi) setattr(trial_f, rtype, getattr(fi, rtype)) # Since we only allos diff wrt to coef then in the case rtype == '' # we have dfi/dx = 1 J += df_dfi # Done return J
dl.File("results/poisson_parameter_prmean.pvd") << vector2Function( prior.mean, Vh[PARAMETER], name=xxname[PARAMETER]) dl.File("results/poisson_adjoint.pvd") << xx[ADJOINT] exportPointwiseObservation(Vh[STATE], misfit.B, misfit.d, "results/poisson_observation") if rank == 0: print(sep, "Generate samples from Prior and Posterior\n", "Export generalized Eigenpairs", sep) fid_prior = dl.File("samples/sample_prior.pvd") fid_post = dl.File("samples/sample_post.pvd") nsamples = 500 noise = dl.Vector() posterior.init_vector(noise, "noise") s_prior = dl.Function(Vh[PARAMETER], name="sample_prior") s_post = dl.Function(Vh[PARAMETER], name="sample_post") for i in range(nsamples): parRandom.normal(1., noise) posterior.sample(noise, s_prior.vector(), s_post.vector()) fid_prior << s_prior fid_post << s_post #Save eigenvalues for printing: U.export(Vh[PARAMETER], "hmisfit/evect.pvd", varname="gen_evects", normalize=True) if rank == 0: np.savetxt("hmisfit/eigevalues.dat", d)
def assemble(self, form, arity): '''Assemble a biliner(2), linear(1) form''' reduced_integrals = self.select_integrals(form) #! Selector # Signal to xii.assemble if not reduced_integrals: return None components = [] for integral in form.integrals(): # Delegate to friend if integral not in reduced_integrals: components.append( xii.assembler.xii_assembly.assemble(Form([integral]))) continue reduced_mesh = integral.ufl_domain().ufl_cargo() integrand = integral.integrand() # Split arguments in those that need to be and those that are # already restricted. terminals = set(traverse_unique_terminals(integrand)) # FIXME: is it enough info (in general) to decide terminals_to_restrict = self.restriction_filter( terminals, reduced_mesh) # You said this is a trace ingral! assert terminals_to_restrict # Let's pick a guy for restriction terminal = terminals_to_restrict.pop() # We have some assumption on the candidate assert self.is_compatible(terminal, reduced_mesh) data = self.reduction_matrix_data(terminal) integrand = ufl2uflcopy(integrand) # With sane inputs we can get the reduced element and setup the # intermediate function space where the reduction of terminal # lives V = terminal.function_space() TV = self.reduced_space(V, reduced_mesh) #! Space construc # Setup the matrix to from space of the trace_terminal to the # intermediate space. FIXME: normal and trace_mesh #! mat construct df.info('\tGetting reduction op') rop_timer = df.Timer('rop') T = self.reduction_matrix(V, TV, reduced_mesh, data) df.info('\tDone (reduction op) %g' % rop_timer.stop()) # T if is_test_function(terminal): replacement = df.TestFunction(TV) # Passing the args to get the comparison a make substitution integrand = replace(integrand, terminal, replacement, attributes=self.attributes) trace_form = Form([integral.reconstruct(integrand=integrand)]) if arity == 2: # Make attempt on the substituted form A = xii.assembler.xii_assembly.assemble(trace_form) components.append(block_transpose(T) * A) else: b = xii.assembler.xii_assembly.assemble(trace_form) Tb = df.Function(V).vector() # Alloc and apply T.transpmult(b, Tb) components.append(Tb) if is_trial_function(terminal): assert arity == 2 replacement = df.TrialFunction(TV) # Passing the args to get the comparison integrand = replace(integrand, terminal, replacement, attributes=self.attributes) trace_form = Form([integral.reconstruct(integrand=integrand)]) A = xii.assembler.xii_assembly.assemble(trace_form) components.append(A * T) # Okay, then this guy might be a function if isinstance(terminal, df.Function): replacement = df.Function(TV) # Replacement is not just a placeholder T.mult(terminal.vector(), replacement.vector()) # Substitute integrand = replace(integrand, terminal, replacement, attributes=self.attributes) trace_form = Form([integral.reconstruct(integrand=integrand)]) components.append( xii.assembler.xii_assembly.assemble(trace_form)) # The whole form is then the sum of integrals return reduce(operator.add, components)
tau = df.Constant(parameters["tau"]) h = df.Constant(parameters["h"]) M = df.Constant(parameters["M"]) geo_map = TorusMap(R, r) geo_map.initialize(res, restart_folder=parameters["restart_folder"]) W = geo_map.mixed_space((geo_map.ref_el, ) * 4) # Define trial and test functions du = df.TrialFunction(W) chi, xi, eta, etahat = df.TestFunctions(W) # Define functions u = df.TrialFunction(W) u_ = df.Function(W, name="u_") # current solution u_1 = df.Function(W, name="u_1") # solution from previous converged step # Split mixed functions psi, mu, nu, nuhat = df.split(u) psi_, mu_, nu_, nuhat_ = df.split(u_) psi_1, mu_1, nu_1, nuhat_1 = df.split(u_1) # Create intial conditions if parameters["restart_folder"] is None: init_mode = parameters["init_mode"] if init_mode == "random": u_init = RandomIC(u_, degree=1) elif init_mode == "striped": u_init = StripedIC(u_, alpha=parameters["alpha"] * np.pi / 180.0,
def scalar_laplacians(mesh): """ Calculate the laplacians needed by fiberrule algorithms Arguments --------- mesh : dolfin.Mesh A dolfin mesh with marked boundaries: base = 10, rv = 20, lv = 30, epi = 40 The base is assumed placed at x=0 """ if not isinstance(mesh, d.Mesh): raise TypeError("Expected a dolfin.Mesh as the mesh argument.") # Init connectivities mesh.init(2) facet_markers = d.MeshFunction("size_t", mesh, 2, mesh.domains()) # Boundary markers, solutions and cases markers = dict(base=10, rv=20, lv=30, epi=40, apex=50) # Solver parameters solver_param=dict(solver_parameters=dict( preconditioner="ml_amg" if d.has_krylov_solver_preconditioner("ml_amg") \ else "default", linear_solver="gmres")) cases = ["rv", "lv", "epi"] boundaries = cases + ["base"] # Check that all boundary faces are marked num_boundary_facets = d.BoundaryMesh(mesh, "exterior").num_cells() if num_boundary_facets != sum(np.sum(\ facet_markers.array()==markers[boundary])\ for boundary in boundaries): d.error("Not all boundary faces are marked correctly. Make sure all "\ "boundary facets are marked as: base = 10, rv = 20, lv = 30, "\ "epi = 40.") # Coords and cells coords = mesh.coordinates() cells_info = mesh.cells() # Find apex by solving a laplacian with base solution = 0 # Create Base variational problem V = d.FunctionSpace(mesh, "CG", 1) u = d.TrialFunction(V) v = d.TestFunction(V) a = d.dot(d.grad(u), d.grad(v)) * d.dx L = v * d.Constant(1) * d.dx DBC_10 = d.DirichletBC(V, 1, facet_markers, markers["base"], "topological") # Create solutions solutions = dict( (what, d.Function(V)) for what in markers if what != "base") d.solve(a == L, solutions["apex"], DBC_10, solver_parameters={"linear_solver": "gmres"}) apex_values = solutions["apex"].vector().array() apex_values[d.dof_to_vertex_map(V)] = solutions["apex"].vector().array() ind_apex_max = apex_values.argmax() apex_coord = coords[ind_apex_max, :] # Update rhs L = v * d.Constant(0) * d.dx d.info(" Apex coord: ({0}, {1}, {2})".format(*apex_coord)) d.info(" Num coords: {0}".format(len(coords))) d.info(" Num cells: {0}".format(len(cells_info))) # Calculate volume volume = 0.0 for cell in d.cells(mesh): volume += cell.volume() d.info(" Volume: {0}".format(volume)) d.info("") # Cases # ===== # # 1) base: 1, apex: 0 # 2) lv: 1, rv, epi: 0 # 3) rv: 1, lv, epi: 0 # 4) epi: 1, rv, lv: 0 class ApexDomain(d.SubDomain): def inside(self, x, on_boundary): return d.near(x[0], apex_coord[0]) and d.near(x[1], apex_coord[1]) and \ d.near(x[2], apex_coord[2]) apex_domain = ApexDomain() # Case 1: Poisson = 1 DBC_11 = d.DirichletBC(V, 0, apex_domain, "pointwise") # Using Poisson if Poisson: d.solve(a == L, solutions["apex"], [DBC_10, DBC_11], solver_parameters={"linear_solver": "gmres"}) # Using Eikonal equation else: Le = v * d.Constant(1) * d.dx d.solve(a == Le, solutions["apex"], DBC_11, solver_parameters={"linear_solver": "gmres"}) # Create Eikonal problem eps = d.Constant(mesh.hmax() / 25) y = solutions["apex"] F = d.sqrt(d.inner(d.grad(y), d.grad(y)))*v*d.dx - \ d.Constant(1)*v*d.dx + eps*d.inner(d.grad(y), d.grad(v))*d.dx d.solve(F == 0, y, DBC_11, solver_parameters={ "linear_solver": "lu", "newton_solver": { "relative_tolerance": 1e-5 } }) # Check that solution of the three last cases all sum to 1. sol = solutions["apex"].vector().copy() sol[:] = 0.0 # Iterate over the three different cases for case in cases: # Solve linear system bcs = [d.DirichletBC(V, 1 if what == case else 0, \ facet_markers, markers[what], "topological") \ for what in cases]
def solve(selfmat, var, b): if selfmat.adjoint: operators = transpose_operators(selfmat.operators) else: operators = selfmat.operators # Fetch/construct the solver if var.type in ['ADJ_FORWARD', 'ADJ_TLM']: solver = krylov_solvers[idx] need_to_set_operator = self._need_to_reset_operator else: if adj_krylov_solvers[idx] is None: need_to_set_operator = True adj_krylov_solvers[idx] = KrylovSolver( *solver_parameters) else: need_to_set_operator = self._need_to_reset_operator solver = adj_krylov_solvers[idx] solver.parameters.update(parameters) self._need_to_reset_operator = False if selfmat.adjoint: (nsp_, tnsp_) = (tnsp, nsp) else: (nsp_, tnsp_) = (nsp, tnsp) x = dolfin.Function(fn_space) if selfmat.initial_guess is not None and var.type == 'ADJ_FORWARD': x.vector()[:] = selfmat.initial_guess.vector() if b.data is None: dolfin.info_red( "Warning: got zero RHS for the solve associated with variable %s" % var) return adjlinalg.Vector(x) if var.type in ['ADJ_TLM', 'ADJ_ADJOINT']: selfmat.bcs = [ utils.homogenize(bc) for bc in selfmat.bcs if isinstance(bc, dolfin.cpp.DirichletBC) ] + [ bc for bc in selfmat.bcs if not isinstance(bc, dolfin.cpp.DirichletBC) ] # This is really hideous. Sorry. if isinstance(b.data, dolfin.Function): rhs = b.data.vector().copy() [bc.apply(rhs) for bc in selfmat.bcs] if need_to_set_operator: if assemble_system: # if we called assemble_system, rather than assemble v = dolfin.TestFunction(fn_space) (A, rhstmp) = dolfin.assemble_system( operators[0], dolfin.inner(b.data, v) * dolfin.dx, selfmat.bcs) if has_preconditioner: (P, rhstmp) = dolfin.assemble_system( operators[1], dolfin.inner(b.data, v) * dolfin.dx, selfmat.bcs) solver.set_operators(A, P) else: solver.set_operator(A) else: # we called assemble A = dolfin.assemble(operators[0]) [bc.apply(A) for bc in selfmat.bcs] if has_preconditioner: P = dolfin.assemble(operators[1]) [bc.apply(P) for bc in selfmat.bcs] solver.set_operators(A, P) else: solver.set_operator(A) else: if assemble_system: # if we called assemble_system, rather than assemble (A, rhs) = dolfin.assemble_system( operators[0], b.data, selfmat.bcs) if need_to_set_operator: if has_preconditioner: (P, rhstmp) = dolfin.assemble_system( operators[1], b.data, selfmat.bcs) solver.set_operators(A, P) else: solver.set_operator(A) else: # we called assemble A = dolfin.assemble(operators[0]) rhs = dolfin.assemble(b.data) [bc.apply(A) for bc in selfmat.bcs] [bc.apply(rhs) for bc in selfmat.bcs] if need_to_set_operator: if has_preconditioner: P = dolfin.assemble(operators[1]) [bc.apply(P) for bc in selfmat.bcs] solver.set_operators(A, P) else: solver.set_operator(A) # Set the nullspace for the linear operator if nsp_ is not None and need_to_set_operator: dolfin.as_backend_type(A).set_nullspace(nsp_) # (Possibly override the user in) orthogonalize # the right-hand-side if tnsp_ is not None: tnsp_.orthogonalize(rhs) solver.solve(x.vector(), rhs) return adjlinalg.Vector(x)
def test_assembly_ds_domains(mesh): V = dolfin.FunctionSpace(mesh, ("CG", 1)) u, v = dolfin.TrialFunction(V), dolfin.TestFunction(V) marker = dolfin.MeshFunction("size_t", mesh, mesh.topology.dim - 1, 0) def bottom(x): return numpy.isclose(x[:, 1], 0.0) def top(x): return numpy.isclose(x[:, 1], 1.0) def left(x): return numpy.isclose(x[:, 0], 0.0) def right(x): return numpy.isclose(x[:, 0], 1.0) marker.mark(bottom, 111) marker.mark(top, 222) marker.mark(left, 333) marker.mark(right, 444) ds = ufl.Measure('ds', subdomain_data=marker, domain=mesh) w = dolfin.Function(V) with w.vector.localForm() as w_local: w_local.set(0.5) # # Assemble matrix # a = w * ufl.inner(u, v) * (ds(111) + ds(222) + ds(333) + ds(444)) A = dolfin.fem.assemble_matrix(a) A.assemble() norm1 = A.norm() a2 = w * ufl.inner(u, v) * ds A2 = dolfin.fem.assemble_matrix(a2) A2.assemble() norm2 = A2.norm() assert norm1 == pytest.approx(norm2, 1.0e-12) # # Assemble vector # L = ufl.inner(w, v) * (ds(111) + ds(222) + ds(333) + ds(444)) b = dolfin.fem.assemble_vector(L) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) L2 = ufl.inner(w, v) * ds b2 = dolfin.fem.assemble_vector(L2) b2.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) assert b.norm() == pytest.approx(b2.norm(), 1.0e-12) # # Assemble scalar # L = w * (ds(111) + ds(222) + ds(333) + ds(444)) s = dolfin.fem.assemble_scalar(L) s = dolfin.MPI.sum(mesh.mpi_comm(), s) L2 = w * ds s2 = dolfin.fem.assemble_scalar(L2) s2 = dolfin.MPI.sum(mesh.mpi_comm(), s2) assert (s == pytest.approx(s2, 1.0e-12) and 2.0 == pytest.approx(s, 1.0e-12))
def __init__(self, problem_params, dtype_u, dtype_f): """ Initialization routine Args: problem_params (dict): custom parameters for the example dtype_u: particle data type (will be passed parent class) dtype_f: acceleration data type (will be passed parent class) """ # Sub domain for Periodic boundary condition class PeriodicBoundary(df.SubDomain): # Left boundary is "target domain" G def inside(self, x, on_boundary): return bool(df.DOLFIN_EPS > x[0] > -df.DOLFIN_EPS and on_boundary) # Map right boundary (H) to left boundary (G) def map(self, x, y): y[0] = x[0] - 1.0 # these parameters will be used later, so assert their existence essential_keys = [ 'c_nvars', 't0', 'family', 'order', 'refinements', 'nu', 'freq' ] for key in essential_keys: if key not in problem_params: msg = 'need %s to instantiate problem, only got %s' % ( key, str(problem_params.keys())) raise ParameterError(msg) # set logger level for FFC and dolfin df.set_log_level(df.WARNING) logging.getLogger('FFC').setLevel(logging.WARNING) # set solver and form parameters df.parameters["form_compiler"]["optimize"] = True df.parameters["form_compiler"]["cpp_optimize"] = True # set mesh and refinement (for multilevel) mesh = df.UnitIntervalMesh(self.params.c_nvars) for i in range(self.refinements): mesh = df.refine(mesh) # define function space for future reference self.V = df.FunctionSpace(mesh, self.params.family, self.params.order, constrained_domain=PeriodicBoundary()) tmp = df.Function(self.V) print('DoFs on this level:', len(tmp.vector().array())) # invoke super init, passing number of dofs, dtype_u and dtype_f super(fenics_adv_diff_1d, self).__init__(self.V, dtype_u, dtype_f, problem_params) u = df.TrialFunction(self.V) v = df.TestFunction(self.V) # Stiffness term (diffusion) a_K = -1.0 * df.inner(df.nabla_grad(u), self.params.nu * df.nabla_grad(v)) * df.dx # Stiffness term (advection) a_G = df.inner(self.params.mu * df.nabla_grad(u)[0], v) * df.dx # Mass term a_M = u * v * df.dx self.M = df.assemble(a_M) self.K = df.assemble(a_K) self.G = df.assemble(a_G)