10 #include "gtest/gtest.h" 30 #include "libmesh/elem.h" 31 #include "libmesh/tensor_value.h" 32 #include "libmesh/point.h" 33 #include "libmesh/vector_value.h" 34 #include "libmesh/utility.h" 43 const char * argv[2] = {
"foo",
"\0"};
48 std::vector<unsigned int> num_elem = {64, 128, 256};
49 std::vector<Real> weller_errors;
50 std::vector<Real> moukalled_errors;
51 std::vector<Real> tano_errors;
52 std::vector<Real> tano_errors_twice;
53 std::vector<Real> h(num_elem.size());
55 h[i] = 1. / num_elem[i];
59 const auto nx = num_elem[i];
61 auto * factory = &app->getFactory();
62 std::string mesh_type =
"MeshGeneratorMesh";
64 std::shared_ptr<MeshGeneratorMesh>
mesh;
70 app->actionWarehouse().mesh() =
mesh;
73 std::unique_ptr<MeshBase> lm_mesh;
74 InputParameters params = factory->getValidParams(
"GeneratedMeshGenerator");
75 params.
set<
unsigned int>(
"nx") = nx;
76 params.
set<
unsigned int>(
"ny") = nx;
80 lm_mesh = mesh_gen->generate();
81 mesh->setMeshBase(std::move(lm_mesh));
84 mesh->prepare(
nullptr);
85 mesh->setCoordSystem({}, coord_type_enum);
86 mooseAssert(
mesh->getAxisymmetricRadialCoord() == 0,
87 "This should be 0 because we haven't set anything.");
88 const auto & all_fi =
mesh->allFaceInfo();
89 mesh->buildFiniteVolumeInfo();
90 mesh->computeFiniteVolumeCoords();
91 std::vector<const FaceInfo *> faces(all_fi.size());
93 faces[i] = &all_fi[i];
95 auto & lm_mesh =
mesh->getMesh();
99 for (
auto *
const elem : lm_mesh.active_element_ptr_range())
101 const auto centroid = elem->vertex_average();
103 std::cos(centroid(0)) * std::sin(centroid(1)));
104 u[elem->id()] =
value;
108 up_weller(*
mesh,
"up_weller",
true);
110 up_moukalled(*
mesh,
"up_moukalled",
true);
112 up_tano(*
mesh,
"up_tano",
true);
114 for (
const auto & fi : all_fi)
116 auto moukalled_reconstruct = [&fi](
auto & functor,
auto & container)
121 const Point surface_vector = fi.normal() * fi.faceArea();
122 auto product = (uf * fi.dCN()) * surface_vector;
124 container[fi.elem().id()] += product * fi.gC() / fi.elemVolume();
125 if (fi.neighborPtr())
126 container[fi.neighbor().id()] +=
127 std::move(product) * (1. - fi.gC()) / fi.neighborVolume();
130 moukalled_reconstruct(u, up_moukalled);
137 Real weller_error = 0;
139 Real moukalled_error = 0;
140 const auto current_h = h[i];
141 for (
auto *
const elem : lm_mesh.active_element_ptr_range())
143 const auto elem_id = elem->id();
147 auto compute_elem_error =
148 [elem_id, current_h, elem, &analytic](
auto & container,
auto & error)
150 auto & current = libmesh_map_find(container, elem_id);
151 const auto diff = analytic - current;
152 error += diff * diff * current_h * current_h;
155 const auto elem_point_eval = container(
161 compute_elem_error(up_weller, weller_error);
162 compute_elem_error(up_moukalled, moukalled_error);
163 compute_elem_error(up_tano, tano_error);
165 error = std::sqrt(error);
166 weller_error = std::sqrt(weller_error);
167 moukalled_error = std::sqrt(moukalled_error);
168 tano_error = std::sqrt(tano_error);
169 weller_errors.push_back(weller_error);
170 moukalled_errors.push_back(moukalled_error);
171 tano_errors.push_back(tano_error);
177 for (
auto *
const elem : lm_mesh.active_element_ptr_range())
179 const auto elem_id = elem->id();
183 auto compute_elem_error = [elem_id, current_h, &analytic](
auto & container,
auto & error)
185 auto & current = libmesh_map_find(container, elem_id);
186 const auto diff = analytic - current;
187 error += diff * diff * current_h * current_h;
189 compute_elem_error(up_tano, tano_error);
191 tano_error = std::sqrt(tano_error);
192 tano_errors_twice.push_back(tano_error);
195 *
mesh,
"not_restricted",
true);
201 catch (std::runtime_error & e)
203 EXPECT_TRUE(std::string(e.what()).find(
"not_restricted") != std::string::npos);
204 EXPECT_TRUE(std::string(e.what()).find(
"Make sure to fill") != std::string::npos);
208 *
mesh, {1},
"is_restricted",
true);
214 catch (std::runtime_error & e)
216 EXPECT_TRUE(std::string(e.what()).find(
"is_restricted") != std::string::npos);
217 EXPECT_TRUE(std::string(e.what()).find(
"0") != std::string::npos);
219 std::string(e.what()).find(
220 "that subdomain id is not one of the subdomain ids the functor is restricted to") !=
225 std::for_each(h.begin(), h.end(), [](
Real & h_elem) { h_elem = std::log(h_elem); });
227 auto expect_errors = [&h](
auto & errors_arg,
Real expected_error)
230 errors_arg.begin(), errors_arg.end(), [](
Real & error) { error = std::log(error); });
234 const auto & coeffs = fit.getCoefficients();
235 EXPECT_NEAR(coeffs[1], expected_error, .05);
239 expect_errors(moukalled_errors, 2);
240 expect_errors(tano_errors, 2);
241 expect_errors(tano_errors_twice, 2);
This class constructs a functional expansion using a separate series for each Cartesian dimension...
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
static constexpr std::size_t dim
void interpolateReconstruct(CellCenteredMapFunctor< T, Map > &output_functor, const Moose::FunctorBase< T > &input_functor, const unsigned int num_int_recs, const bool weight_with_sf, const std::vector< const FaceInfo *> &faces, const Moose::StateArg &time)
Takes an input functor that can be evaluated at faces, typically by linearly interpolating between ad...
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
static MooseAppPtr createAppShared(int argc, char **argv, std::unique_ptr< Parser > parser)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)
TEST(TestReconstruction, Cartesian)
auto index_range(const T &sizable)
void testReconstruction(const Moose::CoordinateSystemType coord_type)
A functor whose evaluation relies on querying a map where the keys are element ids and the values cor...