def _read_from_xdmf_file(fun, directory, filename, suffix, components=None): if components is not None: filename = filename + "_component_" + "".join(components) function_name = "function_" + "".join(components) else: function_name = "function" fun_rank = fun.value_rank() fun_dim = product(fun.value_shape()) assert fun_rank <= 2 if ((fun_rank is 1 and fun_dim not in (2, 3)) or (fun_rank is 2 and fun_dim not in (4, 9))): fun_V = fun.function_space() for i in range(fun_dim): if components is not None: filename_i = filename + "_subcomponent_" + str(i) else: filename_i = filename + "_component_" + str(i) fun_i_V = get_function_subspace(fun_V, i) fun_i = Function(fun_i_V) if not _read_from_xdmf_file(fun_i, directory, filename_i, suffix, None): return False else: assign(fun.sub(i), fun_i) return True else: full_filename_checkpoint = os.path.join(str(directory), filename + "_checkpoint.xdmf") file_exists = False if is_io_process() and os.path.exists(full_filename_checkpoint): file_exists = True file_exists = is_io_process.mpi_comm.bcast(file_exists, root=is_io_process.root) if file_exists: if suffix is not None: assert SuffixIO.exists_file(directory, filename + "_suffix") last_suffix = SuffixIO.load_file(directory, filename + "_suffix") if suffix <= last_suffix: if full_filename_checkpoint in _all_xdmf_files: assert _all_xdmf_latest_suffix[ full_filename_checkpoint] == suffix - 1 _all_xdmf_latest_suffix[ full_filename_checkpoint] = suffix else: assert suffix == 0 _all_xdmf_files[full_filename_checkpoint] = XDMFFile( full_filename_checkpoint) _all_xdmf_latest_suffix[full_filename_checkpoint] = 0 _all_xdmf_files[full_filename_checkpoint].read_checkpoint( fun, function_name, suffix) return True else: return False else: with XDMFFile(full_filename_checkpoint) as file_checkpoint: file_checkpoint.read_checkpoint(fun, function_name, 0) return True else: return False
def _read_from_file(fun, directory, filename, suffix, components=None): if components is not None: filename = filename + "_component_" + "".join(components) function_name = "function_" + "".join(components) else: function_name = "function" fun_rank = fun.value_rank() fun_dim = product(fun.value_shape()) assert fun_rank <= 2 if ((fun_rank is 1 and fun_dim not in (2, 3)) or (fun_rank is 2 and fun_dim not in (4, 9))): funs = fun.split(deepcopy=True) for (i, fun_i) in enumerate(funs): if components is not None: filename_i = filename + "_subcomponent_" + str(i) else: filename_i = filename + "_component_" + str(i) _read_from_file(fun_i, directory, filename_i, suffix, None) assign(fun.sub(i), fun_i) else: if suffix is not None: if suffix is 0: # Remove from storage and re-create try: del _all_solution_files[(directory, filename)] except KeyError: pass _all_solution_files[(directory, filename)] = SolutionFile( directory, filename) file_ = _all_solution_files[(directory, filename)] file_.read(fun, function_name, suffix) else: file_ = SolutionFile(directory, filename) file_.read(fun, function_name, 0)
def initialize(self, warp, istart): self.istart = istart for i in xrange(istart, istart + self.N): rad = 0.0 ist = 0 for n, d in zip(self.Ns, self.Dias): for j in xrange(n): print j fib = warp.fibrils[i * np.sum(self.Ns) + ist] qhh = Geometry_Curves.qhh_stockinette2 temp_field = Function(fib.problem.spaces['V']) p1 = rad * np.cos(2.0 * np.pi * float(j) / float(n)) p2 = rad * np.sin(2.0 * np.pi * float(j) / float(n)) for fix in xrange(3): temp_field.interpolate( Expression(qhh[fix], sq=-(self.restL - self.setL) / self.restL, p=np.pi / self.restL * (4.0), o=self.setL / 3.5, A1=1.3 * self.width / self.N, A2=self.width / self.N, y1=p1, y2=p2)) assign(fib.problem.fields['wx'].sub(fix), temp_field) temp_field.interpolate(Constant((0.0, 0.0, 0.0))) assign(fib.problem.fields['wv'].sub(fix), temp_field) ist += 1 rad += d
def _write_to_pvd_file(fun, directory, filename, suffix, components=None): if components is not None: filename = filename + "_component_" + "".join(components) fun_rank = fun.value_rank() fun_dim = product(fun.value_shape()) assert fun_rank <= 2 if ((fun_rank is 1 and fun_dim not in (2, 3)) or (fun_rank is 2 and fun_dim not in (4, 9))): funs = fun.split(deepcopy=True) for (i, fun_i) in enumerate(funs): if components is not None: filename_i = filename + "_subcomponent_" + str(i) else: filename_i = filename + "_component_" + str(i) _write_to_pvd_file(fun_i, directory, filename_i, suffix) else: full_filename = os.path.join(str(directory), filename + ".pvd") if suffix is not None: if full_filename in _all_pvd_files: assert _all_pvd_latest_suffix[full_filename] == suffix - 1 _all_pvd_latest_suffix[full_filename] = suffix else: assert suffix == 0 _all_pvd_files[full_filename] = File(full_filename, "compressed") _all_pvd_latest_suffix[full_filename] = 0 _all_pvd_functions[full_filename] = fun.copy(deepcopy=True) # Make sure to always use the same function, otherwise dolfin # changes the numbering and visualization is difficult in ParaView assign(_all_pvd_functions[full_filename], fun) _all_pvd_files[full_filename] << _all_pvd_functions[full_filename] else: file_ = File(full_filename, "compressed") file_ << fun
def hessianab(self, m1h, m2h): """ m1h, m2h = Vector(V) """ setfct(self.m1, m1h) setfct(self.m2, m2h) assign(self.m.sub(0), self.m1) assign(self.m.sub(1), self.m2) return self.regTV.hessian(self.m.vector())
def hessianab(self, m1h, m2h): """ m1h, m2h = Vector(V) """ setfct(self.m1h, m1h) setfct(self.m2h, m2h) assign(self.m12h.sub(0), self.m1h) assign(self.m12h.sub(1), self.m2h) return self.H * self.m12h.vector()
def hessianab(self, ahat, bhat): """ ahat, bhat = Vector(V) """ setfct(self.ahat, ahat) setfct(self.bhat, bhat) assign(self.abhat.sub(0), self.ahat) assign(self.abhat.sub(1), self.bhat) return self.H * self.abhat.vector()
def solve(self, sol, rhs): """ Solve A.sol = rhs Arguments: sol = solution rhs = rhs """ self.ab.vector().zero() self.ab.vector().axpy(1.0, rhs) a, b = self.ab.split(deepcopy=True) xa, xb = self.X.split(deepcopy=True) if self.param == 'a': n_pcg = self.solver.solve(xa.vector(), a.vector()) xb.vector().zero() xb.vector().axpy(1.0, b.vector()) elif self.param == 'b': xa.vector().zero() xa.vector().axpy(1.0, a.vector()) n_pcg = self.solver.solve(xb.vector(), b.vector()) dl.assign(self.X.sub(0), xa) dl.assign(self.X.sub(1), xb) sol.zero() sol.axpy(1.0, self.X.vector()) return n_pcg
def diffusivity_field_simple(setup, r, ddata_bulk, boundary="poresolidb"): "interpolates diffusivity field defined on the geometry given by setup" # build 1D interpolations from data fn, ft = preprocess_Dr(ddata_bulk, r) setup.prerefine(visualize=True) dist = distance_boundary_from_geo(setup.geo, boundary) VV = dolfin.VectorFunctionSpace(setup.geo.mesh, "CG", 1) normal = dolfin.project(dolfin.grad(dist), VV) phys = setup.phys D0 = phys.kT / (6. * np.pi * phys.eta * r * 1e-9) def DBulk(x, i): r = dist(x) n = normal(x) Dn = D0 * float(fn(r)) Dt = D0 * float(ft(r)) D = transformation(n, Dn, Dt) return D[i][i] D = lambda i: dict(fluid=lambda x: DBulk(x, i), ) dim = setup.geop.dim DD = [harmonic_interpolation(setup, subdomains=D(i)) for i in range(dim)] D = dolfin.Function(VV) dolfin.assign(D, DD) return dict(dist=dist, D=D)
def block_assign(object_to, object_from): assert isinstance(object_to, BlockFunction) and isinstance( object_from, BlockFunction) as_backend_type(object_from.block_vector()).vec().copy( as_backend_type(object_to.block_vector()).vec()) object_to.block_vector().apply("insert") for (function_to, function_from) in zip(object_to, object_from): assign(function_to, function_from)
def solve(self): assert not hasattr(self, "_is_solving") self._is_solving = True f00 = project(self.f00, self.V00) f01 = project(self.f01, self.V00) assign(self._solution.sub(0).sub(0), f00) assign(self._solution.sub(0).sub(1), f01) delattr(self, "_is_solving") return self._solution
def solve(self): print("solving mock problem at mu =", self.mu) assert not hasattr(self, "_is_solving") self._is_solving = True f00 = project(self.f00, self.V00) f01 = project(self.f01, self.V00) assign(self._solution.sub(0).sub(0), f00) assign(self._solution.sub(0).sub(1), f01) delattr(self, "_is_solving") return self._solution
def function_load(fun, directory, filename, suffix=None): fun_V = fun.function_space() if hasattr(fun_V, "_index_to_components") and len(fun_V._index_to_components) > 1: for (index, components) in fun_V._index_to_components.items(): sub_fun_V = get_function_subspace(fun_V, components) sub_fun = Function(sub_fun_V) _read_from_file(sub_fun, directory, filename, suffix, components) assign(fun.sub(index), sub_fun) else: _read_from_file(fun, directory, filename, suffix)
def _split_func_to_vec(self, function): """ Given a split object (after a function.split(), returns a unified vector representation :param function: tuple of functions after split :return: dolfin.vector with elements assigned according to function values """ dolf_function = dolf.Function(self.forms.function_space) for i in range(len(function)): dolf.assign(dolf_function.sub(i), function[i]) return dolf_function.vector()
def update(self, f, field, step): """ Set dolfin vector f with values from field. """ if field == "u": u_data = self["u", step][:, :self.dim] for i in range(self.dim): self.set_val(self.dummy_function, u_data[:, i]) df.assign(f.sub(i), self.dummy_function) else: f_data = self[field, step][:] self.set_val(f, f_data)
def reconstruct_solution(reduced_solution, N): (mesh, _, _, restrictions) = read_mesh() W = generate_block_function_space(mesh, restrictions) reconstructed_solution = BlockFunction(W) basis_functions = read_basis_functions(W, N) for c in components: assign(reconstructed_solution.sub(c), (basis_functions[c] * reduced_solution[c]).sub(c)) reconstructed_solution.apply("from subfunctions") return reconstructed_solution
def mult(self, ahat, y): self.ahat.vector().zero() self.ahat.vector().axpy(1.0, ahat) self.abhat.vector().zero() dl.assign(self.abhat.sub(0), self.ahat) self.obj.mult(self.abhat.vector(), self.yab.vector()) ya, yb = self.yab.split(deepcopy=True) y.zero() y.axpy(1.0, ya.vector()) y.axpy(1.0, self.regul.hessian(ahat))
def compare_ab_global(self): """ Check that med param (a, b) are the same across all proc """ assign(self.ab.sub(0), self.PDE.a) assign(self.ab.sub(1), self.PDE.b) ab_recv = self.ab.vector().copy() normabloc = np.linalg.norm(self.ab.vector().array()) MPIAllReduceVector(self.ab.vector(), ab_recv, self.mpicomm_global) ab_recv /= MPI.size(self.mpicomm_global) diff = ab_recv - self.ab.vector() reldiff = np.linalg.norm(diff.array())/normabloc assert reldiff < 2e-16, 'Diff in (a,b) across proc: {:.2e}'.format(reldiff)
def solve_time_step(self, t): A = self.assembler.getMatrix() P, P_diff = self.assembler.getPreconditioners() b = self.assembler.getRHS(t, self.us_nm1, self.us_nm2, self.uf_nm1, self.p_nm1) for bc in self.bcs: for obj in [A, P, b]: bc.apply(obj) if self.three_way: bc.apply(P_diff) if self.three_way: for bc in self.bcs_diff: bc.apply(P_diff) if self.first_timestep: self.create_solver(A, P, P_diff, b) self.first_timestep = False self.solver.set_up() self.solver.solve(b.vec(), self.sol.vector().vec()) self.sol.vector().apply("") # Update ghost dofs # Update solution us, uf, p = self.sol.split(True) df.assign(self.us_nm2, self.us_nm1) df.assign(self.us_nm1, us) df.assign(self.uf_nm1, uf) df.assign(self.p_nm1, p) return self.solver.getIterationNumber()
def initialize(self, warp, istart): self.istart = istart for i in xrange(istart, istart + self.NX): for j in xrange(np.sum(self.pattern)): fib = warp.fibrils[i * np.sum(self.pattern) + j] qhh = Geometry_Curves.qhh_plain_0 temp_field = Function(fib.problem.spaces['V']) for fix in xrange(3): temp_field.interpolate( Expression(qhh[fix], sq=-(self.restX - self.setX) / self.restX, p=np.pi / self.restX * (self.NY) / 2.0, A1=(-1.0 if i % 2 == 0 else 1.0) * self.height)) assign(fib.problem.fields['wx'].sub(fix), temp_field) temp_field.interpolate(Constant((0.0, 0.0, 0.0))) assign(fib.problem.fields['wv'].sub(fix), temp_field) for i in xrange(istart + self.NX, istart + (self.NX + self.NY)): for j in xrange(np.sum(self.pattern)): fib = warp.fibrils[i * np.sum(self.pattern) + j] qhh = Geometry_Curves.qhh_plain_1 temp_field = Function(fib.problem.spaces['V']) for fix in xrange(3): temp_field.interpolate( Expression(qhh[fix], sq=-(self.restY - self.setY) / self.restY, p=np.pi / self.restY * (self.NX) / 2.0, A1=(-1.0 if i % 2 == 1 else 1.0) * self.height)) assign(fib.problem.fields['wx'].sub(fix), temp_field) temp_field.interpolate(Constant((0.0, 0.0, 0.0))) assign(fib.problem.fields['wv'].sub(fix), temp_field)
def testsplitassign(): USEi = True mesh = dl.UnitSquareMesh(40, 40) V1 = dl.FunctionSpace(mesh, "Lagrange", 2) V2 = dl.FunctionSpace(mesh, "Lagrange", 2) if USEi: V1V2 = createMixedFSi([V1, V2]) splitassign = SplitAndAssigni([V1, V2], mesh.mpi_comm()) else: V1V2 = createMixedFS(V1, V2) splitassign = SplitAndAssign(V1, V2, mesh.mpi_comm()) mpirank = dl.MPI.rank(mesh.mpi_comm()) u = dl.interpolate(dl.Expression(("x[0]*x[1]", "11+x[0]+x[1]"), degree=10), V1V2) uu = dl.Function(V1V2) u1, u2 = u.split(deepcopy=True) u1v, u2v = splitassign.split(u.vector()) u11 = dl.interpolate(dl.Expression("x[0]*x[1]", degree=10), V1) u22 = dl.interpolate(dl.Expression("11+x[0]+x[1]", degree=10), V2) a,b,c,d= dl.norm(u1.vector()-u1v), dl.norm(u2.vector()-u2v),\ dl.norm(u1.vector()-u11.vector()), dl.norm(u2.vector()-u22.vector()) if mpirank == 0: print '\nSplitting an interpolated function:', a, b, c, d if USEi: uv = splitassign.assign([u1v, u2v]) else: uv = splitassign.assign(u1v, u2v) dl.assign(uu.sub(0), u11) dl.assign(uu.sub(1), u22) a, b = dl.norm(uv - u.vector()), dl.norm(uv - uu.vector()) if mpirank == 0: print 'Putting it back together:', a, b for ii in xrange(10): u.vector()[:] = np.random.randn(len(u.vector().array())) u1, u2 = u.split(deepcopy=True) u1v, u2v = splitassign.split(u.vector()) if USEi: uv = splitassign.assign([u1v, u2v]) else: uv = splitassign.assign(u1v, u2v) a, b = dl.norm(u1.vector() - u1v), dl.norm(u2.vector() - u2v) c = dl.norm(uv - u.vector()) if mpirank == 0: print 'Splitting random numbers:', a, b print 'Putting it back together:', c
def evaluate_expression(expression, function, replaced_expression=None): if replaced_expression is None: replaced_expression = expression assert isinstance(expression, (BaseExpression, Function, Operator)) if isinstance(expression, BaseExpression): LagrangeInterpolator.interpolate(function, replaced_expression) elif isinstance(expression, Function): assign(function, replaced_expression) elif isinstance(expression, Operator): project(replaced_expression, function.function_space(), function=function) else: raise ValueError("Invalid expression")
def solve(self, opt): """ This procedure implements a first-order semi-Lagrangian time-stepping scheme to solve a parabolic second-order HJB equation in non-variational form - du/dt - sup_gamma{a^gamma : D^2 u + b^gamma * D u + c^gamma * u - f^gamma}= 0 """ if hasattr(self, 'dt'): opt["timeSteps"] *= opt["timeStepFactor"] nt = opt["timeSteps"] nc = len(self.gamma) Tspace = np.linspace(self.T[1], self.T[0], nt + 1) self.dt = (self.T[1] - self.T[0]) / nt self.u_np1 = Function(self.V) print('Setting final time conditions') assign(self.u, project(self.u_T, self.V)) if opt["saveSolution"]: file_u = File('./pvd/u.pvd') file_gamma = [] for i in range(nc): file_gamma.append(File('./pvd/gamma_{}.pvd'.format(i))) for i, s in enumerate(Tspace[1:]): self.current_time = s print('Iteration {}/{}:\t t = {}'.format(i + 1, nt, s)) self.iter = i # Update time in coefficient functions self.updateTime(s) assign(self.u_np1, self.u) # Solve problem for current time step super().solve(opt) # self.plotControl() # self.plotSolution() if opt["saveSolution"]: file_u << self.u for i in range(nc): try: file_gamma[i] << self.gamma[i] except AttributeError: file_gamma[i] << project(self.gamma[i], self.controlSpace[i])
def update_w(self, mhat, alphaLS, compute_what=True): """ update dual variable in direction what and update re-scaled version """ # Update wx and wy if compute_what: self.compute_what(mhat) self.regTV.wx.vector().axpy(alphaLS, self.regTV.wxhat.vector()) self.regTV.wy.vector().axpy(alphaLS, self.regTV.wyhat.vector()) # Update rescaled variables rescaledradiusdual = self.parameters['rescaledradiusdual'] # wx**2 as_backend_type(self.regTV.wxsq).vec().pointwiseMult(\ as_backend_type(self.regTV.wx.vector()).vec(),\ as_backend_type(self.regTV.wx.vector()).vec()) # wy**2 as_backend_type(self.regTV.wysq).vec().pointwiseMult(\ as_backend_type(self.regTV.wy.vector()).vec(),\ as_backend_type(self.regTV.wy.vector()).vec()) # |w| self.w_loc.vector().zero() self.w_loc.vector().axpy(1.0, self.regTV.wxsq + self.regTV.wysq) normw1, normw2 = self.w_loc.split(deepcopy=True) normw = normw1.vector() + normw2.vector() as_backend_type(normw).vec().sqrtabs() # |w|/r as_backend_type(normw).vec().pointwiseDivide(\ as_backend_type(normw).vec(),\ as_backend_type(self.one*rescaledradiusdual).vec()) # max(1.0, |w|/r) count = pointwiseMaxCount(self.factorw.vector(), normw, 1.0) # rescale wx and wy assign(self.factorww.sub(0), self.factorw) assign(self.factorww.sub(1), self.factorw) as_backend_type(self.regTV.wxrs.vector()).vec().pointwiseDivide(\ as_backend_type(self.regTV.wx.vector()).vec(),\ as_backend_type(self.factorww.vector()).vec()) as_backend_type(self.regTV.wyrs.vector()).vec().pointwiseDivide(\ as_backend_type(self.regTV.wy.vector()).vec(),\ as_backend_type(self.factorww.vector()).vec()) minf = self.factorw.vector().min() maxf = self.factorw.vector().max() if self.parameters['print']: print ('[V_TVPD] perc. dual entries rescaled={:.2f} %, ' +\ 'min(factorw)={}, max(factorw)={}').format(\ 100.*float(count)/self.factorw.vector().size(), minf, maxf)
def assign_scalars_to_vectorfunctions(components, vector_func): """ Assign the values of scalar functions to the components of a vector field. Parameters ---------- components : list, tuple A list/tuple of scalar-valued dolfin.Function objects used to create a vector-valued function. vector_func : dolfin.Function The vector-valued dolfin.Function object that the scalar components are to be assigned to. """ for i, component in enumerate(components): dlf.assign(vector_func.sub(i), component) return None
def load_initial_conditions(DS, c): V_phi = DS.subspace("phi", 0, deepcopy=True) k = V_phi.ufl_element().degree() phi_expr = df.Expression("0.5*(1.0 - tanh((2.0*x[1] - 1.0) / eps))", degree=k, eps=c[r"\eps"]) _phi = df.Function(V_phi) _phi.interpolate(phi_expr) pv0 = DS.primitive_vars_ptl(0) phi = pv0["phi"].split()[0] df.assign(phi, _phi) # with uncached dofmaps # FIXME: consider creating FunctionAssigner instances within DS # Copy interpolated initial condition also to CTL for i, w in enumerate(DS.solution_ptl(0)): DS.solution_ctl()[i].assign(w)
def mediummisfit(self, target_medium): """ Compute medium misfit at current position """ assign(self.ab.sub(0), self.PDE.a) assign(self.ab.sub(1), self.PDE.b) try: diff = self.ab.vector() - target_medium.vector() except: diff = self.ab.vector() - target_medium Md = self.Mass*diff self.ab.vector().zero() self.ab.vector().axpy(1.0, Md) Mda, Mdb = self.ab.split(deepcopy=True) self.ab.vector().zero() self.ab.vector().axpy(1.0, diff) da, db = self.ab.split(deepcopy=True) medmisfita = np.sqrt(da.vector().inner(Mda.vector())) medmisfitb = np.sqrt(db.vector().inner(Mdb.vector())) return medmisfita, medmisfitb
def update_w(self, alpha): """ update w and re-scale wH """ self.w.vector().axpy(alpha, self.dw.vector()) # project each w (coord-wise) onto unit sphere to get wH (wx, wy) = self.w.split(deepcopy=True) wxa, wya = wx.vector().array(), wy.vector().array() normw = np.sqrt(wxa**2 + wya**2) factorw = [max(1.0, ii) for ii in normw] setfct(wx, wxa/factorw) setfct(wy, wya/factorw) assign(self.wH.sub(0), wx) assign(self.wH.sub(1), wy) # check (wx,wy) = self.wH.split(deepcopy=True) wxa, wya = wx.vector().array(), wy.vector().array() assert np.amax(np.sqrt(wxa**2 + wya**2)) <= 1.0 + 1e-14 # Print results dualresnorm = assemble(self.dualresnorm) normgraddm = assemble(self.normgraddm) print 'line search dual variable: max(|w|)={}, err(w,df)={}, |grad(dm)|={}'.\ format(np.amax(np.sqrt(normw)), np.sqrt(dualresnorm), np.sqrt(normgraddm))
def prepare_initial_condition(DS): phi_cpp = """ class Expression_phi : public Expression { public: double depth, eps, width_factor; Expression_phi() : Expression(), depth(0.5), eps(0.125), width_factor(1.0) {} void eval(Array<double>& value, const Array<double>& x) const { double r = x[1] - depth; if (r <= -0.5*width_factor*eps) value[0] = 1.0; else if (r >= 0.5*width_factor*eps) value[0] = 0.0; else value[0] = 0.5*(1.0 - tanh(2.*r/eps)); } }; """ phi_prm = dict(eps=0.125, width_factor=3.0) # Load ic for phi_0 _phi = dolfin.Function(DS.subspace("phi", 0, deepcopy=True)) expr = dolfin.Expression(phi_cpp, element=_phi.ufl_element()) for key, val in six.iteritems(phi_prm): setattr(expr, key, val) _phi.interpolate(expr) pv0 = DS.primitive_vars_ptl(0) phi = pv0["phi"].split()[0] dolfin.assign(phi, _phi) # with uncached dofmaps # Copy interpolated initial condition also to CTL for i, w in enumerate(DS.solution_ptl(0)): DS.solution_ctl()[i].assign(w) return _phi
def data_to_S1(x, y, mesh, **values): "2D data clouds of vector valued functions => dolfin S1 functions" trid = dln.Triangulation(x, y) #mesh = nanopores.RectangleMesh([0, -Ry], [Rx, Ry], Nx, Ny) functions = [] for F in values.values(): Fi = [None] * 2 for i in (0, 1): intp = trid.nn_interpolator(F[:, i]) intp2 = lambda x: intp([x[0]], [x[1]]) Fi[i] = lambda_to_S1(intp2, mesh) V = dolfin.VectorFunctionSpace(mesh, "CG", 1) FF = dolfin.Function(V) dolfin.assign(FF, [Fi[0], Fi[1]]) functions.append(FF) if len(functions) == 1: return functions[0] else: return tuple(functions)
def _read_from_file(fun, directory, filename, suffix, components=None): if components is not None: filename = filename + "_component_" + "".join(components) function_name = "function_" + "".join(components) else: function_name = "function" fun_V_element = fun.function_space().ufl_element() if isinstance(fun_V_element, MixedElement) and not isinstance( fun_V_element, (TensorElement, VectorElement)): funs = fun.split(deepcopy=True) for (i, fun_i) in enumerate(funs): if components is not None: filename_i = filename + "_subcomponent_" + str(i) else: filename_i = filename + "_component_" + str(i) _read_from_file(fun_i, directory, filename_i, suffix, None) assign(fun.sub(i), fun_i) else: if fun_V_element.family() == "Real": SolutionFile = SolutionFileXML else: if has_hdf5() and has_hdf5_parallel(): SolutionFile = SolutionFileXDMF else: SolutionFile = SolutionFileXML if suffix is not None: if suffix == 0: # Remove from storage and re-create try: del _all_solution_files[(directory, filename)] except KeyError: pass _all_solution_files[(directory, filename)] = SolutionFile( directory, filename) file_ = _all_solution_files[(directory, filename)] file_.read(fun, function_name, suffix) else: file_ = SolutionFile(directory, filename) file_.read(fun, function_name, 0)
from dolfin import (Constant, DirichletBC, Function, FunctionSpace, Point, RectangleMesh, TestFunction, dx, grad, inner, interactive, near, plot, solve, assign, interpolate, Expression, dot) v = Constant((1.0, 0.0)) def left(x, on_boundary): return on_boundary and near(x[0], 0.0) mesh = RectangleMesh(Point(0.0, 0.0), Point(1.0, 1.0), 50, 50) dt = 0.001 S = FunctionSpace(mesh, 'CG', 1) T = Function(S) T0 = interpolate(Expression("1.0 / (10.0 * x[0] + 1.0)"), S) T_t = TestFunction(S) r = (T_t * ((T - T0) + dt * dot(v, grad(T)))) * dx bc1 = DirichletBC(S, 1.0, left) t = 0.0 while t <= 1.0: solve(r == 0, T, [bc1]) assign(T0, T) plot(T, mesh) t += dt
def run_with_params(Tb, mu_value, k_s, path): run_time_init = clock() mesh = BoxMesh(Point(0.0, 0.0, 0.0), Point(mesh_width, mesh_width, mesh_height), nx, ny, nz) pbc = PeriodicBoundary() WE = VectorElement('CG', mesh.ufl_cell(), 2) SE = FiniteElement('CG', mesh.ufl_cell(), 1) WSSS = FunctionSpace(mesh, MixedElement(WE, SE, SE, SE), constrained_domain=pbc) # W = FunctionSpace(mesh, WE, constrained_domain=pbc) # S = FunctionSpace(mesh, SE, constrained_domain=pbc) W = WSSS.sub(0).collapse() S = WSSS.sub(1).collapse() temperature_vals = [27.0 + 273, Tb + 273, 1300.0 + 273, 1305.0 + 273] temp_prof = TemperatureProfile(temperature_vals, element=S.ufl_element()) mu_a = mu_value # this was taken from the Blankenbach paper, can change Ep = b / temp_prof.delta mu_bot = exp(-Ep * (temp_prof.bottom * temp_prof.delta - 1573.0) + cc) * mu_a # TODO: verify exponentiation Ra = rho_0 * alpha * g * temp_prof.delta * h ** 3 / (kappa_0 * mu_a) w0 = rho_0 * alpha * g * temp_prof.delta * h ** 2 / mu_a tau = h / w0 p0 = mu_a * w0 / h log(mu_a, mu_bot, Ra, w0, p0) slip_vx = 1.6E-09 / w0 # Non-dimensional slip_velocity = Constant((slip_vx, 0.0, 0.0)) zero_slip = Constant((0.0, 0.0, 0.0)) time_step = 3.0E11 / tau * 2 dt = Constant(time_step) t_end = 3.0E15 / tau / 5.0 # Non-dimensional times u = Function(WSSS) # Instead of TrialFunctions, we use split(u) for our non-linear problem v, p, T, Tf = split(u) v_t, p_t, T_t, Tf_t = TestFunctions(WSSS) T0 = interpolate(temp_prof, S) mu_exp = Expression('exp(-Ep * (T_val * dTemp - 1573.0) + cc * x[2] / mesh_height)', Ep=Ep, dTemp=temp_prof.delta, cc=cc, mesh_height=mesh_height, T_val=T0, element=S.ufl_element()) Tf0 = interpolate(temp_prof, S) mu = Function(S) v0 = Function(W) v_theta = (1.0 - theta) * v0 + theta * v T_theta = (1.0 - theta) * T0 + theta * T Tf_theta = (1.0 - theta) * Tf0 + theta * Tf # TODO: Verify forms r_v = (inner(sym(grad(v_t)), 2.0 * mu * sym(grad(v))) - div(v_t) * p - T * v_t[2]) * dx r_p = p_t * div(v) * dx heat_transfer = Constant(k_s) * (Tf_theta - T_theta) * dt r_T = (T_t * ((T - T0) + dt * inner(v_theta, grad(T_theta))) # TODO: Inner vs dot + (dt / Ra) * inner(grad(T_t), grad(T_theta)) - T_t * heat_transfer) * dx v_melt = Function(W) z_hat = Constant((0.0, 0.0, 1.0)) # TODO: inner -> dot, take out Tf_t r_Tf = (Tf_t * ((Tf - Tf0) + dt * inner(v_melt, grad(Tf_theta))) + Tf_t * heat_transfer) * dx r = r_v + r_p + r_T + r_Tf bcv0 = DirichletBC(WSSS.sub(0), zero_slip, top) bcv1 = DirichletBC(WSSS.sub(0), slip_velocity, bottom) bcv2 = DirichletBC(WSSS.sub(0).sub(1), Constant(0.0), back) bcv3 = DirichletBC(WSSS.sub(0).sub(1), Constant(0.0), front) bcp0 = DirichletBC(WSSS.sub(1), Constant(0.0), bottom) bct0 = DirichletBC(WSSS.sub(2), Constant(temp_prof.surface), top) bct1 = DirichletBC(WSSS.sub(2), Constant(temp_prof.bottom), bottom) bctf1 = DirichletBC(WSSS.sub(3), Constant(temp_prof.bottom), bottom) bcs = [bcv0, bcv1, bcv2, bcv3, bcp0, bct0, bct1, bctf1] t = 0 count = 0 files = DefaultDictByKey(partial(create_xdmf, path)) while t < t_end: mu.interpolate(mu_exp) rhosolid = rho_0 * (1.0 - alpha * (T0 * temp_prof.delta - 1573.0)) deltarho = rhosolid - rho_melt # TODO: project (accuracy) vs interpolate assign(v_melt, project(v0 - darcy * (grad(p) * p0 / h - deltarho * z_hat * g) / w0, W)) # TODO: Written out one step later? # v_melt.assign(v0 - darcy * (grad(p) * p0 / h - deltarho * yvec * g) / w0) # TODO: use nP after to avoid projection? solve(r == 0, u, bcs) nV, nP, nT, nTf = u.split() # TODO: write with Tf, ... etc if count % output_every == 0: time_left(count, t_end / time_step, run_time_init) # TODO: timestep vs dt # TODO: Make sure all writes are to the same function for each time step files['T_fluid'].write(nTf, t) files['p'].write(nP, t) files['v_solid'].write(nV, t) files['T_solid'].write(nT, t) files['mu'].write(mu, t) files['v_melt'].write(v_melt, t) files['gradp'].write(project(grad(nP), W), t) files['rho'].write(project(rhosolid, S), t) files['Tf_grad'].write(project(grad(Tf), W), t) files['advect'].write(project(dt * dot(v_melt, grad(nTf))), t) files['ht'].write(project(heat_transfer, S), t) assign(T0, nT) assign(v0, nV) assign(Tf0, nTf) t += time_step count += 1 log('Case mu={}, Tb={}, k={} complete. Run time = {:.2f} minutes'.format(mu_a, Tb, k_s, (clock() - run_time_init) / 60.0))
def RunJob(Tb, mu_value, path): runtimeInit = clock() tfile = File(path + '/t6t.pvd') mufile = File(path + "/mu.pvd") ufile = File(path + '/velocity.pvd') gradpfile = File(path + '/gradp.pvd') pfile = File(path + '/pstar.pvd') parameters = open(path + '/parameters', 'w', 0) vmeltfile = File(path + '/vmelt.pvd') rhofile = File(path + '/rhosolid.pvd') for name in dir(): ev = str(eval(name)) if name[0] != '_' and ev[0] != '<': parameters.write(name + ' = ' + ev + '\n') temp_values = [27. + 273, Tb + 273, 1300. + 273, 1305. + 273] dTemp = temp_values[3] - temp_values[0] temp_values = [x / dTemp for x in temp_values] # non dimensionalising temp mu_a = mu_value # this was taken from the blankenbach paper, can change.. Ep = b / dTemp mu_bot = exp(-Ep * (temp_values[3] * dTemp - 1573) + cc) * mu_a Ra = rho_0 * alpha * g * dTemp * h**3 / (kappa_0 * mu_a) w0 = rho_0 * alpha * g * dTemp * h**2 / mu_a tau = h / w0 p0 = mu_a * w0 / h print(mu_a, mu_bot, Ra, w0, p0) vslipx = 1.6e-09 / w0 vslip = Constant((vslipx, 0.0)) # nondimensional noslip = Constant((0.0, 0.0)) dt = 3.E11 / tau tEnd = 3.E13 / tau # non-dimensionalising times class PeriodicBoundary(SubDomain): def inside(self, x, on_boundary): return left(x, on_boundary) def map(self, x, y): y[0] = x[0] - MeshWidth y[1] = x[1] pbc = PeriodicBoundary() class TempExp(Expression): def eval(self, value, x): if x[1] >= LAB(x): value[0] = temp_values[0] + (temp_values[1] - temp_values[0]) * (MeshHeight - x[1]) / (MeshHeight - LAB(x)) else: value[0] = temp_values[3] - (temp_values[3] - temp_values[2]) * (x[1]) / (LAB(x)) class FluidTemp(Expression): def eval(self, value, x): if value[0] < 1295: value[0] = 1295 mesh = RectangleMesh(Point(0.0, 0.0), Point(MeshWidth, MeshHeight), nx, ny) Svel = VectorFunctionSpace(mesh, 'CG', 2, constrained_domain=pbc) Spre = FunctionSpace(mesh, 'CG', 1, constrained_domain=pbc) Stemp = FunctionSpace(mesh, 'CG', 1, constrained_domain=pbc) Smu = FunctionSpace(mesh, 'CG', 1, constrained_domain=pbc) Sgradp = VectorFunctionSpace(mesh, 'CG', 2, constrained_domain=pbc) Srho = FunctionSpace(mesh, 'CG', 1, constrained_domain=pbc) S0 = MixedFunctionSpace([Svel, Spre, Stemp]) u = Function(S0) v, p, T = split(u) v_t, p_t, T_t = TestFunctions(S0) T0 = interpolate(TempExp(), Stemp) muExp = Expression('exp(-Ep * (T_val * dTemp - 1573) + cc * x[2] / meshHeight)', Smu.ufl_element(), Ep=Ep, dTemp=dTemp, cc=cc, meshHeight=MeshHeight, T_val=T0) mu = interpolate(muExp, Smu) rhosolid = Function(Srho) deltarho = Function(Srho) v0 = Function(Svel) vmelt = Function(Svel) v_theta = (1. - theta)*v0 + theta*v T_theta = (1. - theta)*T + theta*T0 r_v = (inner(sym(grad(v_t)), 2.*mu*sym(grad(v))) \ - div(v_t)*p \ - T*v_t[1] )*dx r_p = p_t*div(v)*dx r_T = (T_t*((T - T0) \ + dt*inner(v_theta, grad(T_theta))) \ + (dt/Ra)*inner(grad(T_t), grad(T_theta)) )*dx # + k_s*(Tf-T_theta)*dt Tf = T0.interpolate(FluidTemp()) # Tf = T0.interpolate(Expression('value[0] >= 1295.0 ? value[0] : 1295.0')) # Tf.interpolate(Expression('value[0] >= 1295 ? value[0] : 1295')) # project(Expression('value[0] >= 1295 ? value[0] : 1295'), Tf) # Alex, a question for you: # can you see if there is a way to set Tf = T in regions where T >=1295 celsius # # 1295 celsius is my arbitrary choice for the LAB isotherm. In regions # where T < 1295 C, set Tf to be some constant for now, such as 1295 C. # Once we do this, then we can add in a term like that last line above where # it will only be non-zero when the solid temperature, T, is cooler than 1295 # can you do this? After this is done, we will then worry about a calculation # where we solve for Tf as a function of time in the regions cooler than 1295 C # Makes sense? If not, we can skype soon -- email me with questions # 3/19/16 r = r_v + r_p + r_T bcv0 = DirichletBC(S0.sub(0), noslip, top) bcv1 = DirichletBC(S0.sub(0), vslip, bottom) bcp0 = DirichletBC(S0.sub(1), Constant(0.0), bottom) bct0 = DirichletBC(S0.sub(2), Constant(temp_values[0]), top) bct1 = DirichletBC(S0.sub(2), Constant(temp_values[3]), bottom) bcs = [bcv0, bcv1, bcp0, bct0, bct1] t = 0 count = 0 while (t < tEnd): solve(r == 0, u, bcs) t += dt nV, nP, nT = u.split() gp = grad(nP) rhosolid = rho_0 * (1 - alpha * (nT * dTemp - 1573)) deltarho = rhosolid - rhomelt yvec = Constant((0.0, 1.0)) vmelt = nV * w0 - darcy * (gp * p0 / h - deltarho * yvec * g) if (count % 100 == 0): pfile << nP ufile << nV tfile << nT mufile << mu gradpfile << project(grad(nP), Sgradp) mufile << project(mu * mu_a, Smu) rhofile << project(rhosolid, Srho) vmeltfile << project(vmelt, Svel) count += 1 assign(T0, nT) assign(v0, nV) mu.interpolate(muExp) print('Case mu=%g, Tb=%g complete.' % (mu_a, Tb), ' Run time =', clock() - runtimeInit, 's')
def solve( mesh, W_element, P_element, Q_element, u0, p0, theta0, kappa, rho, mu, cp, g, extra_force, heat_source, u_bcs, p_bcs, theta_dirichlet_bcs, theta_neumann_bcs, dx_submesh, ds_submesh ): # First do a fixed_point iteration. This is usually quite robust and leads # to a point from where Newton can converge reliably. u0, p0, theta0 = solve_fixed_point( mesh, W_element, P_element, Q_element, theta0, kappa, rho, mu, cp, g, extra_force, heat_source, u_bcs, p_bcs, theta_dirichlet_bcs, theta_neumann_bcs, my_dx=dx_submesh, my_ds=ds_submesh, max_iter=100, tol=1.0e-8 ) WPQ = FunctionSpace( mesh, MixedElement([W_element, P_element, Q_element]) ) uptheta0 = Function(WPQ) # Initial guess assign(uptheta0.sub(0), u0) assign(uptheta0.sub(1), p0) assign(uptheta0.sub(2), theta0) rho_const = rho(_average(theta0)) stokes_heat_problem = StokesHeat( WPQ, kappa, rho, rho_const, mu, cp, g, extra_force, heat_source, u_bcs, p_bcs, theta_dirichlet_bcs=theta_dirichlet_bcs, theta_neumann_bcs=theta_neumann_bcs, my_dx=dx_submesh, my_ds=ds_submesh ) # solver = FixedPointSolver() from dolfin import PETScSNESSolver solver = PETScSNESSolver() # http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/SNES/SNESType.html solver.parameters['method'] = 'newtonls' # The Jacobian system for Stokes (+heat) are hard to solve. # Use LU for now. solver.parameters['linear_solver'] = 'lu' solver.parameters['maximum_iterations'] = 100 # TODO tighten tolerance. might not always work though... solver.parameters['absolute_tolerance'] = 1.0e-3 solver.parameters['relative_tolerance'] = 0.0 solver.parameters['report'] = True solver.solve(stokes_heat_problem, uptheta0.vector()) # u0, p0, theta0 = split(uptheta0) # Create a *deep* copy of u0, p0, theta0 to be able to deal with them # as actually separate entities vectors. u0, p0, theta0 = uptheta0.split(deepcopy=True) return u0, p0, theta0