def MollifiedBiLaplacianPrior(Vh, gamma, delta, locations, m_true, Theta = None, pen = 1e1, order=2, rel_tol=1e-12, max_iter=1000): """ This function construct an instance of :code"`SqrtPrecisionPDE_Prior` with covariance matrix :math:`C = \\left( [\\delta + \\mbox{pen} \\sum_i m(x - x_i) ] I + \\gamma \\mbox{div } \\Theta \\nabla\\right) ^ {-2}`, where - :math:`\\Theta` is a SPD tensor that models anisotropy in the covariance kernel. - :math:`x_i (i=1,...,n)` are points were we assume to know exactly the value of the parameter (i.e., :math:`m(x_i) = m_{\\mbox{true}}( x_i) \\mbox{ for } i=1,...,n).` - :math:`m` is the mollifier function: :math:`m(x - x_i) = \\exp\\left( - \\left[\\frac{\\gamma}{\\delta}\\| x - x_i \\|_{\\Theta^{-1}}\\right]^{\\mbox{order}} \\right).` - :code:`pen` is a penalization parameter. The magnitude of :math:`\\delta \\gamma` governs the variance of the samples, while the ratio :math:`\\frac{\\gamma}{\\delta}` governs the correlation length. The prior mean is computed by solving .. math:: \\left( [\\delta + \\sum_i m(x - x_i) ] I + \\gamma \\mbox{div } \\Theta \\nabla \\right) m = \\sum_i m(x - x_i) m_{\\mbox{true}}. Input: - :code:`Vh`: the finite element space for the parameter - :code:`gamma` and :code:`delta`: the coefficients in the PDE - :code:`locations`: the points :math:`x_i` at which we assume to know the true value of the parameter - :code:`m_true`: the true model - :code:`Theta`: the SPD tensor for anisotropic diffusion of the PDE - :code:`pen`: a penalization parameter for the mollifier """ assert delta != 0. or pen != 0, "Intrinsic Gaussian Prior are not supported" mfun = dl.CompiledExpression(ExpressionModule.Mollifier(), degree = Vh.ufl_element().degree()+2) mfun.set(Theta._cpp_object, gamma/delta, order) for ii in range(locations.shape[0]): mfun.addLocation(locations[ii,0], locations[ii,1]) def sqrt_precision_varf_handler(trial, test): if Theta == None: varfL = dl.inner(dl.nabla_grad(trial), dl.nabla_grad(test))*dl.dx else: varfL = dl.inner(Theta*dl.grad(trial), dl.grad(test))*dl.dx varfM = dl.inner(trial,test)*dl.dx varfmo = mfun*dl.inner(trial,test)*dl.dx return dl.Constant(gamma)*varfL+dl.Constant(delta)*varfM + dl.Constant(pen)*varfmo prior = SqrtPrecisionPDE_Prior(Vh, sqrt_precision_varf_handler, None, rel_tol, max_iter) prior.mean = dl.Vector(prior.R.mpi_comm()) prior.init_vector(prior.mean, 0) test = dl.TestFunction(Vh) m_true_fun = vector2Function(m_true, Vh) rhs = dl.assemble(dl.Constant(pen)*mfun*dl.inner(m_true_fun,test)*dl.dx) prior.Asolver.solve(prior.mean, rhs) return prior
def from_parameters(cls, params=None): params = params or {} parameters = cls.default_parameters() parameters.update(params) msh_name = Path("test.msh") create_benchmark_ellipsoid_mesh_gmsh( msh_name, r_short_endo=parameters["r_short_endo"], r_short_epi=parameters["r_short_epi"], r_long_endo=parameters["r_long_endo"], r_long_epi=parameters["r_long_epi"], quota_base=parameters["quota_base"], psize=parameters["mesh_generation"]["psize"], ndiv=parameters["mesh_generation"]["ndiv"], ) geo: HeartGeometry = gmsh2dolfin(msh_name) msh_name.unlink() obj = cls( mesh=geo.mesh, marker_functions=geo.marker_functions, markers=geo.markers, ) obj._parameters = parameters # microstructure mspace = obj._parameters["microstructure"]["function_space"] dolfin.info("Creating microstructure") # coordinate mapping cart2coords_code = obj._compile_cart2coords_code() cart2coords = dolfin.compile_cpp_code(cart2coords_code) cart2coords_expr = dolfin.CompiledExpression( cart2coords.SimpleEllipsoidCart2Coords(), degree=1, ) # local coordinate base localbase_code = obj._compile_localbase_code() localbase = dolfin.compile_cpp_code(localbase_code) localbase_expr = dolfin.CompiledExpression( localbase.SimpleEllipsoidLocalCoords( cart2coords_expr.cpp_object()), degree=1, ) # function space family, degree = mspace.split("_") degree = int(degree) V = dolfin.TensorFunctionSpace(obj.mesh, family, degree, shape=(3, 3)) # microstructure expression alpha_endo = obj._parameters["microstructure"]["alpha_endo"] alpha_epi = obj._parameters["microstructure"]["alpha_epi"] microstructure_code = obj._compile_microstructure_code() microstructure = dolfin.compile_cpp_code(microstructure_code) microstructure_expr = dolfin.CompiledExpression( microstructure.EllipsoidMicrostructure( cart2coords_expr.cpp_object(), localbase_expr.cpp_object(), alpha_epi, alpha_endo, ), degree=1, ) # interpolation W = dolfin.VectorFunctionSpace(obj.mesh, family, degree) microinterp = interpolate(microstructure_expr, V) s0 = project(microinterp[0, :], W) n0 = project(microinterp[1, :], W) f0 = project(microinterp[2, :], W) obj.microstructure = Microstructure(f0=f0, s0=s0, n0=n0) obj.update_xshift() return obj
} values[0] = tau; }; }; PYBIND11_MODULE(SIGNATURE, m){ py::class_<SUPG, std::shared_ptr<SUPG>, dolfin::Expression> (m, "SUPG").def(py::init<std::shared_ptr<dolfin::Function>>()) .def("eval", &SUPG::eval) .def_readwrite("D", &SUPG::D); } ''' tau_code_compiled = df.compile_cpp_code(tau_code) tau_c = df.CompiledExpression(tau_code_compiled.SUPG(u_.cpp_object()), D=.1, element=r_.ufl_element()) # tau_c.value_rank() values = np.zeros(2) x = np.array([0.5, 0.5]) tau_c.eval(values, x) print(df.assemble(tau_c*df.dx(domain=mesh))) tau = df.interpolate(tau_c, Q) df.plot(tau) plt.show()
double R = sqrt(pow(x[0],2)+pow(x[1],2)); double phi = atan2(x[1],x[0]); double d_0 = C_9 + C_2*cyl_bessel_k(0, R*lambda_2/tau) + C_8*cyl_bessel_i(0, R*lambda_2/tau); double d = - (10*A_1 * pow(R,2))/(27*tau) + (4*C_4*R)/(tau) - (2*C_5*tau)/R + C_14*cyl_bessel_k(1, R*lambda_2/tau) + C_15* cyl_bessel_i(1, R*lambda_2/tau); values[0] = d_0 + cos(phi) * d; } // The data stored in mesh functions double R; }; PYBIND11_MODULE(SIGNATURE, m) { py::class_<Pressure, std::shared_ptr<Pressure>, dolfin::Expression> (m, "Pressure") .def(py::init<>()); } """ c = df.CompiledExpression(df.compile_cpp_code(p_code).Pressure(), degree=1) print(2 * c([1, 1])) p_i = df.interpolate(c, V) df.plot(p_i) file = df.File("out.pvd") file.write(p_i)
targets[:, 0] = targets_x targets[:, 1] = targets_y #targets everywhere #targets = np.random.uniform(0.1,0.9, [ntargets, ndim] ) if rank == 0: print("Number of observation points: {0}".format(ntargets)) misfit = PointwiseStateObservation(Vh[STATE], targets) gamma = .1 delta = .5 theta0 = 2. theta1 = .5 alpha = math.pi / 4 anis_diff = dl.CompiledExpression(ExpressionModule.AnisTensor2D(), degree=1) anis_diff.set(theta0, theta1, alpha) prior = BiLaplacianPrior(Vh[PARAMETER], gamma, delta, anis_diff, robin_bc=True) mtrue = true_model(prior) if rank == 0: print( "Prior regularization: (delta_x - gamma*Laplacian)^order: delta={0}, gamma={1}, order={2}" .format(delta, gamma, 2))
class RadialAngle : public dolfin::Expression { public: // Create expression with 3 components RadialAngle() : dolfin::Expression() {} // Function for evaluating expression on each cell void eval(Eigen::Ref<Eigen::VectorXd> values, Eigen::Ref<const Eigen::VectorXd> x) const override { values[0] = atan2(x[1],x[0]); } // The data stored in mesh functions double R; }; PYBIND11_MODULE(SIGNATURE, m) { py::class_<RadialAngle, std::shared_ptr<RadialAngle>, dolfin::Expression> (m, "RadialAngle") .def(py::init<>()) .def_readwrite("R", &RadialAngle::R); } """ c = df.CompiledExpression(df.compile_cpp_code(conductivity_code).RadialAngle(), degree=1, R=1.23) print(2*c(1))
def vocal_tract_solver_backward(f_data, g_data, c_sound, length, Nx, basis_degree, T, num_tsteps, iteration): """ TODO """ # f expression f_cppcode = """ #include <iostream> #include <cmath> #include <pybind11/pybind11.h> #include <pybind11/eigen.h> #include <dolfin/function/Expression.h> class FExpress: public dolfin::Expression { public: int t_idx; // time index double DX; // length of uniformly spaced cell Eigen::MatrixXd array; // external data // Constructor FExpress() : dolfin::Expression(1), t_idx(0) { } // Overload: evaluate at given point in given cell void eval(Eigen::Ref<Eigen::VectorXd> values, Eigen::Ref<const Eigen::VectorXd> x) const { // values: values at the point // x: coordinates of the point int x_idx = std::round(x(0) / DX); // spatial index values(0) = array(t_idx, x_idx); } }; // Binding FExpress PYBIND11_MODULE(SIGNATURE, m) { pybind11::class_<FExpress, std::shared_ptr<FExpress>, dolfin::Expression> (m, "FExpress") .def(pybind11::init<>()) .def_readwrite("t_idx", &FExpress::t_idx) .def_readwrite("DX", &FExpress::DX) .def_readwrite("array", &FExpress::array) ; } """ f_expr = dolfin.compile_cpp_code(f_cppcode).FExpress() f = dolfin.CompiledExpression(f_expr, degree=basis_degree + 2) f.array = f_data f.t_idx = 0 f.DX = 1.0 / (Nx * basis_degree) # Initial expression u_I = F.Constant(0.0) # Neumann boundary expression g_cppcode = """ #include <pybind11/pybind11.h> #include <pybind11/eigen.h> #include <dolfin/function/Expression.h> class GExpress: public dolfin::Expression { public: int idx; // time-dependent index Eigen::VectorXd array; // external data // Constructor GExpress() : dolfin::Expression(1), idx(0) { } // Overload: evaluate at given point in given cell void eval(Eigen::Ref<Eigen::VectorXd> values, Eigen::Ref<const Eigen::VectorXd> x) const { // values: values at the point // x: coordinates of the point values(0) = array(idx); } }; // Binding GExpress PYBIND11_MODULE(SIGNATURE, m) { pybind11::class_<GExpress, std::shared_ptr<GExpress>, dolfin::Expression> (m, "GExpress") .def(pybind11::init<>()) .def_readwrite("idx", &GExpress::idx) .def_readwrite("array", &GExpress::array) ; } """ g_expr = dolfin.compile_cpp_code(g_cppcode).GExpress() g = dolfin.CompiledExpression(g_expr, degree=basis_degree + 2) g.array = g_data subboundary_L = F.CompiledSubDomain( "on_boundary && near(x[0], length, tol)", length=length, tol=1e-14) # boundary @ L # Solve boundary_conditions = {1: {"Neumann": g}, "subboundary": subboundary_L} divisions = (Nx, ) dt = T / num_tsteps # time step size U_k = pde_solver_backward( f, boundary_conditions, u_I, c_sound, divisions, T, dt, num_tsteps, initial_method="project", degree=basis_degree, iteration=iteration, ) return U_k
def vocal_tract_solver(f_data, u0, uL, c_sound, length, Nx, basis_degree, T, num_tsteps, iteration): # f expression f_cppcode = """ #include <iostream> #include <cmath> #include <pybind11/pybind11.h> #include <pybind11/eigen.h> #include <dolfin/function/Expression.h> class FExpress: public dolfin::Expression { public: int t_idx; // time index double DX; // length of uniformly spaced cell Eigen::MatrixXd array; // external data // Constructor FExpress() : dolfin::Expression(1), t_idx(0) { } // Overload: evaluate at given point in given cell void eval(Eigen::Ref<Eigen::VectorXd> values, Eigen::Ref<const Eigen::VectorXd> x) const { // values: values at the point // x: coordinates of the point int x_idx = std::round(x(0) / DX); // spatial index values(0) = array(t_idx, x_idx); } }; // Binding FExpress PYBIND11_MODULE(SIGNATURE, m) { pybind11::class_<FExpress, std::shared_ptr<FExpress>, dolfin::Expression> (m, "FExpress") .def(pybind11::init<>()) .def_readwrite("t_idx", &FExpress::t_idx) .def_readwrite("DX", &FExpress::DX) .def_readwrite("array", &FExpress::array) ; } """ f_expr = dolfin.compile_cpp_code(f_cppcode).FExpress() f = dolfin.CompiledExpression(f_expr, degree=basis_degree + 2) f.array = f_data f.t_idx = 0 f.DX = length / (Nx * basis_degree) # Initial expression u_I = F.Constant(0.0) # Dirichlet boundary expression g_cppcode = """ #include <pybind11/pybind11.h> #include <pybind11/eigen.h> #include <dolfin/function/Expression.h> class GExpress: public dolfin::Expression { public: int idx; // time-dependent index Eigen::VectorXd array; // external data // Constructor GExpress() : dolfin::Expression(1), idx(0) { } // Overload: evaluate at given point in given cell void eval(Eigen::Ref<Eigen::VectorXd> values, Eigen::Ref<const Eigen::VectorXd> x) const { // values: values at the point // x: coordinates of the point values(0) = array(idx); } }; // Binding GExpress PYBIND11_MODULE(SIGNATURE, m) { pybind11::class_<GExpress, std::shared_ptr<GExpress>, dolfin::Expression> (m, "GExpress") .def(pybind11::init<>()) .def_readwrite("idx", &GExpress::idx) .def_readwrite("array", &GExpress::array) ; } """ g_expr = dolfin.compile_cpp_code(g_cppcode).GExpress() u_D_0 = dolfin.CompiledExpression(g_expr, degree=basis_degree + 2) u_D_0.array = u0 u_D_0.idx = 0 u_D_L = dolfin.CompiledExpression(g_expr, degree=basis_degree + 2) u_D_L.array = uL u_D_L.idx = 0 # u_D = [u_D_0, u_D_L] u_D = [u_D_0] def boundary_0(x, on_boundary): """ Test if x is on boundary. """ tol = 1e-14 return on_boundary and (F.near(x[0], 0.0, tol)) def boundary_L(x, on_boundary): """ Test if x is on boundary. """ tol = 1e-14 return on_boundary and (F.near(x[0], length, tol)) f_boundary = [boundary_0, boundary_L] f_boundary = [boundary_0] # Solve dt = T / num_tsteps # time step size uL_k, U_k = pde_solver( f, u_D, u_I, c_sound, f_boundary, (Nx, ), T, dt, num_tsteps, initial_method="project", degree=basis_degree, iteration=iteration, ) return uL_k, U_k
# (ns1.compute_vertex_values()+ns2.compute_vertex_values())) err_l2 = df.errornorm(es,ns1+ns2,"L2")#fenics inbuilt norm calculator err_linf = np.max(np.abs(es.compute_vertex_values()- (ns1.compute_vertex_values()+ns2.compute_vertex_values()))) max_l2= np.linalg.norm(es.compute_vertex_values()) max_linf = np.max(np.abs(es.compute_vertex_values())) or 1 normalised_err_l2= err_l2/max_linf normalised_err_linf = err_linf/max_linf return normalised_err_l2, normalised_err_linf if my_input_cls['moment_order']== 3: with open("01_coeffs.cpp", "r") as file: exact_solution_cpp_code = file.read() load_value = df.compile_cpp_code(exact_solution_cpp_code) #Temperature t_e = df.CompiledExpression(load_value.Temperature(),degree=2) t_l2,t_linf = ErrorCalculation(t_e,sol[0]) #Heat flux sx_e = df.CompiledExpression(load_value.Heatfluxx(),degree=2) sx_l2,sx_linf = ErrorCalculation(sx_e,sol[1]) sy_e = df.CompiledExpression(load_value.Heatfluxy(),degree=2) sy_l2,sy_linf = ErrorCalculation(sy_e,sol[2]) errors =[ t_l2, t_linf, sx_l2, sx_linf, sy_l2,sy_linf , ] print(errors) if my_input_cls['moment_order']== 'nono-6': with open("01_coeffs.cpp", "r") as file: exact_solution_cpp_code = file.read()
def theta_sol_3d(): def transcendental_eq_3d(savefig): f = lambda x: prm.rho * prm.L_m * x**3 - prm.q_0 / ( 16 * np.pi ) * np.exp(-(x**2) / prm.kappa_l) + prm.k_s * np.sqrt( prm.kappa_s ) * (prm.theta_m - prm.theta_i) * np.exp(-(x**2) / prm.kappa_s) / ( (-2) * gamma(0.5) * gammaincc(0.5, x**2 / prm.kappa_s) + 2 * np .sqrt(prm.kappa_s) / x * np.exp(-x**2 / prm.kappa_s)) lambda_ = fsolve(f, 0.00001, xtol=1e-10) if savefig: ax, _ = graph_transcendental_eq(lambda_, f, 3) ax.axhline(y=0, lw=1, color='k') return lambda_[0] lambda_ = transcendental_eq_3d(ploteq) # Analytic solution cpp code (pybind11): code_analytic = ''' #include <pybind11/pybind11.h> #include <pybind11/eigen.h> namespace py = pybind11; #include <dolfin/function/Expression.h> #include <dolfin/mesh/MeshFunction.h> #include <math.h> #include <boost/math/special_functions/gamma.hpp> using boost::math::tgamma; class StefanAnalytic3d : public dolfin::Expression { public: double t, theta_i, theta_m, kappa_l, kappa_s, lambda_, c_3d; // Analytical solution, returns one value StefanAnalytic3d() : dolfin::Expression() {}; // Function for evaluating expression void eval(Eigen::Ref<Eigen::VectorXd> values, Eigen::Ref<const Eigen::VectorXd> x) const override { double f_l = (x[0]*x[0]+x[1]*x[1]+x[2]*x[2])/(4*kappa_l*t) ; double f_s = (x[0]*x[0]+x[1]*x[1]+x[2]*x[2])/(4*kappa_s*t) ; if ( sqrt(x[0]*x[0]+x[1]*x[1]+x[2]*x[2]) <= 2*lambda_*sqrt(t) ) { values[0] = theta_m + c_3d*((-2*tgamma(0.5,f_l) + 2*sqrt(1/f_l)*exp(-f_l)) - (-2*tgamma(0.5,lambda_*lambda_/kappa_l) + 2*sqrt(kappa_l)/lambda_*exp(-lambda_*lambda_/kappa_l))); } else { values[0] = theta_i - (theta_i - theta_m)/(-2*tgamma(0.5,lambda_*lambda_/kappa_s) + 2*sqrt(kappa_s)/lambda_*exp(-lambda_*lambda_/kappa_s))*(-2*tgamma(0.5,f_s) + 2*sqrt(1/f_s)*exp(-f_s)); } } }; PYBIND11_MODULE(SIGNATURE, m) { py::class_<StefanAnalytic3d, std::shared_ptr<StefanAnalytic3d>, dolfin::Expression> (m, "StefanAnalytic3d") .def(py::init<>()) .def_readwrite("kappa_l", &StefanAnalytic3d::kappa_l) .def_readwrite("kappa_s", &StefanAnalytic3d::kappa_s) .def_readwrite("lambda_", &StefanAnalytic3d::lambda_) .def_readwrite("theta_m", &StefanAnalytic3d::theta_m) .def_readwrite("c_3d", &StefanAnalytic3d::c_3d) .def_readwrite("theta_i", &StefanAnalytic3d::theta_i) .def_readwrite("t", &StefanAnalytic3d::t); } ''' # Compile cpp code for dolfin: theta_analytic = dolfin.CompiledExpression( dolfin.compile_cpp_code(code_analytic).StefanAnalytic3d(), kappa_l=prm.kappa_l, kappa_s=prm.kappa_s, theta_m=prm.theta_m, c_3d=prm.q_0 / (16 * np.pi * np.sqrt(prm.kappa_l) * prm.k_l), theta_i=prm.theta_i, lambda_=lambda_, t=0.1, degree=3) # 3d heat flux cpp code: code_flux = '-k*c_3d*exp(-r*r/(4*kappa*t))*sqrt(4*kappa*t)/(r*r)' # Heat influx: q_in = dolfin.Expression(code_flux, t=0.1, k=prm.k_l, c_3d=-prm.q_0 / (8 * np.pi * prm.k_l * np.sqrt(prm.kappa_l)), r=prm.R1, kappa=prm.kappa_l, degree=0) q_in_k = dolfin.Expression( code_flux, t=0.1, k=prm.k_l, c_3d=-prm.q_0 / (8 * np.pi * prm.k_l * np.sqrt(prm.kappa_l)), r=prm.R1, kappa=prm.kappa_l, degree=0) # Heat outflux: q_out = dolfin.Expression( code_flux, t=0.1, k=prm.k_s, c_3d=-(prm.theta_i - prm.theta_m) / ((-1) * gamma(0.5) * gammaincc(0.5, lambda_**2 / prm.kappa_s) + np.sqrt(prm.kappa_s) / lambda_ * np.exp(-lambda_**2 / prm.kappa_s)), r=prm.R2, kappa=prm.kappa_s, degree=0) q_out_k = dolfin.Expression( code_flux, t=0.1, k=prm.k_s, c_3d=-(prm.theta_i - prm.theta_m) / ((-1) * gamma(0.5) * gammaincc(0.5, lambda_**2 / prm.kappa_s) + np.sqrt(prm.kappa_s) / lambda_ * np.exp(-lambda_**2 / prm.kappa_s)), r=prm.R2, kappa=prm.kappa_s, degree=0) return lambda_, theta_analytic, q_in, q_in_k, q_out, q_out_k