184 {
185
187
188 auto core_log = logging::core::get();
189 core_log->add_sink(
192 BOOST_LOG_SCOPED_THREAD_ATTR("Timeline", attrs::timer());
194
195 try {
196
197 auto print_ddg = [](
auto &
t,
auto str =
"") {
198 constexpr double eps = 1e-6;
199 for (int ii = 0; ii != 3; ++ii)
200 for (int jj = 0; jj != 3; ++jj)
201 for (int kk = 0; kk != 3; ++kk)
202 for (int ll = 0; ll != 3; ++ll) {
203 double v =
t(ii, jj, kk, ll);
204 double w = std::abs(
v) <
eps ? 0 :
v;
206 << str << std::fixed << std::setprecision(3) << std::showpos
207 << ii + 1 << " " << jj + 1 << " " << kk + 1 << " " << ll + 1
209 }
210 };
211
212 auto print_ddg_direction = [](
auto &
t,
auto kk,
int ll) {
213 for (int ii = 0; ii != 3; ++ii)
214 for (int jj = 0; jj <= ii; ++jj)
216 << ii + 1 << " " << jj + 1 << " " << kk + 1 << " " << ll + 1
217 <<
" : " <<
t(ii, jj, kk, ll);
218 };
219
221 for (int ii = 0; ii != 3; ++ii)
222 for (int jj = 0; jj != 3; ++jj)
224 << ii + 1 <<
" " << jj + 1 <<
" : " <<
t(ii, jj);
225 };
226
227 enum swap { swap12, swap01 };
228 auto run_lapack = [](
auto &
a, swap s = swap12) {
229 int info;
230 double wkopt;
232
234
236
238
240
241
242 int lwork = -1;
243 info =
lapack_dsyev(
'V',
'U', 3,
a.data(), 3, w, &wkopt, lwork);
244 if (info > 0)
245 THROW_MESSAGE(
"The algorithm failed to compute eigenvalues.");
247 std::vector<double> work(lwork);
248
249 info =
lapack_dsyev(
'V',
'U', 3,
a.data(), 3, w, &*work.begin(), lwork);
250 if (info > 0)
251 THROW_MESSAGE(
"The algorithm failed to compute eigenvalues.");
252
253 if (s == swap12) {
255
256 a[0 * 3 + 0],
a[0 * 3 + 1],
a[0 * 3 + 2],
257
258 a[2 * 3 + 0],
a[2 * 3 + 1],
a[2 * 3 + 2],
259
260 a[1 * 3 + 0],
a[1 * 3 + 1],
a[1 * 3 + 2]};
261
263 return std::make_tuple(t_a, t_eig_vec, t_eig_vals);
264 }
265
267
268 a[1 * 3 + 0],
a[1 * 3 + 1],
a[1 * 3 + 2],
269
270 a[0 * 3 + 0],
a[0 * 3 + 1],
a[0 * 3 + 2],
271
272 a[2 * 3 + 0],
a[2 * 3 + 1],
a[2 * 3 + 2],
273
274 };
275
277 return std::make_tuple(t_a, t_eig_vec, t_eig_vals);
278 };
279
280
281 {
283
284 1., 0.1, -0.5,
285
286 0.1, 2., 0.,
287
288 -0.5, 0., 3.};
289
291
292 0.969837, -0.0860972, 0.228042,
293
294 0.0790574, 0.996073, 0.0398449,
295
296 -0.230577, -0.0206147, 0.972836};
297
299
301
302 1., 0., 0.,
303
304 0., 1., 0.,
305
306 0., 0., 1.};
307
309 t_S_sym(
i,
j) = (t_S(
i,
j) || t_S(
j,
i)) / 2.;
310
311 MOFEM_LOG(
"ATOM_TEST", Sev::verbose) <<
"Diff A";
313
314
315 {
316 auto f = [](
double v) {
return exp(
v); };
317 auto d_f = [](
double v) {
return exp(
v); };
318 auto dd_f = [](
double v) {
return exp(
v); };
319
321 MOFEM_LOG(
"ATOM_TEST", Sev::verbose) <<
"Reconstruct mat";
323
325
326 MOFEM_LOG(
"ATOM_TEST", Sev::verbose) <<
"Diff";
327 print_ddg_direction(t_d, 0, 2);
328
329 auto t_dd =
331
332 MOFEM_LOG(
"ATOM_TEST", Sev::verbose) <<
"Diff Diff";
333 print_ddg_direction(t_dd, 0, 2);
334
335 auto norm2_t_b = t_b(
i,
j) * t_b(
i,
j);
336 MOFEM_LOG(
"ATOM_TEST", Sev::inform) <<
"norm2_t_b " << norm2_t_b;
337
339 MOFEM_LOG(
"ATOM_TEST", Sev::inform) <<
"norm2_t_d " << norm2_t_d;
340
342 MOFEM_LOG(
"ATOM_TEST", Sev::inform) <<
"norm2_t_dd " << norm2_t_dd;
343
344 constexpr double regression_t_b = 572.543;
345 constexpr double regression_t_d = 859.939;
346 constexpr double regression_t_dd = 859.939;
347
348 constexpr double eps = 1e-2;
349 if (std::abs(norm2_t_b - regression_t_b) >
eps)
351 if (std::abs(norm2_t_d - regression_t_d) >
eps)
353 if (std::abs(norm2_t_dd - regression_t_dd) >
eps)
355 }
356
357
358
359
360
361 {
362
363 std::array<double, 9>
a{1., 0.1, -0.5,
364
365 0.1, 2., 0.,
366
367 -0.5, 0., 3.};
368
369 auto tuple = run_lapack(
a);
370
371 auto &t_eig_vec = std::get<1>(tuple);
372 auto &t_eig_vals = std::get<2>(tuple);
373
374 std::array<double, 3> sorted_reference_eigenvalues{
375 t_L(0), t_L(1), t_L(2)};
376 std::array<double, 3> sorted_lapack_eigenvalues{
377 t_eig_vals(0), t_eig_vals(1), t_eig_vals(2)};
378 std::sort(sorted_reference_eigenvalues.begin(),
379 sorted_reference_eigenvalues.end());
380 std::sort(sorted_lapack_eigenvalues.begin(),
381 sorted_lapack_eigenvalues.end());
382
383 double t_eig_val_diff = 0;
384 for (int ii = 0; ii != 3; ++ii)
385 t_eig_val_diff += std::pow(sorted_lapack_eigenvalues[ii] -
386 sorted_reference_eigenvalues[ii],
387 2);
389 << "Sorted eigenvalue difference " << t_eig_val_diff;
390
391 auto f = [](
double v) {
return exp(
v); };
392
395 t_c(
i,
j) -= t_b(
i,
j);
397
398 auto norm2_t_c = t_c(
i,
j) * t_c(
i,
j);
400 << "Reconstruct mat difference with LAPACK eigenvalues and "
401 "vectors "
402 << norm2_t_c;
403
404 constexpr double eps = 1e-8;
405 if (fabs(norm2_t_c) >
eps)
407 "Matrix not reconstructed");
408 }
409
413
414
415 {
416 auto f = [](
double v) {
return v; };
417 auto d_f = [](
double v) {
return 1; };
418 auto dd_f = [](
double v) {
return 0; };
419
420 constexpr double eps = 1e-10;
421 {
423 t_b(
i,
j) -= (t_A(
i,
j) || t_A(
j,
i)) / 2;
424 auto norm2_t_b = t_b(
i,
j) * t_b(
i,
j);
426 << "Result should be matrix itself " << norm2_t_b;
429 "This norm should be zero");
430 }
431
432 {
433
436
437 MOFEM_LOG(
"ATOM_TEST", Sev::verbose) <<
"t_d_a";
438 print_ddg(t_d_a, "hand ");
439 MOFEM_LOG(
"ATOM_TEST", Sev::verbose) <<
"t_d";
440 print_ddg(t_d, "code ");
441
444 << "Derivative hand calculation minus code " << nrm2_t_d_a;
445 if (nrm2_t_d_a >
eps)
447 "This norm should be zero");
448 }
449
450 {
452
453 1., 0., 0.,
454
455 0., 1., 0.,
456
457 0., 0., 1.};
458
460 t_S_sym(
i,
j) = t_S(
i,
j) || t_S(
j,
i);
461
462 auto t_dd =
464
466 MOFEM_LOG(
"ATOM_TEST", Sev::inform) <<
"norm2_t_dd " << norm2_t_dd;
467 if (norm2_t_dd >
eps)
469 "This norm should be zero");
470 }
471 }
472
473
474 {
475 auto f = [](
double v) {
return v *
v; };
476 auto d_f = [](
double v) {
return 2 *
v; };
477 auto dd_f = [](
double v) {
return 2; };
478
479 constexpr double eps = 1e-9;
480
481
482 {
485 t_a(
i,
j) = t_b(
i,
j) - t_A(
i,
k) * t_A(
k,
j);
487 auto norm2_t_a = t_a(
i,
j) * t_a(
i,
j);
489 << "Result should be matrix times matrix " << norm2_t_a;
492 "This norm should be zero");
493 }
494
495
496 {
498 print_ddg_direction(t_d, 0, 2);
500 MOFEM_LOG(
"ATOM_TEST", Sev::verbose) <<
"t_d_a";
501 print_ddg(t_d_a, "hand ");
502 MOFEM_LOG(
"ATOM_TEST", Sev::verbose) <<
"t_d";
503 print_ddg(t_d, "code ");
506 << "Derivative hand calculation minus code " << nrm2_t_d_a;
507 if (nrm2_t_d_a >
eps)
509 "This norm should be zero");
510 }
511
512
513 {
515
516 1., 1. / 2., 1. / 3.,
517
518 2. / 2., 1., 2. / 3.,
519
520 3. / 2., 1., 3. / 3.};
521
523 t_S_sym(
i,
j) = t_S(
i,
j) || t_S(
j,
i);
524
525 auto t_dd =
528
529 MOFEM_LOG(
"ATOM_TEST", Sev::verbose) <<
"t_dd_a";
530 print_ddg(t_dd_a, "hand ");
531 MOFEM_LOG(
"ATOM_TEST", Sev::verbose) <<
"t_dd";
532 print_ddg(t_dd, "code ");
533
536 << "Derivative hand calculation minus code " << nrm2_t_dd_a;
537 if (nrm2_t_dd_a >
eps)
539 "This norm should be zero");
540 }
541 }
542 }
543
544
545 {
546
547 std::array<double, 9>
a{5., 4., 0,
548
549 4., 5, 0.,
550
551 0.0, 0., 9};
552
553 auto tuple = run_lapack(
a, swap01);
554 auto &t_a = std::get<0>(tuple);
555 auto &t_eig_vecs = std::get<1>(tuple);
556 auto &t_eig_vals = std::get<2>(tuple);
557
558 auto f = [](
double v) {
return v; };
559 auto d_f = [](
double v) {
return 1; };
560
561 constexpr double eps = 1e-10;
562 {
564 t_b(
i,
j) -= (t_a(
i,
j) || t_a(
j,
i)) / 2;
565 auto norm2_t_b = t_b(
i,
j) * t_b(
i,
j);
567 << "Result should be matrix itself " << norm2_t_b;
570 "This norm should be zero");
571 }
572
573 {
576 MOFEM_LOG(
"ATOM_TEST", Sev::verbose) <<
"t_d_a";
577 print_ddg(t_d_a, "hand ");
578 MOFEM_LOG(
"ATOM_TEST", Sev::verbose) <<
"t_d";
579 print_ddg(t_d, "code ");
582 << "Derivative hand calculation minus code " << nrm2_t_d_a;
583 if (nrm2_t_d_a >
eps)
585 "This norm should be zero");
586 }
587
588 {
589 auto f = [](
double v) {
return v *
v; };
590 auto d_f = [](
double v) {
return 2 *
v; };
593 MOFEM_LOG(
"ATOM_TEST", Sev::verbose) <<
"t_d_a";
594 print_ddg(t_d_a, "hand ");
595 MOFEM_LOG(
"ATOM_TEST", Sev::verbose) <<
"t_d";
596 print_ddg(t_d, "code ");
599 << "Derivative hand calculation minus code " << nrm2_t_d_a;
600 if (nrm2_t_d_a >
eps)
602 "This norm should be zero");
603 }
604 }
605
606
607 {
608
609 std::array<double, 9>
a{4., 0., 0,
610
611 0., 4., 0.,
612
613 0.0, 0., 4.};
614
615 auto f = [](
double v) {
return v; };
616 auto d_f = [](
double v) {
return 1; };
617
618 auto tuple = run_lapack(
a);
619 auto &t_a = std::get<0>(tuple);
620 auto &t_eig_vecs = std::get<1>(tuple);
621 auto &t_eig_vals = std::get<2>(tuple);
622
623 constexpr double eps = 1e-10;
624 {
626 t_b(
i,
j) -= (t_a(
i,
j) || t_a(
j,
i)) / 2;
627 auto norm2_t_b = t_b(
i,
j) * t_b(
i,
j);
629 << "Result should be matrix itself " << norm2_t_b;
632 "This norm should be zero");
633 }
634
635 {
638 MOFEM_LOG(
"ATOM_TEST", Sev::verbose) <<
"t_d_a";
639 print_ddg(t_d_a, "hand ");
640 MOFEM_LOG(
"ATOM_TEST", Sev::verbose) <<
"t_d";
641 print_ddg(t_d, "code ");
644 << "Derivative hand calculation minus code " << nrm2_t_d_a;
645 if (nrm2_t_d_a >
eps)
647 "This norm should be zero");
648 }
649
650 {
651 auto f = [](
double v) {
return v *
v; };
652 auto d_f = [](
double v) {
return 2 *
v; };
655 MOFEM_LOG(
"ATOM_TEST", Sev::verbose) <<
"t_d_a";
656 print_ddg(t_d_a, "hand ");
657 MOFEM_LOG(
"ATOM_TEST", Sev::verbose) <<
"t_d";
658 print_ddg(t_d, "code ");
661 << "Derivative hand calculation minus code " << nrm2_t_d_a;
662 if (nrm2_t_d_a >
eps)
664 "This norm should be zero");
665 }
666 }
667
668
669
670 {
671
672 std::array<double, 9>
a{0.1, 0., 0.,
673
674 0., 0.1, 0.,
675
676 0., 0., 0.1};
677
678 auto tuple = run_lapack(
a);
679
680 auto &t_eig_vecs = std::get<1>(tuple);
681 auto &t_eig_vals = std::get<2>(tuple);
682
683 t_eig_vals(0) -= 1e-5;
684 t_eig_vals(2) += 1e-5;
685
686 constexpr double eps = 1e-10;
687
688 auto f = [](
double v) {
return v; };
689 auto d_f = [](
double v) {
return 1; };
690 auto dd_f = [](
double v) {
return 0; };
691
693
694 1., 1. / 2., 1. / 3.,
695
696 2. / 2., 1., 2. / 3.,
697
698 3. / 2., 1., 3. / 3.};
699
701 t_S_sym(
i,
j) = t_S(
i,
j) || t_S(
j,
i);
702
704 dd_f, t_S_sym, 1);
705
706 MOFEM_LOG(
"ATOM_TEST", Sev::verbose) <<
"t_dd";
707 print_ddg(t_dd, "test ");
708
711 << "Second-derivative norm " << nrm2_t_dd;
714 "This norm should be zero");
715 }
716
717
718
719 {
720
721 std::array<double, 9>
a{2, 0., 0.,
722
723 0., 2, 0.,
724
725 0., 0., 2};
726
727 auto tuple = run_lapack(
a);
728
729 auto &t_eig_vecs = std::get<1>(tuple);
730 auto &t_eig_vals = std::get<2>(tuple);
731
732 constexpr double eps = 1e-10;
733
734 auto f = [](
double v) {
return v *
v; };
735 auto d_f = [](
double v) {
return 2 *
v; };
736 auto dd_f = [](
double v) {
return 2; };
738
739 1., 1. / 2., 1. / 3.,
740
741 2. / 1., 1., 2. / 3.,
742
743 3. / 1., 3. / 1., 1.};
744
746 t_S_sym(
i,
j) = t_S(
i,
j) || t_S(
j,
i);
747
749 dd_f, t_S_sym, 1);
750
751
753
756 << "Derivative hand calculation minus code " << nrm2_t_dd_a;
757 if (nrm2_t_dd_a >
eps)
759 "This norm should be zero");
760 }
761
762
763 {
764
765 std::array<double, 9>
a{5., 4., 0.,
766
767 4., 5., 0.,
768
769 0., 0., 9};
770
771 auto tuple = run_lapack(
a, swap01);
772
773 auto &t_eig_vecs = std::get<1>(tuple);
774 auto &t_eig_vals = std::get<2>(tuple);
775
776 constexpr double eps = 1e-10;
777
778 auto f = [](
double v) {
return v *
v; };
779 auto d_f = [](
double v) {
return 2 *
v; };
780 auto dd_f = [](
double v) {
return 2; };
781
783
784 1., 1. / 2., 1. / 3.,
785
786 2. / 1., 1., 2. / 3.,
787
788 3. / 1., 3. / 1., 1.};
789
791 t_S_sym(
i,
j) = t_S(
i,
j) || t_S(
j,
i);
792
794 dd_f, t_S_sym, 2);
795 print_ddg(t_dd, "test ");
796
798
801 << "Derivative hand calculation minus code " << nrm2_t_dd_a;
802 if (nrm2_t_dd_a >
eps)
804 "This norm should be zero");
805 }
806
807
808 {
809
810 std::array<double, 9>
a{2, 0., 0.,
811
812 0., 2, 0.,
813
814 0., 0., 2};
815
816 auto tuple = run_lapack(
a);
817
818 auto &t_eig_vecs = std::get<1>(tuple);
819 auto &t_eig_vals = std::get<2>(tuple);
820
821 t_eig_vals(0) -= 1e-5;
822 t_eig_vals(2) += 1e-5;
823
824 constexpr double eps = 1e-7;
825
826 auto f = [](
double v) {
return exp(
v); };
827 auto d_f = [](
double v) {
return exp(
v); };
828 auto dd_f = [](
double v) {
return exp(
v); };
830
831 1., 1. / 2., 1. / 3.,
832
833 2. / 1., 1., 2. / 3.,
834
835 3. / 1., 3. / 1., 1.};
836
838 t_S_sym(
i,
j) = t_S(
i,
j) || t_S(
j,
i);
839
841 dd_f, t_S_sym, 3);
843 dd_f, t_S_sym, 1);
844
847 << "Derivative norm t_dd_1 " << nrm2_t_dd_t1;
848
851 << "Derivative norm t_dd_2 " << nrm2_t_dd_t2;
852
853 print_ddg(t_dd_1, "t_dd_1 ");
854 print_ddg(t_dd_2, "t_dd_2 ");
855
857 t_dd_3(
i,
j,
k,
l) = t_dd_1(
i,
j,
k,
l) - t_dd_2(
i,
j,
k,
l);
858
859 for (int ii = 0; ii != 3; ++ii)
860 for (int jj = 0; jj != 3; ++jj)
861 for (int kk = 0; kk != 3; ++kk)
862 for (int ll = 0; ll != 3; ++ll) {
863 constexpr double eps = 1e-4;
864 if (std::abs(t_dd_3(ii, jj, kk, ll)) >
eps)
866 << "Error " << ii << " " << jj << " " << kk << " " << ll
867 << " " << t_dd_1(ii, jj, kk, ll) << " "
868 << t_dd_2(ii, jj, kk, ll);
869 }
870
873 << "Derivative branch difference " << nrm2_t_dd_3;
874 if (nrm2_t_dd_3 >
eps)
876 "This norm should be zero");
877 }
878
879
880
881 {
882
883 std::array<double, 9>
a{5., 4., 0.,
884
885 4., 5., 0.,
886
887 0., 0., 9};
888
889 auto tuple = run_lapack(
a, swap01);
890
891 auto &t_eig_vecs = std::get<1>(tuple);
892 auto &t_eig_vals = std::get<2>(tuple);
893
894 t_eig_vals(0) -= 1e-4;
895 t_eig_vals(2) += 1e-4;
896
897 constexpr double eps = 1e-4;
898
899 auto f = [](
double v) {
return v *
v; };
900 auto d_f = [](
double v) {
return 2 *
v; };
901 auto dd_f = [](
double v) {
return 2; };
902
904
905 1., 1. / 2., 1. / 3.,
906
907 2. / 1., 1., 2. / 3.,
908
909 3. / 1., 3. / 1., 1.};
910
912 t_S_sym(
i,
j) = t_S(
i,
j) || t_S(
j,
i);
913
915 dd_f, t_S_sym, 3);
917 dd_f, t_S_sym, 2);
918
921 << "Derivative norm t_dd_1 " << nrm2_t_dd_t1;
922
925 << "Derivative norm t_dd_2 " << nrm2_t_dd_t2;
926
927 print_ddg(t_dd_1, "t_dd_1 ");
928 print_ddg(t_dd_2, "t_dd_2 ");
929
931 t_dd_3(
i,
j,
k,
l) = t_dd_1(
i,
j,
k,
l) - t_dd_2(
i,
j,
k,
l);
932
933 for (int ii = 0; ii != 3; ++ii)
934 for (int jj = 0; jj != 3; ++jj)
935 for (int kk = 0; kk != 3; ++kk)
936 for (int ll = 0; ll != 3; ++ll) {
937 constexpr double eps = 1e-3;
938 if (std::abs(t_dd_3(ii, jj, kk, ll)) >
eps)
940 << "Error " << ii << " " << jj << " " << kk << " " << ll
941 << " " << t_dd_1(ii, jj, kk, ll) << " "
942 << t_dd_2(ii, jj, kk, ll);
943 }
944
947 << "Derivative branch difference " << nrm2_t_dd_3;
948 if (nrm2_t_dd_3 >
eps)
950 "This norm should be zero");
951 }
952
953
954
955 {
956
957 std::array<double, 9>
a{5., 4., 0.,
958
959 4., 5., 0.,
960
961 0., 0., 9};
962
963 auto tuple = run_lapack(
a, swap01);
964
965 auto &t_eig_vecs = std::get<1>(tuple);
966 auto &t_eig_vals = std::get<2>(tuple);
967
968 constexpr double eps = 1e-4;
969 constexpr int p = 3;
970
971 auto f = [](
double v) {
return pow(
v, p); };
972 auto d_f = [](
double v) {
return p * pow(
v, p - 1); };
973 auto dd_f = [](
double v) {
974 return p * (p - 1) * pow(
v, std::max(0, p - 2));
975 };
976
978
979 1., 1. / 2., 1. / 3.,
980
981 2. / 1., 1., 2. / 3.,
982
983 3. / 1., 3. / 1., 1.};
984
985
986
987
988 t_eig_vals(0) += 2e-5;
989 t_eig_vals(2) -= 2e-5;
991 dd_f, t_S, 3);
993 dd_f, t_S, 2);
994
997 << "Derivative norm t_dd_1 " << nrm2_t_dd_t1;
998
1001 << "Derivative norm t_dd_2 " << nrm2_t_dd_t2;
1002
1003 print_ddg(t_dd_1, "t_dd_1 ");
1004 print_ddg(t_dd_2, "t_dd_2 ");
1005
1007 t_dd_3(
i,
j,
k,
l) = t_dd_1(
i,
j,
k,
l) - t_dd_2(
i,
j,
k,
l);
1008
1009 for (int ii = 0; ii != 3; ++ii)
1010 for (int jj = 0; jj != 3; ++jj)
1011 for (int kk = 0; kk != 3; ++kk)
1012 for (int ll = 0; ll != 3; ++ll) {
1013 constexpr double eps = 1e-3;
1014 if (std::abs(t_dd_3(ii, jj, kk, ll)) >
eps)
1016 << "Error " << ii << " " << jj << " " << kk << " " << ll
1017 << " " << t_dd_1(ii, jj, kk, ll) << " "
1018 << t_dd_2(ii, jj, kk, ll) << " " << t_dd_3(ii, jj, kk, ll);
1019 }
1020
1023 << "Derivative branch difference " << nrm2_t_dd_3;
1024 if (nrm2_t_dd_3 >
eps)
1026 "This norm should be zero");
1027 }
1028
1029
1030 {
1031
1032 std::array<double, 9>
a{1., 0.1, -0.5,
1033
1034 0.1, 2., 0.,
1035
1036 -0.5, 0., 3.};
1037
1038 auto tuple = run_lapack(
a);
1039
1040 auto &t_eig_vecs = std::get<1>(tuple);
1041 auto &t_eig_vals = std::get<2>(tuple);
1042
1043 auto f = [](
double v) {
return exp(
v); };
1044 auto d_f = [](
double v) {
return exp(
v); };
1045 auto dd_f = [](
double v) {
return exp(
v); };
1046
1048
1049 1., 1. / 2., 1. / 3.,
1050
1051 2. / 1., 1., 2. / 3.,
1052
1053 3. / 1., 3. / 1., 1.};
1054
1056 t_S_sym(
i,
j) = t_S(
i,
j) || t_S(
j,
i);
1057
1058 MOFEM_LOG(
"ATOM_TEST", Sev::inform) <<
"Start";
1059 for (int ii = 0; ii != 1000; ++ii) {
1062 dd_f, t_S_sym, 3);
1063 std::ignore = t_d;
1064 std::ignore = t_dd;
1065 }
1066 MOFEM_LOG(
"ATOM_TEST", Sev::inform) <<
"End";
1067 }
1068
1069
1070
1071 auto run_lapack_2d = [](
auto &
a) {
1072 int info;
1073 double wkopt;
1075
1077
1079
1081
1082
1083 int lwork = -1;
1084 info =
lapack_dsyev(
'V',
'U', 2,
a.data(), 2, w, &wkopt, lwork);
1085 if (info > 0)
1086 THROW_MESSAGE(
"The algorithm failed to compute eigenvalues.");
1088 std::vector<double> work(lwork);
1089
1090 info =
lapack_dsyev(
'V',
'U', 2,
a.data(), 2, w, &*work.begin(), lwork);
1091 if (info > 0)
1092 THROW_MESSAGE(
"The algorithm failed to compute eigenvalues.");
1093
1095
1096 a[0 * 2 + 0],
a[0 * 2 + 1],
1097
1098 a[1 * 2 + 0],
a[1 * 2 + 1]};
1099
1101
1102 return std::make_tuple(t_a, t_eig_vecs, t_eig_vals);
1103 };
1104
1105
1106 {
1107
1108 std::array<double, 9>
a{1., 0.1,
1109
1110 0.1, 2.};
1111
1112 auto tuple = run_lapack_2d(
a);
1113 auto &t_A = std::get<0>(tuple);
1114 auto &t_eig_vecs = std::get<1>(tuple);
1115 auto &t_eig_vals = std::get<2>(tuple);
1116
1117 auto f = [](
double v) {
return v *
v; };
1118 auto d_f = [](
double v) {
return 2 *
v; };
1119 auto dd_f = [](
double v) {
return 2; };
1120
1121 constexpr double eps = 1e-6;
1122
1127
1128
1129 {
1132 t_a(
i,
j) = t_b(
i,
j) - t_A(
i,
k) * t_A(
k,
j);
1134 auto norm2_t_a = t_a(
i,
j) * t_a(
i,
j);
1136 << "Result should be matrix times matrix " << norm2_t_a;
1137 if (norm2_t_a >
eps)
1139 "This norm should be zero");
1140 }
1141
1142
1143 {
1148 << "Derivative hand calculation minus code " << nrm2_t_d_a;
1149 if (nrm2_t_d_a >
eps)
1151 "This norm should be zero");
1152 }
1153
1154
1155 {
1157
1158 1., 1. / 2,
1159
1160 2. / 2., 1.};
1161
1162
1163
1164
1165
1166
1168 dd_f, t_S, 2);
1170
1171 MOFEM_LOG(
"ATOM_TEST", Sev::verbose) <<
"t_dd_a";
1172 MOFEM_LOG(
"ATOM_TEST", Sev::verbose) <<
"t_dd";
1173
1176 << "Derivative hand calculation minus code " << nrm2_t_dd_a;
1177 if (nrm2_t_dd_a >
eps)
1179 "This norm should be zero");
1180 }
1181 }
1182
1183
1184 {
1185
1186 std::array<double, 9>
a{2., 0,
1187
1188 0, 2.};
1189
1190 auto tuple = run_lapack_2d(
a);
1191 auto &t_A = std::get<0>(tuple);
1192 auto &t_eig_vecs = std::get<1>(tuple);
1193 auto &t_eig_vals = std::get<2>(tuple);
1194
1195 auto f = [](
double v) {
return v *
v; };
1196 auto d_f = [](
double v) {
return 2 *
v; };
1197 auto dd_f = [](
double v) {
return 2; };
1198
1199 constexpr double eps = 1e-6;
1200
1205
1206
1207 {
1210 t_a(
i,
j) = t_b(
i,
j) - t_A(
i,
k) * t_A(
k,
j);
1212 auto norm2_t_a = t_a(
i,
j) * t_a(
i,
j);
1214 << "Result should be matrix times matrix " << norm2_t_a;
1215 if (norm2_t_a >
eps)
1217 "This norm should be zero");
1218 }
1219
1220
1221 {
1226 << "Derivative hand calculation minus code " << nrm2_t_d_a;
1227 if (nrm2_t_d_a >
eps)
1229 "This norm should be zero");
1230 }
1231
1232
1233 {
1235
1236 1., 1. / 2,
1237
1238 2. / 2., 1.};
1239
1243 t_S_sym(
i,
j) = t_S(
i,
j) || t_S(
j,
i);
1244
1246 dd_f, t_S_sym, 1);
1248
1249 MOFEM_LOG(
"ATOM_TEST", Sev::verbose) <<
"t_dd_a";
1250 MOFEM_LOG(
"ATOM_TEST", Sev::verbose) <<
"t_dd";
1251
1254 << "Derivative hand calculation minus code " << nrm2_t_dd_a;
1255 if (nrm2_t_dd_a >
eps)
1257 "This norm should be zero");
1258 }
1259 }
1260 }
1262
1264}
Kronecker Delta class symmetric.
#define CATCH_ERRORS
Catch errors.
@ MOFEM_ATOM_TEST_INVALID
#define CHKERR
Inline error check.
#define THROW_MESSAGE(msg)
Throw MoFEM exception.
static LoggerType & setLog(const std::string channel)
Set ans resset chanel logger.
#define MOFEM_LOG_ATTRIBUTES(channel, bit)
Add attributes to channel.
const double v
phase velocity of light in medium (cm/ns)
static __CLPK_integer lapack_dsyev(char jobz, char uplo, __CLPK_integer n, __CLPK_doublereal *a, __CLPK_integer lda, __CLPK_doublereal *w, __CLPK_doublereal *work, __CLPK_integer lwork)
auto get_diff_matrix(T1 &t_d, const FTensor::Number< DIM > &)
auto get_diff2_matrix2(T1 &t_s, T2 &t_dd, const FTensor::Number< DIM > &)
auto get_norm_t4(T &t, const FTensor::Number< DIM > &)
auto get_diff_matrix2(T1 &t_a, T2 &t_d, const FTensor::Number< DIM > &)
auto getMat(A &&t_val, B &&t_vec, Fun< double > f)
Get the Mat object.
auto getDiffMat(A &&t_val, B &&t_vec, Fun< double > f, Fun< double > d_f, const int nb)
Get the Diff Mat object.
auto getDiffDiffMat(A &&t_val, B &&t_vec, Fun< double > f, Fun< double > d_f, Fun< double > dd_f, C &&t_S, const int nb)
Get the Diff Diff Mat object.
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
static boost::shared_ptr< SinkType > createSink(boost::shared_ptr< std::ostream > stream_ptr, std::string comm_filter)
Create a sink object.
static boost::shared_ptr< std::ostream > getStrmSelf()
Get the strm self object.