This is used to check consistency of code. If problem is notices with additional non-zero elements in matrix, this function can help detect problem. Should be used as a part of atom tests
889 {
892
894
895 struct TestMatrixFillIn :
public FEMethod {
896 CoreInterface *mFieldPtr;
897
899
900 int rowPrint, colPrint;
901
902 TestMatrixFillIn(CoreInterface *m_field_ptr, Mat
a,
int row_print,
903 int col_print)
904 : mFieldPtr(m_field_ptr),
A(
a), rowPrint(row_print),
905 colPrint(col_print){};
906
910 }
911
914
915 if (refinedFiniteElementsPtr->find(
916 numeredEntFiniteElementPtr->getEnt()) ==
917 refinedFiniteElementsPtr->end()) {
919 "data inconsistency");
920 }
921
922 auto row_dofs = getRowDofsPtr();
923 auto col_dofs = getColDofsPtr();
924
925 for (auto cit = col_dofs->begin(); cit != col_dofs->end(); cit++) {
926
927 if (refinedEntitiesPtr->find((*cit)->getEnt()) ==
928 refinedEntitiesPtr->end()) {
930 "data inconsistency");
931 }
932 if (!(*cit)->getActive()) {
934 "data inconsistency");
935 }
936
937 FieldEntityEntFiniteElementAdjacencyMap_multiIndex::index<
938 Composite_Unique_mi_tag>::type::iterator ait;
939 ait = adjacenciesPtr->get<Composite_Unique_mi_tag>().find(
940 boost::make_tuple((*cit)->getFieldEntityPtr()->getLocalUniqueId(),
941 numeredEntFiniteElementPtr->getLocalUniqueId()));
942 if (ait == adjacenciesPtr->end()) {
944 "adjacencies data inconsistency");
945 } else {
946 UId uid = ait->getEntUniqueId();
947 if (entitiesPtr->find(uid) == entitiesPtr->end()) {
949 "data inconsistency");
950 }
951 if (dofsPtr->find((*cit)->getLocalUniqueId()) == dofsPtr->end()) {
953 "data inconsistency");
954 }
955 }
956
957 if ((*cit)->getEntType() != MBVERTEX) {
958
959 auto range =
960 col_dofs->get<Ent_mi_tag>().equal_range((*cit)->getEnt());
961 int nb_dofs_on_ent = std::distance(range.first, range.second);
962
963 int max_order = (*cit)->getMaxOrder();
964 if ((*cit)->getNbOfCoeffs() * (*cit)->getOrderNbDofs(max_order) !=
965 nb_dofs_on_ent) {
966
967
968
969
970
972 << "Warning: Number of Dofs in Col different than number "
973 "of dofs for given entity order "
974 << (*cit)->getNbOfCoeffs() * (*cit)->getOrderNbDofs(max_order)
975 << " " << nb_dofs_on_ent;
976 }
977 }
978 }
979
980 for (auto rit = row_dofs->begin(); rit != row_dofs->end(); rit++) {
981
982 if (refinedEntitiesPtr->find((*rit)->getEnt()) ==
983 refinedEntitiesPtr->end()) {
985 "data inconsistency");
986 }
987 if (!(*rit)->getActive()) {
989 "data inconsistency");
990 }
991
992 FieldEntityEntFiniteElementAdjacencyMap_multiIndex::index<
993 Composite_Unique_mi_tag>::type::iterator ait;
994 ait = adjacenciesPtr->get<Composite_Unique_mi_tag>().find(
995 boost::make_tuple((*rit)->getFieldEntityPtr()->getLocalUniqueId(),
996 numeredEntFiniteElementPtr->getLocalUniqueId()));
997 if (ait == adjacenciesPtr->end()) {
999 MOFEM_LOG(
"SELF", Sev::error) << *(*rit);
1000 MOFEM_LOG(
"SELF", Sev::error) << *(*rit);
1001 MOFEM_LOG(
"SELF", Sev::error) << *numeredEntFiniteElementPtr;
1002 MOFEM_LOG(
"SELF", Sev::error) <<
"dof: " << (*rit)->getBitRefLevel();
1004 << "fe: " << numeredEntFiniteElementPtr->getBitRefLevel();
1006 << "problem: " << problemPtr->getBitRefLevel();
1008 << "problem mask: " << problemPtr->getBitRefLevelMask();
1010 "adjacencies data inconsistency");
1011 } else {
1012 UId uid = ait->getEntUniqueId();
1013 if (entitiesPtr->find(uid) == entitiesPtr->end()) {
1015 "data inconsistency");
1016 }
1017 if (dofsPtr->find((*rit)->getLocalUniqueId()) == dofsPtr->end()) {
1019 "data inconsistency");
1020 }
1021 }
1022 int row = (*rit)->getPetscGlobalDofIdx();
1023
1024 auto col_dofs = getColDofsPtr();
1025 for (auto cit = col_dofs->begin(); cit != col_dofs->end(); cit++) {
1026
1027 int col = (*cit)->getPetscGlobalDofIdx();
1028
1029 if (row == rowPrint && col == colPrint) {
1030 MOFEM_LOG(
"SELF", Sev::noisy) <<
"fe:\n"
1031 << *numeredEntFiniteElementPtr;
1032 MOFEM_LOG(
"SELF", Sev::noisy) <<
"row:\n" << *(*rit);
1033 MOFEM_LOG(
"SELF", Sev::noisy) <<
"col:\n" << *(*cit);
1035 << "fe:\n"
1036 << numeredEntFiniteElementPtr->getBitRefLevel();
1037 MOFEM_LOG(
"SELF", Sev::noisy) <<
"row:\n"
1038 << (*rit)->getBitRefLevel();
1039 MOFEM_LOG(
"SELF", Sev::noisy) <<
"col:\n"
1040 << (*cit)->getBitRefLevel();
1041 }
1042
1043 CHKERR MatSetValue(
A, row, col, 1, INSERT_VALUES);
1044 }
1045
1046 if ((*rit)->getEntType() != MBVERTEX) {
1047
1048 auto range =
1049 row_dofs->get<Ent_mi_tag>().equal_range((*rit)->getEnt());
1050 int nb_dofs_on_ent = std::distance(range.first, range.second);
1051
1052 int max_order = (*rit)->getMaxOrder();
1053 if ((*rit)->getNbOfCoeffs() * (*rit)->getOrderNbDofs(max_order) !=
1054 nb_dofs_on_ent) {
1055
1056
1057
1058
1059
1061 << "Warning: Number of Dofs in Row different than number "
1062 "of dofs for given entity order "
1063 << (*rit)->getNbOfCoeffs() * (*rit)->getOrderNbDofs(max_order)
1064 << " " << nb_dofs_on_ent;
1065 }
1066 }
1067 }
1068
1070 }
1071
1074
1075
1076 CHKERR MatAssemblyBegin(
A, MAT_FLUSH_ASSEMBLY);
1077 CHKERR MatAssemblyEnd(
A, MAT_FLUSH_ASSEMBLY);
1078
1080 }
1081 };
1082
1083
1084 CHKERR MatSetOption(
A, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE);
1085
1087 MatView(
A, PETSC_VIEWER_STDOUT_WORLD);
1088 }
1089
1090 if (verb >=
NOISY) {
1091 MatView(
A, PETSC_VIEWER_DRAW_WORLD);
1092 std::string wait;
1093 std::cin >> wait;
1094 }
1095
1096 TestMatrixFillIn method(&m_field,
A, row_print, col_print);
1097
1098
1100 auto &prb_set = problems_ptr->get<Problem_mi_tag>();
1101 auto p_miit = prb_set.find(problem_name);
1102 if (p_miit == prb_set.end())
1104 "problem < %s > not found (top tip: check spelling)",
1105 problem_name.c_str());
1106 MOFEM_LOG_C(
"WORLD", Sev::inform,
"check problem < %s >",
1107 problem_name.c_str());
1108
1109
1111 for (auto &fe : *fe_ptr) {
1112 MOFEM_LOG_C(
"WORLD", Sev::verbose,
"\tcheck element %s",
1113 fe->getName().c_str());
1117 }
1118
1119 CHKERR MatAssemblyBegin(
A, MAT_FINAL_ASSEMBLY);
1120 CHKERR MatAssemblyEnd(
A, MAT_FINAL_ASSEMBLY);
1121
1123
1125}
#define MOFEM_LOG_C(channel, severity, format,...)
#define MatrixManagerFunctionBegin
Create adjacent matrices using different indices.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
virtual const FiniteElement_multiIndex * get_finite_elements() const =0
Get the finite elements object.
virtual const Problem_multiIndex * get_problems() const =0
Get the problems object.
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_ATTRIBUTES(channel, bit)
Add attributes to channel.
virtual MoFEMErrorCode loop_finite_elements(const std::string problem_name, const std::string &fe_name, FEMethod &method, boost::shared_ptr< NumeredEntFiniteElement_multiIndex > fe_ptr=nullptr, MoFEMTypes bh=MF_EXIST, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr(), int verb=DEFAULT_VERBOSITY)=0
Make a loop over finite elements.
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
boost::shared_ptr< CacheTuple > CacheTupleSharedPtr
virtual MPI_Comm & get_comm() const =0