14 using namespace MoFEM;
16 static char help[] =
"...\n\n";
42 template <
int FIELD_DIM>
46 template <
int FIELD_DIM>
50 template <
int FIELD_DIM>
54 template <
int FIELD_DIM>
58 template <
int FIELD_DIM>
64 int main(
int argc,
char *argv[]) {
80 DMType dm_name =
"DMMOFEM";
84 auto core_log = logging::core::get();
117 auto post_proc = [&](
auto dm,
auto f_res,
auto out_name) {
120 boost::make_shared<PostProcBrokenMeshInMoab<DomainEle>>(m_field);
124 auto scal_vec = boost::make_shared<VectorDouble>();
125 auto vec_mat = boost::make_shared<MatrixDouble>();
127 post_proc_fe->getOpPtrVector().push_back(
129 post_proc_fe->getOpPtrVector().push_back(
133 post_proc_fe->getOpPtrVector().push_back(
137 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
139 {{
"SCALAR", scal_vec}},
141 {{
"VECTOR", vec_mat}},
149 post_proc_fe->writeFile(out_name);
158 auto TestOpGradGrad = [&]() {
160 MOFEM_LOG(
"OpTester", Sev::verbose) <<
"TestOpGradGrad";
162 pip->getOpDomainLhsPipeline().clear();
163 pip->getOpDomainRhsPipeline().clear();
165 pip->setDomainLhsIntegrationRule([](
int,
int,
int o) {
return 2 * o; });
166 pip->setDomainLhsIntegrationRule([](
int,
int,
int o) {
return 2 * o; });
169 "SCALAR",
"SCALAR", [](
double,
double,
double) {
return 1; }));
171 "VECTOR",
"VECTOR", [](
double,
double,
double) {
return 1; }));
173 auto scl_mat = boost::make_shared<MatrixDouble>();
174 auto vec_mat = boost::make_shared<MatrixDouble>();
176 pip->getOpDomainRhsPipeline().push_back(
178 pip->getOpDomainRhsPipeline().push_back(
183 "SCALAR", scl_mat, [](
double,
double,
double) {
return 1; }));
185 "VECTOR", vec_mat, [](
double,
double,
double) {
return 1; }));
187 constexpr
double eps = 1e-6;
189 auto x = opt->setRandomFields(
simple->getDM(),
190 {{
"SCALAR", {-1, 1}}, {
"VECTOR", {-1, 1}}});
191 auto diff_x = opt->setRandomFields(
192 simple->getDM(), {{
"SCALAR", {-1, 1}}, {
"VECTOR", {-1, 1}}});
194 auto diff_res = opt->checkCentralFiniteDifference(
195 simple->getDM(),
simple->getDomainFEName(), pip->getDomainRhsFE(),
202 CHKERR VecNorm(diff_res, NORM_2, &fnorm);
203 MOFEM_LOG_C(
"OpTester", Sev::inform,
"TestOpGradGrad %3.4e", fnorm);
205 constexpr
double err = 1e-9;
208 "Norm of directional derivative too large");
216 opt->directionalCentralFiniteDifference(
221 "out_directional_directive_gradgrad.h5m");
228 auto TestOpConvection = [&]() {
230 MOFEM_LOG(
"OpTester", Sev::verbose) <<
"TestOpConvection";
232 pip->getOpDomainLhsPipeline().clear();
233 pip->getOpDomainRhsPipeline().clear();
235 pip->setDomainLhsIntegrationRule([](
int,
int,
int o) {
return 2 * o; });
236 pip->setDomainLhsIntegrationRule([](
int,
int,
int o) {
return 2 * o; });
238 auto evaluate_field = [&](
auto &pipe) {
239 auto scl_mat = boost::make_shared<MatrixDouble>();
240 auto vec_mat = boost::make_shared<MatrixDouble>();
241 auto dot_vec_vel = boost::make_shared<MatrixDouble>();
247 "VECTOR", dot_vec_vel));
248 return std::make_tuple(scl_mat, vec_mat, dot_vec_vel);
251 auto [rhs_scl_mat, rhs_vec_mat, rhs_dot_vec_vel] =
252 evaluate_field(pip->getOpDomainRhsPipeline());
253 pip->getOpDomainRhsPipeline().push_back(
255 pip->getOpDomainRhsPipeline().push_back(
259 auto [lhs_scl_mat, lhs_vec_mat, lhs_dot_vec_vel] =
260 evaluate_field(pip->getOpDomainLhsPipeline());
264 auto op_convective_term_lhs_du_scalar =
266 op_convective_term_lhs_du_scalar->feScalingFun =
267 [](
const FEMethod *fe_ptr) {
return fe_ptr->ts_a; };
268 pip->getOpDomainLhsPipeline().push_back(op_convective_term_lhs_du_scalar);
269 pip->getOpDomainLhsPipeline().push_back(
272 auto op_convective_term_lhs_du_vec =
274 op_convective_term_lhs_du_vec->feScalingFun = [](
const FEMethod *fe_ptr) {
277 pip->getOpDomainLhsPipeline().push_back(op_convective_term_lhs_du_vec);
278 pip->getOpDomainLhsPipeline().push_back(
282 constexpr
double eps = 1e-6;
284 auto x = opt->setRandomFields(
simple->getDM(),
285 {{
"SCALAR", {-1, 1}}, {
"VECTOR", {-1, 1}}});
286 auto x_t = opt->setRandomFields(
287 simple->getDM(), {{
"SCALAR", {-1, 1}}, {
"VECTOR", {-1, 1}}});
288 auto diff_x = opt->setRandomFields(
289 simple->getDM(), {{
"SCALAR", {-1, 1}}, {
"VECTOR", {-1, 1}}});
291 auto diff_res = opt->checkCentralFiniteDifference(
292 simple->getDM(),
simple->getDomainFEName(), pip->getDomainRhsFE(),
299 CHKERR VecNorm(diff_res, NORM_2, &fnorm);
300 MOFEM_LOG_C(
"OpTester", Sev::inform,
"TestOpConvection %3.4e", fnorm);
302 constexpr
double err = 1e-9;
305 "Norm of directional derivative too large");
314 opt->directionalCentralFiniteDifference(
316 pip->getDomainRhsFE(), x, x_t,
319 "out_directional_directive_convection.h5m");
326 CHKERR TestOpConvection();