1*3eb59678SJeremy L Thompson // Copyright (c) 2017-2025, Lawrence Livermore National Security, LLC and other CEED contributors. 2*3eb59678SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3*3eb59678SJeremy L Thompson // 4*3eb59678SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause 5*3eb59678SJeremy L Thompson // 6*3eb59678SJeremy L Thompson // This file is part of CEED: http://github.com/ceed 7*3eb59678SJeremy L Thompson // 8*3eb59678SJeremy L Thompson // libCEED Example 3 9*3eb59678SJeremy L Thompson // 10*3eb59678SJeremy L Thompson // This example illustrates a simple usage of libCEED to compute the volume of a 11*3eb59678SJeremy L Thompson // 3D body using matrix-free application of a mass operator. Arbitrary mesh and 12*3eb59678SJeremy L Thompson // solution orders in 1D, 2D and 3D are supported from the same code. This 13*3eb59678SJeremy L Thompson // calculation is executed in triplicate with a 3 component vector system. 14*3eb59678SJeremy L Thompson // 15*3eb59678SJeremy L Thompson // The example has no dependencies, and is designed to be self-contained. For 16*3eb59678SJeremy L Thompson // additional examples that use external discretization libraries (MFEM, PETSc, 17*3eb59678SJeremy L Thompson // etc.) see the subdirectories in libceed/examples. 18*3eb59678SJeremy L Thompson // 19*3eb59678SJeremy L Thompson // All libCEED objects use a Ceed device object constructed based on a command 20*3eb59678SJeremy L Thompson // line argument (-ceed). 21*3eb59678SJeremy L Thompson 22*3eb59678SJeremy L Thompson use clap::Parser; 23*3eb59678SJeremy L Thompson use libceed::{ 24*3eb59678SJeremy L Thompson BasisOpt, Ceed, ElemRestrictionOpt, QFunctionInputs, QFunctionOpt, QFunctionOutputs, VectorOpt, 25*3eb59678SJeremy L Thompson }; 26*3eb59678SJeremy L Thompson mod opt; 27*3eb59678SJeremy L Thompson mod transform; 28*3eb59678SJeremy L Thompson 29*3eb59678SJeremy L Thompson // ---------------------------------------------------------------------------- 30*3eb59678SJeremy L Thompson // Example 3 31*3eb59678SJeremy L Thompson // ---------------------------------------------------------------------------- 32*3eb59678SJeremy L Thompson fn main() -> libceed::Result<()> { 33*3eb59678SJeremy L Thompson let options = opt::Opt::parse(); 34*3eb59678SJeremy L Thompson example_1_vector(options) 35*3eb59678SJeremy L Thompson } 36*3eb59678SJeremy L Thompson 37*3eb59678SJeremy L Thompson #[allow(clippy::erasing_op)] 38*3eb59678SJeremy L Thompson #[allow(clippy::identity_op)] 39*3eb59678SJeremy L Thompson fn example_1_vector(options: opt::Opt) -> libceed::Result<()> { 40*3eb59678SJeremy L Thompson // Process command line arguments 41*3eb59678SJeremy L Thompson let opt::Opt { 42*3eb59678SJeremy L Thompson ceed_spec, 43*3eb59678SJeremy L Thompson dim, 44*3eb59678SJeremy L Thompson mesh_degree, 45*3eb59678SJeremy L Thompson solution_degree, 46*3eb59678SJeremy L Thompson num_qpts, 47*3eb59678SJeremy L Thompson problem_size_requested, 48*3eb59678SJeremy L Thompson test, 49*3eb59678SJeremy L Thompson quiet, 50*3eb59678SJeremy L Thompson gallery, 51*3eb59678SJeremy L Thompson } = options; 52*3eb59678SJeremy L Thompson assert!((0..=3).contains(&dim)); 53*3eb59678SJeremy L Thompson assert!(mesh_degree >= 1); 54*3eb59678SJeremy L Thompson assert!(solution_degree >= 1); 55*3eb59678SJeremy L Thompson assert!(num_qpts >= 1); 56*3eb59678SJeremy L Thompson let ncomp_x = dim; 57*3eb59678SJeremy L Thompson let problem_size: i64 = if problem_size_requested < 0 { 58*3eb59678SJeremy L Thompson if test { 59*3eb59678SJeremy L Thompson 8 * 16 60*3eb59678SJeremy L Thompson } else { 61*3eb59678SJeremy L Thompson 256 * 1024 62*3eb59678SJeremy L Thompson } 63*3eb59678SJeremy L Thompson } else { 64*3eb59678SJeremy L Thompson problem_size_requested 65*3eb59678SJeremy L Thompson }; 66*3eb59678SJeremy L Thompson let ncomp_u = 3; 67*3eb59678SJeremy L Thompson 68*3eb59678SJeremy L Thompson // Summary output 69*3eb59678SJeremy L Thompson if !quiet { 70*3eb59678SJeremy L Thompson println!("Selected options: [command line option] : <current value>"); 71*3eb59678SJeremy L Thompson println!(" Ceed specification [-c] : {}", ceed_spec); 72*3eb59678SJeremy L Thompson println!(" Mesh dimension [-d] : {}", dim); 73*3eb59678SJeremy L Thompson println!(" Mesh degree [-m] : {}", mesh_degree); 74*3eb59678SJeremy L Thompson println!(" Solution degree [-p] : {}", solution_degree); 75*3eb59678SJeremy L Thompson println!(" Num. 1D quadr. pts [-q] : {}", num_qpts); 76*3eb59678SJeremy L Thompson println!(" Approx. # unknowns [-s] : {}", problem_size); 77*3eb59678SJeremy L Thompson println!( 78*3eb59678SJeremy L Thompson " QFunction source [-g] : {}", 79*3eb59678SJeremy L Thompson if gallery { "gallery" } else { "user closure" } 80*3eb59678SJeremy L Thompson ); 81*3eb59678SJeremy L Thompson } 82*3eb59678SJeremy L Thompson 83*3eb59678SJeremy L Thompson // Initalize ceed context 84*3eb59678SJeremy L Thompson let ceed = Ceed::init(&ceed_spec); 85*3eb59678SJeremy L Thompson 86*3eb59678SJeremy L Thompson // Mesh and solution bases 87*3eb59678SJeremy L Thompson let basis_mesh = ceed.basis_tensor_H1_Lagrange( 88*3eb59678SJeremy L Thompson dim, 89*3eb59678SJeremy L Thompson ncomp_x, 90*3eb59678SJeremy L Thompson mesh_degree + 1, 91*3eb59678SJeremy L Thompson num_qpts, 92*3eb59678SJeremy L Thompson libceed::QuadMode::Gauss, 93*3eb59678SJeremy L Thompson )?; 94*3eb59678SJeremy L Thompson let basis_solution = ceed.basis_tensor_H1_Lagrange( 95*3eb59678SJeremy L Thompson dim, 96*3eb59678SJeremy L Thompson ncomp_u, 97*3eb59678SJeremy L Thompson solution_degree + 1, 98*3eb59678SJeremy L Thompson num_qpts, 99*3eb59678SJeremy L Thompson libceed::QuadMode::Gauss, 100*3eb59678SJeremy L Thompson )?; 101*3eb59678SJeremy L Thompson 102*3eb59678SJeremy L Thompson // Determine mesh size from approximate problem size 103*3eb59678SJeremy L Thompson let num_xyz = mesh::cartesian_mesh_size(dim, solution_degree, problem_size); 104*3eb59678SJeremy L Thompson if !quiet { 105*3eb59678SJeremy L Thompson print!("\nMesh size : nx = {}", num_xyz[0]); 106*3eb59678SJeremy L Thompson if dim > 1 { 107*3eb59678SJeremy L Thompson print!(", ny = {}", num_xyz[1]); 108*3eb59678SJeremy L Thompson } 109*3eb59678SJeremy L Thompson if dim > 2 { 110*3eb59678SJeremy L Thompson print!(", nz = {}", num_xyz[2]); 111*3eb59678SJeremy L Thompson } 112*3eb59678SJeremy L Thompson println!(); 113*3eb59678SJeremy L Thompson } 114*3eb59678SJeremy L Thompson 115*3eb59678SJeremy L Thompson // Build ElemRestriction objects describing the mesh and solution discrete 116*3eb59678SJeremy L Thompson // representations 117*3eb59678SJeremy L Thompson let (rstr_mesh, _) = 118*3eb59678SJeremy L Thompson mesh::build_cartesian_restriction(&ceed, dim, num_xyz, mesh_degree, ncomp_x, num_qpts)?; 119*3eb59678SJeremy L Thompson let (_, rstr_qdata) = 120*3eb59678SJeremy L Thompson mesh::build_cartesian_restriction(&ceed, dim, num_xyz, solution_degree, 1, num_qpts)?; 121*3eb59678SJeremy L Thompson let (rstr_solution, _) = 122*3eb59678SJeremy L Thompson mesh::build_cartesian_restriction(&ceed, dim, num_xyz, solution_degree, ncomp_u, num_qpts)?; 123*3eb59678SJeremy L Thompson let mesh_size = rstr_mesh.lvector_size(); 124*3eb59678SJeremy L Thompson let solution_size = rstr_solution.lvector_size(); 125*3eb59678SJeremy L Thompson if !quiet { 126*3eb59678SJeremy L Thompson println!("Number of mesh nodes : {}", mesh_size / dim); 127*3eb59678SJeremy L Thompson println!("Number of solution nodes : {}", solution_size); 128*3eb59678SJeremy L Thompson } 129*3eb59678SJeremy L Thompson 130*3eb59678SJeremy L Thompson // Create a Vector with the mesh coordinates 131*3eb59678SJeremy L Thompson let mut mesh_coords = mesh::cartesian_mesh_coords(&ceed, dim, num_xyz, mesh_degree, mesh_size)?; 132*3eb59678SJeremy L Thompson 133*3eb59678SJeremy L Thompson // Apply a transformation to the mesh coordinates 134*3eb59678SJeremy L Thompson let exact_volume = transform::transform_mesh_coordinates(dim, mesh_size, &mut mesh_coords)?; 135*3eb59678SJeremy L Thompson 136*3eb59678SJeremy L Thompson // QFunction that builds the quadrature data for the mass operator 137*3eb59678SJeremy L Thompson // -- QFunction from user closure 138*3eb59678SJeremy L Thompson let build_mass = move |[jacobian, weights, ..]: QFunctionInputs, 139*3eb59678SJeremy L Thompson [qdata, ..]: QFunctionOutputs| { 140*3eb59678SJeremy L Thompson // Build quadrature data 141*3eb59678SJeremy L Thompson match dim { 142*3eb59678SJeremy L Thompson 1 => qdata 143*3eb59678SJeremy L Thompson .iter_mut() 144*3eb59678SJeremy L Thompson .zip(jacobian.iter().zip(weights.iter())) 145*3eb59678SJeremy L Thompson .for_each(|(qdata, (j, weight))| *qdata = j * weight), 146*3eb59678SJeremy L Thompson 2 => { 147*3eb59678SJeremy L Thompson let q = qdata.len(); 148*3eb59678SJeremy L Thompson qdata.iter_mut().zip(weights.iter()).enumerate().for_each( 149*3eb59678SJeremy L Thompson |(i, (qdata, weight))| { 150*3eb59678SJeremy L Thompson *qdata = (jacobian[i + q * 0] * jacobian[i + q * 3] 151*3eb59678SJeremy L Thompson - jacobian[i + q * 1] * jacobian[i + q * 2]) 152*3eb59678SJeremy L Thompson * weight 153*3eb59678SJeremy L Thompson }, 154*3eb59678SJeremy L Thompson ); 155*3eb59678SJeremy L Thompson } 156*3eb59678SJeremy L Thompson 3 => { 157*3eb59678SJeremy L Thompson let q = qdata.len(); 158*3eb59678SJeremy L Thompson qdata.iter_mut().zip(weights.iter()).enumerate().for_each( 159*3eb59678SJeremy L Thompson |(i, (qdata, weight))| { 160*3eb59678SJeremy L Thompson *qdata = (jacobian[i + q * 0] 161*3eb59678SJeremy L Thompson * (jacobian[i + q * 4] * jacobian[i + q * 8] 162*3eb59678SJeremy L Thompson - jacobian[i + q * 5] * jacobian[i + q * 7]) 163*3eb59678SJeremy L Thompson - jacobian[i + q * 1] 164*3eb59678SJeremy L Thompson * (jacobian[i + q * 3] * jacobian[i + q * 8] 165*3eb59678SJeremy L Thompson - jacobian[i + q * 5] * jacobian[i + q * 6]) 166*3eb59678SJeremy L Thompson + jacobian[i + q * 2] 167*3eb59678SJeremy L Thompson * (jacobian[i + q * 3] * jacobian[i + q * 7] 168*3eb59678SJeremy L Thompson - jacobian[i + q * 4] * jacobian[i + q * 6])) 169*3eb59678SJeremy L Thompson * weight 170*3eb59678SJeremy L Thompson }, 171*3eb59678SJeremy L Thompson ); 172*3eb59678SJeremy L Thompson } 173*3eb59678SJeremy L Thompson _ => unreachable!(), 174*3eb59678SJeremy L Thompson }; 175*3eb59678SJeremy L Thompson 176*3eb59678SJeremy L Thompson // Return clean error code 177*3eb59678SJeremy L Thompson 0 178*3eb59678SJeremy L Thompson }; 179*3eb59678SJeremy L Thompson let qf_build_closure = ceed 180*3eb59678SJeremy L Thompson .q_function_interior(1, Box::new(build_mass))? 181*3eb59678SJeremy L Thompson .input("dx", ncomp_x * dim, libceed::EvalMode::Grad)? 182*3eb59678SJeremy L Thompson .input("weights", 1, libceed::EvalMode::Weight)? 183*3eb59678SJeremy L Thompson .output("qdata", 1, libceed::EvalMode::None)?; 184*3eb59678SJeremy L Thompson // -- QFunction from gallery 185*3eb59678SJeremy L Thompson let qf_build_named = { 186*3eb59678SJeremy L Thompson let name = format!("Mass{}DBuild", dim); 187*3eb59678SJeremy L Thompson ceed.q_function_interior_by_name(&name)? 188*3eb59678SJeremy L Thompson }; 189*3eb59678SJeremy L Thompson // -- QFunction for use with Operator 190*3eb59678SJeremy L Thompson let qf_build = if gallery { 191*3eb59678SJeremy L Thompson QFunctionOpt::SomeQFunctionByName(&qf_build_named) 192*3eb59678SJeremy L Thompson } else { 193*3eb59678SJeremy L Thompson QFunctionOpt::SomeQFunction(&qf_build_closure) 194*3eb59678SJeremy L Thompson }; 195*3eb59678SJeremy L Thompson 196*3eb59678SJeremy L Thompson // Operator that build the quadrature data for the mass operator 197*3eb59678SJeremy L Thompson let op_build = ceed 198*3eb59678SJeremy L Thompson .operator(qf_build, QFunctionOpt::None, QFunctionOpt::None)? 199*3eb59678SJeremy L Thompson .name("build qdata")? 200*3eb59678SJeremy L Thompson .field("dx", &rstr_mesh, &basis_mesh, VectorOpt::Active)? 201*3eb59678SJeremy L Thompson .field( 202*3eb59678SJeremy L Thompson "weights", 203*3eb59678SJeremy L Thompson ElemRestrictionOpt::None, 204*3eb59678SJeremy L Thompson &basis_mesh, 205*3eb59678SJeremy L Thompson VectorOpt::None, 206*3eb59678SJeremy L Thompson )? 207*3eb59678SJeremy L Thompson .field("qdata", &rstr_qdata, BasisOpt::None, VectorOpt::Active)? 208*3eb59678SJeremy L Thompson .check()?; 209*3eb59678SJeremy L Thompson 210*3eb59678SJeremy L Thompson // Compute the quadrature data for the mass operator 211*3eb59678SJeremy L Thompson let elem_qpts = num_qpts.pow(dim as u32); 212*3eb59678SJeremy L Thompson let num_elem: usize = num_xyz.iter().take(dim).product(); 213*3eb59678SJeremy L Thompson let mut qdata = ceed.vector(num_elem * elem_qpts)?; 214*3eb59678SJeremy L Thompson op_build.apply(&mesh_coords, &mut qdata)?; 215*3eb59678SJeremy L Thompson 216*3eb59678SJeremy L Thompson // QFunction that applies the mass operator 217*3eb59678SJeremy L Thompson // -- QFunction from user closure 218*3eb59678SJeremy L Thompson let apply_mass = move |[u, qdata, ..]: QFunctionInputs, [v, ..]: QFunctionOutputs| { 219*3eb59678SJeremy L Thompson let q = qdata.len(); 220*3eb59678SJeremy L Thompson // Apply mass operator 221*3eb59678SJeremy L Thompson for c in 0..ncomp_u { 222*3eb59678SJeremy L Thompson v.iter_mut() 223*3eb59678SJeremy L Thompson .skip(c * q) 224*3eb59678SJeremy L Thompson .zip(u.iter().skip(c * q).zip(qdata.iter())) 225*3eb59678SJeremy L Thompson .for_each(|(v, (u, w))| *v = u * w); 226*3eb59678SJeremy L Thompson } 227*3eb59678SJeremy L Thompson // Return clean error code 228*3eb59678SJeremy L Thompson 0 229*3eb59678SJeremy L Thompson }; 230*3eb59678SJeremy L Thompson let qf_mass_closure = ceed 231*3eb59678SJeremy L Thompson .q_function_interior(1, Box::new(apply_mass))? 232*3eb59678SJeremy L Thompson .input("u", ncomp_u, libceed::EvalMode::Interp)? 233*3eb59678SJeremy L Thompson .input("qdata", 1, libceed::EvalMode::None)? 234*3eb59678SJeremy L Thompson .output("v", ncomp_u, libceed::EvalMode::Interp)?; 235*3eb59678SJeremy L Thompson // -- QFunction from gallery 236*3eb59678SJeremy L Thompson let qf_mass_named = ceed.q_function_interior_by_name("Vector3MassApply")?; 237*3eb59678SJeremy L Thompson // -- QFunction for use with Operator 238*3eb59678SJeremy L Thompson let qf_mass = if gallery { 239*3eb59678SJeremy L Thompson QFunctionOpt::SomeQFunctionByName(&qf_mass_named) 240*3eb59678SJeremy L Thompson } else { 241*3eb59678SJeremy L Thompson QFunctionOpt::SomeQFunction(&qf_mass_closure) 242*3eb59678SJeremy L Thompson }; 243*3eb59678SJeremy L Thompson 244*3eb59678SJeremy L Thompson // Mass Operator 245*3eb59678SJeremy L Thompson let op_mass = ceed 246*3eb59678SJeremy L Thompson .operator(qf_mass, QFunctionOpt::None, QFunctionOpt::None)? 247*3eb59678SJeremy L Thompson .name("mass")? 248*3eb59678SJeremy L Thompson .field("u", &rstr_solution, &basis_solution, VectorOpt::Active)? 249*3eb59678SJeremy L Thompson .field("qdata", &rstr_qdata, BasisOpt::None, &qdata)? 250*3eb59678SJeremy L Thompson .field("v", &rstr_solution, &basis_solution, VectorOpt::Active)? 251*3eb59678SJeremy L Thompson .check()?; 252*3eb59678SJeremy L Thompson 253*3eb59678SJeremy L Thompson // Solution vectors 254*3eb59678SJeremy L Thompson let mut u = ceed.vector(solution_size)?; 255*3eb59678SJeremy L Thompson let mut v = ceed.vector(solution_size)?; 256*3eb59678SJeremy L Thompson 257*3eb59678SJeremy L Thompson // Initialize u with component index 258*3eb59678SJeremy L Thompson u.set_value(0.0)?; 259*3eb59678SJeremy L Thompson for c in 0..ncomp_u { 260*3eb59678SJeremy L Thompson let q = solution_size / ncomp_u; 261*3eb59678SJeremy L Thompson u.view_mut()?.iter_mut().skip(c * q).take(q).for_each(|u| { 262*3eb59678SJeremy L Thompson *u = (c + 1) as libceed::Scalar; 263*3eb59678SJeremy L Thompson }); 264*3eb59678SJeremy L Thompson } 265*3eb59678SJeremy L Thompson 266*3eb59678SJeremy L Thompson // Apply the mass operator 267*3eb59678SJeremy L Thompson op_mass.apply(&u, &mut v)?; 268*3eb59678SJeremy L Thompson 269*3eb59678SJeremy L Thompson // Compute the mesh volume 270*3eb59678SJeremy L Thompson let volume: libceed::Scalar = v.view()?.iter().sum::<libceed::Scalar>() 271*3eb59678SJeremy L Thompson / ((ncomp_u * (ncomp_u + 1)) / 2) as libceed::Scalar; 272*3eb59678SJeremy L Thompson 273*3eb59678SJeremy L Thompson // Output results 274*3eb59678SJeremy L Thompson if !quiet { 275*3eb59678SJeremy L Thompson println!("Exact mesh volume : {:.12}", exact_volume); 276*3eb59678SJeremy L Thompson println!("Computed mesh volume : {:.12}", volume); 277*3eb59678SJeremy L Thompson println!( 278*3eb59678SJeremy L Thompson "Volume error : {:.12e}", 279*3eb59678SJeremy L Thompson volume - exact_volume 280*3eb59678SJeremy L Thompson ); 281*3eb59678SJeremy L Thompson } 282*3eb59678SJeremy L Thompson let tolerance = match dim { 283*3eb59678SJeremy L Thompson 1 => 200.0 * libceed::EPSILON, 284*3eb59678SJeremy L Thompson _ => 1E-5, 285*3eb59678SJeremy L Thompson }; 286*3eb59678SJeremy L Thompson let error = (volume - exact_volume).abs(); 287*3eb59678SJeremy L Thompson if error > tolerance { 288*3eb59678SJeremy L Thompson println!("Volume error too large: {:.12e}", error); 289*3eb59678SJeremy L Thompson return Err(libceed::Error { 290*3eb59678SJeremy L Thompson message: format!( 291*3eb59678SJeremy L Thompson "Volume error too large - expected: {:.12e}, actual: {:.12e}", 292*3eb59678SJeremy L Thompson tolerance, error 293*3eb59678SJeremy L Thompson ), 294*3eb59678SJeremy L Thompson }); 295*3eb59678SJeremy L Thompson } 296*3eb59678SJeremy L Thompson Ok(()) 297*3eb59678SJeremy L Thompson } 298*3eb59678SJeremy L Thompson 299*3eb59678SJeremy L Thompson // ---------------------------------------------------------------------------- 300*3eb59678SJeremy L Thompson // Tests 301*3eb59678SJeremy L Thompson // ---------------------------------------------------------------------------- 302*3eb59678SJeremy L Thompson #[cfg(test)] 303*3eb59678SJeremy L Thompson mod tests { 304*3eb59678SJeremy L Thompson use super::*; 305*3eb59678SJeremy L Thompson 306*3eb59678SJeremy L Thompson #[test] 307*3eb59678SJeremy L Thompson fn example_1_vector_1d() { 308*3eb59678SJeremy L Thompson let options = opt::Opt { 309*3eb59678SJeremy L Thompson ceed_spec: "/cpu/self/ref/serial".to_string(), 310*3eb59678SJeremy L Thompson dim: 1, 311*3eb59678SJeremy L Thompson mesh_degree: 4, 312*3eb59678SJeremy L Thompson solution_degree: 4, 313*3eb59678SJeremy L Thompson num_qpts: 6, 314*3eb59678SJeremy L Thompson problem_size_requested: -1, 315*3eb59678SJeremy L Thompson test: true, 316*3eb59678SJeremy L Thompson quiet: true, 317*3eb59678SJeremy L Thompson gallery: false, 318*3eb59678SJeremy L Thompson }; 319*3eb59678SJeremy L Thompson assert!(example_1_vector(options).is_ok()); 320*3eb59678SJeremy L Thompson } 321*3eb59678SJeremy L Thompson 322*3eb59678SJeremy L Thompson #[test] 323*3eb59678SJeremy L Thompson fn example_1_vector_2d() { 324*3eb59678SJeremy L Thompson let options = opt::Opt { 325*3eb59678SJeremy L Thompson ceed_spec: "/cpu/self/ref/serial".to_string(), 326*3eb59678SJeremy L Thompson dim: 2, 327*3eb59678SJeremy L Thompson mesh_degree: 4, 328*3eb59678SJeremy L Thompson solution_degree: 4, 329*3eb59678SJeremy L Thompson num_qpts: 6, 330*3eb59678SJeremy L Thompson problem_size_requested: -1, 331*3eb59678SJeremy L Thompson test: true, 332*3eb59678SJeremy L Thompson quiet: true, 333*3eb59678SJeremy L Thompson gallery: false, 334*3eb59678SJeremy L Thompson }; 335*3eb59678SJeremy L Thompson assert!(example_1_vector(options).is_ok()); 336*3eb59678SJeremy L Thompson } 337*3eb59678SJeremy L Thompson 338*3eb59678SJeremy L Thompson #[test] 339*3eb59678SJeremy L Thompson fn example_1_vector_3d() { 340*3eb59678SJeremy L Thompson let options = opt::Opt { 341*3eb59678SJeremy L Thompson ceed_spec: "/cpu/self/ref/serial".to_string(), 342*3eb59678SJeremy L Thompson dim: 3, 343*3eb59678SJeremy L Thompson mesh_degree: 4, 344*3eb59678SJeremy L Thompson solution_degree: 4, 345*3eb59678SJeremy L Thompson num_qpts: 6, 346*3eb59678SJeremy L Thompson problem_size_requested: -1, 347*3eb59678SJeremy L Thompson test: true, 348*3eb59678SJeremy L Thompson quiet: false, 349*3eb59678SJeremy L Thompson gallery: false, 350*3eb59678SJeremy L Thompson }; 351*3eb59678SJeremy L Thompson assert!(example_1_vector(options).is_ok()); 352*3eb59678SJeremy L Thompson } 353*3eb59678SJeremy L Thompson 354*3eb59678SJeremy L Thompson #[test] 355*3eb59678SJeremy L Thompson fn example_1_vector_1d_gallery() { 356*3eb59678SJeremy L Thompson let options = opt::Opt { 357*3eb59678SJeremy L Thompson ceed_spec: "/cpu/self/ref/serial".to_string(), 358*3eb59678SJeremy L Thompson dim: 1, 359*3eb59678SJeremy L Thompson mesh_degree: 4, 360*3eb59678SJeremy L Thompson solution_degree: 4, 361*3eb59678SJeremy L Thompson num_qpts: 6, 362*3eb59678SJeremy L Thompson problem_size_requested: -1, 363*3eb59678SJeremy L Thompson test: true, 364*3eb59678SJeremy L Thompson quiet: true, 365*3eb59678SJeremy L Thompson gallery: true, 366*3eb59678SJeremy L Thompson }; 367*3eb59678SJeremy L Thompson assert!(example_1_vector(options).is_ok()); 368*3eb59678SJeremy L Thompson } 369*3eb59678SJeremy L Thompson 370*3eb59678SJeremy L Thompson #[test] 371*3eb59678SJeremy L Thompson fn example_1_vector_2d_gallery() { 372*3eb59678SJeremy L Thompson let options = opt::Opt { 373*3eb59678SJeremy L Thompson ceed_spec: "/cpu/self/ref/serial".to_string(), 374*3eb59678SJeremy L Thompson dim: 2, 375*3eb59678SJeremy L Thompson mesh_degree: 4, 376*3eb59678SJeremy L Thompson solution_degree: 4, 377*3eb59678SJeremy L Thompson num_qpts: 6, 378*3eb59678SJeremy L Thompson problem_size_requested: -1, 379*3eb59678SJeremy L Thompson test: true, 380*3eb59678SJeremy L Thompson quiet: true, 381*3eb59678SJeremy L Thompson gallery: true, 382*3eb59678SJeremy L Thompson }; 383*3eb59678SJeremy L Thompson assert!(example_1_vector(options).is_ok()); 384*3eb59678SJeremy L Thompson } 385*3eb59678SJeremy L Thompson 386*3eb59678SJeremy L Thompson #[test] 387*3eb59678SJeremy L Thompson fn example_1_vector_3d_gallery() { 388*3eb59678SJeremy L Thompson let options = opt::Opt { 389*3eb59678SJeremy L Thompson ceed_spec: "/cpu/self/ref/serial".to_string(), 390*3eb59678SJeremy L Thompson dim: 3, 391*3eb59678SJeremy L Thompson mesh_degree: 4, 392*3eb59678SJeremy L Thompson solution_degree: 4, 393*3eb59678SJeremy L Thompson num_qpts: 6, 394*3eb59678SJeremy L Thompson problem_size_requested: -1, 395*3eb59678SJeremy L Thompson test: true, 396*3eb59678SJeremy L Thompson quiet: true, 397*3eb59678SJeremy L Thompson gallery: true, 398*3eb59678SJeremy L Thompson }; 399*3eb59678SJeremy L Thompson assert!(example_1_vector(options).is_ok()); 400*3eb59678SJeremy L Thompson } 401*3eb59678SJeremy L Thompson } 402*3eb59678SJeremy L Thompson 403*3eb59678SJeremy L Thompson // ---------------------------------------------------------------------------- 404