1*9ba83ac0SJeremy L Thompson // Copyright (c) 2017-2026, Lawrence Livermore National Security, LLC and other CEED contributors.
23eb59678SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
33eb59678SJeremy L Thompson //
43eb59678SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause
53eb59678SJeremy L Thompson //
63eb59678SJeremy L Thompson // This file is part of CEED: http://github.com/ceed
73eb59678SJeremy L Thompson //
83eb59678SJeremy L Thompson // libCEED Example 3
93eb59678SJeremy L Thompson //
103eb59678SJeremy L Thompson // This example illustrates a simple usage of libCEED to compute the volume of a
113eb59678SJeremy L Thompson // 3D body using matrix-free application of a mass operator. Arbitrary mesh and
123eb59678SJeremy L Thompson // solution orders in 1D, 2D and 3D are supported from the same code. This
133eb59678SJeremy L Thompson // calculation is executed in triplicate with a 3 component vector system.
143eb59678SJeremy L Thompson //
153eb59678SJeremy L Thompson // The example has no dependencies, and is designed to be self-contained. For
163eb59678SJeremy L Thompson // additional examples that use external discretization libraries (MFEM, PETSc,
173eb59678SJeremy L Thompson // etc.) see the subdirectories in libceed/examples.
183eb59678SJeremy L Thompson //
193eb59678SJeremy L Thompson // All libCEED objects use a Ceed device object constructed based on a command
203eb59678SJeremy L Thompson // line argument (-ceed).
213eb59678SJeremy L Thompson
223eb59678SJeremy L Thompson use clap::Parser;
233eb59678SJeremy L Thompson use libceed::{
243eb59678SJeremy L Thompson BasisOpt, Ceed, ElemRestrictionOpt, QFunctionInputs, QFunctionOpt, QFunctionOutputs, VectorOpt,
253eb59678SJeremy L Thompson };
263eb59678SJeremy L Thompson mod opt;
273eb59678SJeremy L Thompson mod transform;
283eb59678SJeremy L Thompson
293eb59678SJeremy L Thompson // ----------------------------------------------------------------------------
303eb59678SJeremy L Thompson // Example 3
313eb59678SJeremy L Thompson // ----------------------------------------------------------------------------
main() -> libceed::Result<()>323eb59678SJeremy L Thompson fn main() -> libceed::Result<()> {
333eb59678SJeremy L Thompson let options = opt::Opt::parse();
343eb59678SJeremy L Thompson example_1_vector(options)
353eb59678SJeremy L Thompson }
363eb59678SJeremy L Thompson
373eb59678SJeremy L Thompson #[allow(clippy::erasing_op)]
383eb59678SJeremy L Thompson #[allow(clippy::identity_op)]
example_1_vector(options: opt::Opt) -> libceed::Result<()>393eb59678SJeremy L Thompson fn example_1_vector(options: opt::Opt) -> libceed::Result<()> {
403eb59678SJeremy L Thompson // Process command line arguments
413eb59678SJeremy L Thompson let opt::Opt {
423eb59678SJeremy L Thompson ceed_spec,
433eb59678SJeremy L Thompson dim,
443eb59678SJeremy L Thompson mesh_degree,
453eb59678SJeremy L Thompson solution_degree,
463eb59678SJeremy L Thompson num_qpts,
473eb59678SJeremy L Thompson problem_size_requested,
483eb59678SJeremy L Thompson test,
493eb59678SJeremy L Thompson quiet,
503eb59678SJeremy L Thompson gallery,
513eb59678SJeremy L Thompson } = options;
523eb59678SJeremy L Thompson assert!((0..=3).contains(&dim));
533eb59678SJeremy L Thompson assert!(mesh_degree >= 1);
543eb59678SJeremy L Thompson assert!(solution_degree >= 1);
553eb59678SJeremy L Thompson assert!(num_qpts >= 1);
563eb59678SJeremy L Thompson let ncomp_x = dim;
573eb59678SJeremy L Thompson let problem_size: i64 = if problem_size_requested < 0 {
583eb59678SJeremy L Thompson if test {
593eb59678SJeremy L Thompson 8 * 16
603eb59678SJeremy L Thompson } else {
613eb59678SJeremy L Thompson 256 * 1024
623eb59678SJeremy L Thompson }
633eb59678SJeremy L Thompson } else {
643eb59678SJeremy L Thompson problem_size_requested
653eb59678SJeremy L Thompson };
663eb59678SJeremy L Thompson let ncomp_u = 3;
673eb59678SJeremy L Thompson
683eb59678SJeremy L Thompson // Summary output
693eb59678SJeremy L Thompson if !quiet {
703eb59678SJeremy L Thompson println!("Selected options: [command line option] : <current value>");
713eb59678SJeremy L Thompson println!(" Ceed specification [-c] : {}", ceed_spec);
723eb59678SJeremy L Thompson println!(" Mesh dimension [-d] : {}", dim);
733eb59678SJeremy L Thompson println!(" Mesh degree [-m] : {}", mesh_degree);
743eb59678SJeremy L Thompson println!(" Solution degree [-p] : {}", solution_degree);
753eb59678SJeremy L Thompson println!(" Num. 1D quadr. pts [-q] : {}", num_qpts);
763eb59678SJeremy L Thompson println!(" Approx. # unknowns [-s] : {}", problem_size);
773eb59678SJeremy L Thompson println!(
783eb59678SJeremy L Thompson " QFunction source [-g] : {}",
793eb59678SJeremy L Thompson if gallery { "gallery" } else { "user closure" }
803eb59678SJeremy L Thompson );
813eb59678SJeremy L Thompson }
823eb59678SJeremy L Thompson
833eb59678SJeremy L Thompson // Initalize ceed context
843eb59678SJeremy L Thompson let ceed = Ceed::init(&ceed_spec);
853eb59678SJeremy L Thompson
863eb59678SJeremy L Thompson // Mesh and solution bases
873eb59678SJeremy L Thompson let basis_mesh = ceed.basis_tensor_H1_Lagrange(
883eb59678SJeremy L Thompson dim,
893eb59678SJeremy L Thompson ncomp_x,
903eb59678SJeremy L Thompson mesh_degree + 1,
913eb59678SJeremy L Thompson num_qpts,
923eb59678SJeremy L Thompson libceed::QuadMode::Gauss,
933eb59678SJeremy L Thompson )?;
943eb59678SJeremy L Thompson let basis_solution = ceed.basis_tensor_H1_Lagrange(
953eb59678SJeremy L Thompson dim,
963eb59678SJeremy L Thompson ncomp_u,
973eb59678SJeremy L Thompson solution_degree + 1,
983eb59678SJeremy L Thompson num_qpts,
993eb59678SJeremy L Thompson libceed::QuadMode::Gauss,
1003eb59678SJeremy L Thompson )?;
1013eb59678SJeremy L Thompson
1023eb59678SJeremy L Thompson // Determine mesh size from approximate problem size
1033eb59678SJeremy L Thompson let num_xyz = mesh::cartesian_mesh_size(dim, solution_degree, problem_size);
1043eb59678SJeremy L Thompson if !quiet {
1053eb59678SJeremy L Thompson print!("\nMesh size : nx = {}", num_xyz[0]);
1063eb59678SJeremy L Thompson if dim > 1 {
1073eb59678SJeremy L Thompson print!(", ny = {}", num_xyz[1]);
1083eb59678SJeremy L Thompson }
1093eb59678SJeremy L Thompson if dim > 2 {
1103eb59678SJeremy L Thompson print!(", nz = {}", num_xyz[2]);
1113eb59678SJeremy L Thompson }
1123eb59678SJeremy L Thompson println!();
1133eb59678SJeremy L Thompson }
1143eb59678SJeremy L Thompson
1153eb59678SJeremy L Thompson // Build ElemRestriction objects describing the mesh and solution discrete
1163eb59678SJeremy L Thompson // representations
1173eb59678SJeremy L Thompson let (rstr_mesh, _) =
1183eb59678SJeremy L Thompson mesh::build_cartesian_restriction(&ceed, dim, num_xyz, mesh_degree, ncomp_x, num_qpts)?;
1193eb59678SJeremy L Thompson let (_, rstr_qdata) =
1203eb59678SJeremy L Thompson mesh::build_cartesian_restriction(&ceed, dim, num_xyz, solution_degree, 1, num_qpts)?;
1213eb59678SJeremy L Thompson let (rstr_solution, _) =
1223eb59678SJeremy L Thompson mesh::build_cartesian_restriction(&ceed, dim, num_xyz, solution_degree, ncomp_u, num_qpts)?;
1233eb59678SJeremy L Thompson let mesh_size = rstr_mesh.lvector_size();
1243eb59678SJeremy L Thompson let solution_size = rstr_solution.lvector_size();
1253eb59678SJeremy L Thompson if !quiet {
1263eb59678SJeremy L Thompson println!("Number of mesh nodes : {}", mesh_size / dim);
1273eb59678SJeremy L Thompson println!("Number of solution nodes : {}", solution_size);
1283eb59678SJeremy L Thompson }
1293eb59678SJeremy L Thompson
1303eb59678SJeremy L Thompson // Create a Vector with the mesh coordinates
1313eb59678SJeremy L Thompson let mut mesh_coords = mesh::cartesian_mesh_coords(&ceed, dim, num_xyz, mesh_degree, mesh_size)?;
1323eb59678SJeremy L Thompson
1333eb59678SJeremy L Thompson // Apply a transformation to the mesh coordinates
1343eb59678SJeremy L Thompson let exact_volume = transform::transform_mesh_coordinates(dim, mesh_size, &mut mesh_coords)?;
1353eb59678SJeremy L Thompson
1363eb59678SJeremy L Thompson // QFunction that builds the quadrature data for the mass operator
1373eb59678SJeremy L Thompson // -- QFunction from user closure
1383eb59678SJeremy L Thompson let build_mass = move |[jacobian, weights, ..]: QFunctionInputs,
1393eb59678SJeremy L Thompson [qdata, ..]: QFunctionOutputs| {
1403eb59678SJeremy L Thompson // Build quadrature data
1413eb59678SJeremy L Thompson match dim {
1423eb59678SJeremy L Thompson 1 => qdata
1433eb59678SJeremy L Thompson .iter_mut()
1443eb59678SJeremy L Thompson .zip(jacobian.iter().zip(weights.iter()))
1453eb59678SJeremy L Thompson .for_each(|(qdata, (j, weight))| *qdata = j * weight),
1463eb59678SJeremy L Thompson 2 => {
1473eb59678SJeremy L Thompson let q = qdata.len();
1483eb59678SJeremy L Thompson qdata.iter_mut().zip(weights.iter()).enumerate().for_each(
1493eb59678SJeremy L Thompson |(i, (qdata, weight))| {
1503eb59678SJeremy L Thompson *qdata = (jacobian[i + q * 0] * jacobian[i + q * 3]
1513eb59678SJeremy L Thompson - jacobian[i + q * 1] * jacobian[i + q * 2])
1523eb59678SJeremy L Thompson * weight
1533eb59678SJeremy L Thompson },
1543eb59678SJeremy L Thompson );
1553eb59678SJeremy L Thompson }
1563eb59678SJeremy L Thompson 3 => {
1573eb59678SJeremy L Thompson let q = qdata.len();
1583eb59678SJeremy L Thompson qdata.iter_mut().zip(weights.iter()).enumerate().for_each(
1593eb59678SJeremy L Thompson |(i, (qdata, weight))| {
1603eb59678SJeremy L Thompson *qdata = (jacobian[i + q * 0]
1613eb59678SJeremy L Thompson * (jacobian[i + q * 4] * jacobian[i + q * 8]
1623eb59678SJeremy L Thompson - jacobian[i + q * 5] * jacobian[i + q * 7])
1633eb59678SJeremy L Thompson - jacobian[i + q * 1]
1643eb59678SJeremy L Thompson * (jacobian[i + q * 3] * jacobian[i + q * 8]
1653eb59678SJeremy L Thompson - jacobian[i + q * 5] * jacobian[i + q * 6])
1663eb59678SJeremy L Thompson + jacobian[i + q * 2]
1673eb59678SJeremy L Thompson * (jacobian[i + q * 3] * jacobian[i + q * 7]
1683eb59678SJeremy L Thompson - jacobian[i + q * 4] * jacobian[i + q * 6]))
1693eb59678SJeremy L Thompson * weight
1703eb59678SJeremy L Thompson },
1713eb59678SJeremy L Thompson );
1723eb59678SJeremy L Thompson }
1733eb59678SJeremy L Thompson _ => unreachable!(),
1743eb59678SJeremy L Thompson };
1753eb59678SJeremy L Thompson
1763eb59678SJeremy L Thompson // Return clean error code
1773eb59678SJeremy L Thompson 0
1783eb59678SJeremy L Thompson };
1793eb59678SJeremy L Thompson let qf_build_closure = ceed
1803eb59678SJeremy L Thompson .q_function_interior(1, Box::new(build_mass))?
1813eb59678SJeremy L Thompson .input("dx", ncomp_x * dim, libceed::EvalMode::Grad)?
1823eb59678SJeremy L Thompson .input("weights", 1, libceed::EvalMode::Weight)?
1833eb59678SJeremy L Thompson .output("qdata", 1, libceed::EvalMode::None)?;
1843eb59678SJeremy L Thompson // -- QFunction from gallery
1853eb59678SJeremy L Thompson let qf_build_named = {
1863eb59678SJeremy L Thompson let name = format!("Mass{}DBuild", dim);
1873eb59678SJeremy L Thompson ceed.q_function_interior_by_name(&name)?
1883eb59678SJeremy L Thompson };
1893eb59678SJeremy L Thompson // -- QFunction for use with Operator
1903eb59678SJeremy L Thompson let qf_build = if gallery {
1913eb59678SJeremy L Thompson QFunctionOpt::SomeQFunctionByName(&qf_build_named)
1923eb59678SJeremy L Thompson } else {
1933eb59678SJeremy L Thompson QFunctionOpt::SomeQFunction(&qf_build_closure)
1943eb59678SJeremy L Thompson };
1953eb59678SJeremy L Thompson
1963eb59678SJeremy L Thompson // Operator that build the quadrature data for the mass operator
1973eb59678SJeremy L Thompson let op_build = ceed
1983eb59678SJeremy L Thompson .operator(qf_build, QFunctionOpt::None, QFunctionOpt::None)?
1993eb59678SJeremy L Thompson .name("build qdata")?
2003eb59678SJeremy L Thompson .field("dx", &rstr_mesh, &basis_mesh, VectorOpt::Active)?
2013eb59678SJeremy L Thompson .field(
2023eb59678SJeremy L Thompson "weights",
2033eb59678SJeremy L Thompson ElemRestrictionOpt::None,
2043eb59678SJeremy L Thompson &basis_mesh,
2053eb59678SJeremy L Thompson VectorOpt::None,
2063eb59678SJeremy L Thompson )?
2073eb59678SJeremy L Thompson .field("qdata", &rstr_qdata, BasisOpt::None, VectorOpt::Active)?
2083eb59678SJeremy L Thompson .check()?;
2093eb59678SJeremy L Thompson
2103eb59678SJeremy L Thompson // Compute the quadrature data for the mass operator
2113eb59678SJeremy L Thompson let elem_qpts = num_qpts.pow(dim as u32);
2123eb59678SJeremy L Thompson let num_elem: usize = num_xyz.iter().take(dim).product();
2133eb59678SJeremy L Thompson let mut qdata = ceed.vector(num_elem * elem_qpts)?;
2143eb59678SJeremy L Thompson op_build.apply(&mesh_coords, &mut qdata)?;
2153eb59678SJeremy L Thompson
2163eb59678SJeremy L Thompson // QFunction that applies the mass operator
2173eb59678SJeremy L Thompson // -- QFunction from user closure
2183eb59678SJeremy L Thompson let apply_mass = move |[u, qdata, ..]: QFunctionInputs, [v, ..]: QFunctionOutputs| {
2193eb59678SJeremy L Thompson let q = qdata.len();
2203eb59678SJeremy L Thompson // Apply mass operator
2213eb59678SJeremy L Thompson for c in 0..ncomp_u {
2223eb59678SJeremy L Thompson v.iter_mut()
2233eb59678SJeremy L Thompson .skip(c * q)
2243eb59678SJeremy L Thompson .zip(u.iter().skip(c * q).zip(qdata.iter()))
2253eb59678SJeremy L Thompson .for_each(|(v, (u, w))| *v = u * w);
2263eb59678SJeremy L Thompson }
2273eb59678SJeremy L Thompson // Return clean error code
2283eb59678SJeremy L Thompson 0
2293eb59678SJeremy L Thompson };
2303eb59678SJeremy L Thompson let qf_mass_closure = ceed
2313eb59678SJeremy L Thompson .q_function_interior(1, Box::new(apply_mass))?
2323eb59678SJeremy L Thompson .input("u", ncomp_u, libceed::EvalMode::Interp)?
2333eb59678SJeremy L Thompson .input("qdata", 1, libceed::EvalMode::None)?
2343eb59678SJeremy L Thompson .output("v", ncomp_u, libceed::EvalMode::Interp)?;
2353eb59678SJeremy L Thompson // -- QFunction from gallery
2363eb59678SJeremy L Thompson let qf_mass_named = ceed.q_function_interior_by_name("Vector3MassApply")?;
2373eb59678SJeremy L Thompson // -- QFunction for use with Operator
2383eb59678SJeremy L Thompson let qf_mass = if gallery {
2393eb59678SJeremy L Thompson QFunctionOpt::SomeQFunctionByName(&qf_mass_named)
2403eb59678SJeremy L Thompson } else {
2413eb59678SJeremy L Thompson QFunctionOpt::SomeQFunction(&qf_mass_closure)
2423eb59678SJeremy L Thompson };
2433eb59678SJeremy L Thompson
2443eb59678SJeremy L Thompson // Mass Operator
2453eb59678SJeremy L Thompson let op_mass = ceed
2463eb59678SJeremy L Thompson .operator(qf_mass, QFunctionOpt::None, QFunctionOpt::None)?
2473eb59678SJeremy L Thompson .name("mass")?
2483eb59678SJeremy L Thompson .field("u", &rstr_solution, &basis_solution, VectorOpt::Active)?
2493eb59678SJeremy L Thompson .field("qdata", &rstr_qdata, BasisOpt::None, &qdata)?
2503eb59678SJeremy L Thompson .field("v", &rstr_solution, &basis_solution, VectorOpt::Active)?
2513eb59678SJeremy L Thompson .check()?;
2523eb59678SJeremy L Thompson
2533eb59678SJeremy L Thompson // Solution vectors
2543eb59678SJeremy L Thompson let mut u = ceed.vector(solution_size)?;
2553eb59678SJeremy L Thompson let mut v = ceed.vector(solution_size)?;
2563eb59678SJeremy L Thompson
2573eb59678SJeremy L Thompson // Initialize u with component index
2583eb59678SJeremy L Thompson u.set_value(0.0)?;
2593eb59678SJeremy L Thompson for c in 0..ncomp_u {
2603eb59678SJeremy L Thompson let q = solution_size / ncomp_u;
2613eb59678SJeremy L Thompson u.view_mut()?.iter_mut().skip(c * q).take(q).for_each(|u| {
2623eb59678SJeremy L Thompson *u = (c + 1) as libceed::Scalar;
2633eb59678SJeremy L Thompson });
2643eb59678SJeremy L Thompson }
2653eb59678SJeremy L Thompson
2663eb59678SJeremy L Thompson // Apply the mass operator
2673eb59678SJeremy L Thompson op_mass.apply(&u, &mut v)?;
2683eb59678SJeremy L Thompson
2693eb59678SJeremy L Thompson // Compute the mesh volume
2703eb59678SJeremy L Thompson let volume: libceed::Scalar = v.view()?.iter().sum::<libceed::Scalar>()
2713eb59678SJeremy L Thompson / ((ncomp_u * (ncomp_u + 1)) / 2) as libceed::Scalar;
2723eb59678SJeremy L Thompson
2733eb59678SJeremy L Thompson // Output results
2743eb59678SJeremy L Thompson if !quiet {
2753eb59678SJeremy L Thompson println!("Exact mesh volume : {:.12}", exact_volume);
2763eb59678SJeremy L Thompson println!("Computed mesh volume : {:.12}", volume);
2773eb59678SJeremy L Thompson println!(
2783eb59678SJeremy L Thompson "Volume error : {:.12e}",
2793eb59678SJeremy L Thompson volume - exact_volume
2803eb59678SJeremy L Thompson );
2813eb59678SJeremy L Thompson }
2823eb59678SJeremy L Thompson let tolerance = match dim {
2833eb59678SJeremy L Thompson 1 => 200.0 * libceed::EPSILON,
2843eb59678SJeremy L Thompson _ => 1E-5,
2853eb59678SJeremy L Thompson };
2863eb59678SJeremy L Thompson let error = (volume - exact_volume).abs();
2873eb59678SJeremy L Thompson if error > tolerance {
2883eb59678SJeremy L Thompson println!("Volume error too large: {:.12e}", error);
2893eb59678SJeremy L Thompson return Err(libceed::Error {
2903eb59678SJeremy L Thompson message: format!(
2913eb59678SJeremy L Thompson "Volume error too large - expected: {:.12e}, actual: {:.12e}",
2923eb59678SJeremy L Thompson tolerance, error
2933eb59678SJeremy L Thompson ),
2943eb59678SJeremy L Thompson });
2953eb59678SJeremy L Thompson }
2963eb59678SJeremy L Thompson Ok(())
2973eb59678SJeremy L Thompson }
2983eb59678SJeremy L Thompson
2993eb59678SJeremy L Thompson // ----------------------------------------------------------------------------
3003eb59678SJeremy L Thompson // Tests
3013eb59678SJeremy L Thompson // ----------------------------------------------------------------------------
3023eb59678SJeremy L Thompson #[cfg(test)]
3033eb59678SJeremy L Thompson mod tests {
3043eb59678SJeremy L Thompson use super::*;
3053eb59678SJeremy L Thompson
3063eb59678SJeremy L Thompson #[test]
example_1_vector_1d()3073eb59678SJeremy L Thompson fn example_1_vector_1d() {
3083eb59678SJeremy L Thompson let options = opt::Opt {
3093eb59678SJeremy L Thompson ceed_spec: "/cpu/self/ref/serial".to_string(),
3103eb59678SJeremy L Thompson dim: 1,
3113eb59678SJeremy L Thompson mesh_degree: 4,
3123eb59678SJeremy L Thompson solution_degree: 4,
3133eb59678SJeremy L Thompson num_qpts: 6,
3143eb59678SJeremy L Thompson problem_size_requested: -1,
3153eb59678SJeremy L Thompson test: true,
3163eb59678SJeremy L Thompson quiet: true,
3173eb59678SJeremy L Thompson gallery: false,
3183eb59678SJeremy L Thompson };
3193eb59678SJeremy L Thompson assert!(example_1_vector(options).is_ok());
3203eb59678SJeremy L Thompson }
3213eb59678SJeremy L Thompson
3223eb59678SJeremy L Thompson #[test]
example_1_vector_2d()3233eb59678SJeremy L Thompson fn example_1_vector_2d() {
3243eb59678SJeremy L Thompson let options = opt::Opt {
3253eb59678SJeremy L Thompson ceed_spec: "/cpu/self/ref/serial".to_string(),
3263eb59678SJeremy L Thompson dim: 2,
3273eb59678SJeremy L Thompson mesh_degree: 4,
3283eb59678SJeremy L Thompson solution_degree: 4,
3293eb59678SJeremy L Thompson num_qpts: 6,
3303eb59678SJeremy L Thompson problem_size_requested: -1,
3313eb59678SJeremy L Thompson test: true,
3323eb59678SJeremy L Thompson quiet: true,
3333eb59678SJeremy L Thompson gallery: false,
3343eb59678SJeremy L Thompson };
3353eb59678SJeremy L Thompson assert!(example_1_vector(options).is_ok());
3363eb59678SJeremy L Thompson }
3373eb59678SJeremy L Thompson
3383eb59678SJeremy L Thompson #[test]
example_1_vector_3d()3393eb59678SJeremy L Thompson fn example_1_vector_3d() {
3403eb59678SJeremy L Thompson let options = opt::Opt {
3413eb59678SJeremy L Thompson ceed_spec: "/cpu/self/ref/serial".to_string(),
3423eb59678SJeremy L Thompson dim: 3,
3433eb59678SJeremy L Thompson mesh_degree: 4,
3443eb59678SJeremy L Thompson solution_degree: 4,
3453eb59678SJeremy L Thompson num_qpts: 6,
3463eb59678SJeremy L Thompson problem_size_requested: -1,
3473eb59678SJeremy L Thompson test: true,
3483eb59678SJeremy L Thompson quiet: false,
3493eb59678SJeremy L Thompson gallery: false,
3503eb59678SJeremy L Thompson };
3513eb59678SJeremy L Thompson assert!(example_1_vector(options).is_ok());
3523eb59678SJeremy L Thompson }
3533eb59678SJeremy L Thompson
3543eb59678SJeremy L Thompson #[test]
example_1_vector_1d_gallery()3553eb59678SJeremy L Thompson fn example_1_vector_1d_gallery() {
3563eb59678SJeremy L Thompson let options = opt::Opt {
3573eb59678SJeremy L Thompson ceed_spec: "/cpu/self/ref/serial".to_string(),
3583eb59678SJeremy L Thompson dim: 1,
3593eb59678SJeremy L Thompson mesh_degree: 4,
3603eb59678SJeremy L Thompson solution_degree: 4,
3613eb59678SJeremy L Thompson num_qpts: 6,
3623eb59678SJeremy L Thompson problem_size_requested: -1,
3633eb59678SJeremy L Thompson test: true,
3643eb59678SJeremy L Thompson quiet: true,
3653eb59678SJeremy L Thompson gallery: true,
3663eb59678SJeremy L Thompson };
3673eb59678SJeremy L Thompson assert!(example_1_vector(options).is_ok());
3683eb59678SJeremy L Thompson }
3693eb59678SJeremy L Thompson
3703eb59678SJeremy L Thompson #[test]
example_1_vector_2d_gallery()3713eb59678SJeremy L Thompson fn example_1_vector_2d_gallery() {
3723eb59678SJeremy L Thompson let options = opt::Opt {
3733eb59678SJeremy L Thompson ceed_spec: "/cpu/self/ref/serial".to_string(),
3743eb59678SJeremy L Thompson dim: 2,
3753eb59678SJeremy L Thompson mesh_degree: 4,
3763eb59678SJeremy L Thompson solution_degree: 4,
3773eb59678SJeremy L Thompson num_qpts: 6,
3783eb59678SJeremy L Thompson problem_size_requested: -1,
3793eb59678SJeremy L Thompson test: true,
3803eb59678SJeremy L Thompson quiet: true,
3813eb59678SJeremy L Thompson gallery: true,
3823eb59678SJeremy L Thompson };
3833eb59678SJeremy L Thompson assert!(example_1_vector(options).is_ok());
3843eb59678SJeremy L Thompson }
3853eb59678SJeremy L Thompson
3863eb59678SJeremy L Thompson #[test]
example_1_vector_3d_gallery()3873eb59678SJeremy L Thompson fn example_1_vector_3d_gallery() {
3883eb59678SJeremy L Thompson let options = opt::Opt {
3893eb59678SJeremy L Thompson ceed_spec: "/cpu/self/ref/serial".to_string(),
3903eb59678SJeremy L Thompson dim: 3,
3913eb59678SJeremy L Thompson mesh_degree: 4,
3923eb59678SJeremy L Thompson solution_degree: 4,
3933eb59678SJeremy L Thompson num_qpts: 6,
3943eb59678SJeremy L Thompson problem_size_requested: -1,
3953eb59678SJeremy L Thompson test: true,
3963eb59678SJeremy L Thompson quiet: true,
3973eb59678SJeremy L Thompson gallery: true,
3983eb59678SJeremy L Thompson };
3993eb59678SJeremy L Thompson assert!(example_1_vector(options).is_ok());
4003eb59678SJeremy L Thompson }
4013eb59678SJeremy L Thompson }
4023eb59678SJeremy L Thompson
4033eb59678SJeremy L Thompson // ----------------------------------------------------------------------------
404