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
901 {
904
906
907 struct TestMatrixFillIn :
public FEMethod {
908 CoreInterface *mFieldPtr;
909
911
912 int rowPrint, colPrint;
913
914 TestMatrixFillIn(CoreInterface *m_field_ptr, Mat
a,
int row_print,
915 int col_print)
916 : mFieldPtr(m_field_ptr), A(
a), rowPrint(row_print),
917 colPrint(col_print){};
918
922 }
923
926
927 if (refinedFiniteElementsPtr->find(
928 numeredEntFiniteElementPtr->getEnt()) ==
929 refinedFiniteElementsPtr->end()) {
931 "data inconsistency");
932 }
933
934 auto row_dofs = getRowDofsPtr();
935 auto col_dofs = getColDofsPtr();
936
937 for (auto cit = col_dofs->begin(); cit != col_dofs->end(); cit++) {
938
939 if (refinedEntitiesPtr->find((*cit)->getEnt()) ==
940 refinedEntitiesPtr->end()) {
942 "data inconsistency");
943 }
944 if (!(*cit)->getActive()) {
946 "data inconsistency");
947 }
948
949 FieldEntityEntFiniteElementAdjacencyMap_multiIndex::index<
950 Composite_Unique_mi_tag>::type::iterator ait;
951 ait = adjacenciesPtr->get<Composite_Unique_mi_tag>().find(
952 boost::make_tuple((*cit)->getFieldEntityPtr()->getLocalUniqueId(),
953 numeredEntFiniteElementPtr->getLocalUniqueId()));
954 if (ait == adjacenciesPtr->end()) {
956 "adjacencies data inconsistency");
957 } else {
958 UId uid = ait->getEntUniqueId();
959 if (entitiesPtr->find(uid) == entitiesPtr->end()) {
961 "data inconsistency");
962 }
963 if (dofsPtr->find((*cit)->getLocalUniqueId()) == dofsPtr->end()) {
965 "data inconsistency");
966 }
967 }
968
969 if ((*cit)->getEntType() != MBVERTEX) {
970
971 auto range =
972 col_dofs->get<Ent_mi_tag>().equal_range((*cit)->getEnt());
973 int nb_dofs_on_ent = std::distance(range.first, range.second);
974
975 int max_order = (*cit)->getMaxOrder();
976 if ((*cit)->getNbOfCoeffs() * (*cit)->getOrderNbDofs(max_order) !=
977 nb_dofs_on_ent) {
978
979
980
981
982
984 << "Warning: Number of Dofs in Col different than number "
985 "of dofs for given entity order "
986 << (*cit)->getNbOfCoeffs() * (*cit)->getOrderNbDofs(max_order)
987 << " " << nb_dofs_on_ent;
988 }
989 }
990 }
991
992 for (auto rit = row_dofs->begin(); rit != row_dofs->end(); rit++) {
993
994 if (refinedEntitiesPtr->find((*rit)->getEnt()) ==
995 refinedEntitiesPtr->end()) {
997 "data inconsistency");
998 }
999 if (!(*rit)->getActive()) {
1001 "data inconsistency");
1002 }
1003
1004 FieldEntityEntFiniteElementAdjacencyMap_multiIndex::index<
1005 Composite_Unique_mi_tag>::type::iterator ait;
1006 ait = adjacenciesPtr->get<Composite_Unique_mi_tag>().find(
1007 boost::make_tuple((*rit)->getFieldEntityPtr()->getLocalUniqueId(),
1008 numeredEntFiniteElementPtr->getLocalUniqueId()));
1009 if (ait == adjacenciesPtr->end()) {
1011 MOFEM_LOG(
"SELF", Sev::error) << *(*rit);
1012 MOFEM_LOG(
"SELF", Sev::error) << *(*rit);
1013 MOFEM_LOG(
"SELF", Sev::error) << *numeredEntFiniteElementPtr;
1014 MOFEM_LOG(
"SELF", Sev::error) <<
"dof: " << (*rit)->getBitRefLevel();
1016 << "fe: " << numeredEntFiniteElementPtr->getBitRefLevel();
1018 << "problem: " << problemPtr->getBitRefLevel();
1020 << "problem mask: " << problemPtr->getBitRefLevelMask();
1022 "adjacencies data inconsistency");
1023 } else {
1024 UId uid = ait->getEntUniqueId();
1025 if (entitiesPtr->find(uid) == entitiesPtr->end()) {
1027 "data inconsistency");
1028 }
1029 if (dofsPtr->find((*rit)->getLocalUniqueId()) == dofsPtr->end()) {
1031 "data inconsistency");
1032 }
1033 }
1034 int row = (*rit)->getPetscGlobalDofIdx();
1035
1036 auto col_dofs = getColDofsPtr();
1037 for (auto cit = col_dofs->begin(); cit != col_dofs->end(); cit++) {
1038
1039 int col = (*cit)->getPetscGlobalDofIdx();
1040
1041 if (row == rowPrint && col == colPrint) {
1042 MOFEM_LOG(
"SELF", Sev::noisy) <<
"fe:\n"
1043 << *numeredEntFiniteElementPtr;
1044 MOFEM_LOG(
"SELF", Sev::noisy) <<
"row:\n" << *(*rit);
1045 MOFEM_LOG(
"SELF", Sev::noisy) <<
"col:\n" << *(*cit);
1047 << "fe:\n"
1048 << numeredEntFiniteElementPtr->getBitRefLevel();
1049 MOFEM_LOG(
"SELF", Sev::noisy) <<
"row:\n"
1050 << (*rit)->getBitRefLevel();
1051 MOFEM_LOG(
"SELF", Sev::noisy) <<
"col:\n"
1052 << (*cit)->getBitRefLevel();
1053 }
1054
1055 CHKERR MatSetValue(A, row, col, 1, INSERT_VALUES);
1056 }
1057
1058 if ((*rit)->getEntType() != MBVERTEX) {
1059
1060 auto range =
1061 row_dofs->get<Ent_mi_tag>().equal_range((*rit)->getEnt());
1062 int nb_dofs_on_ent = std::distance(range.first, range.second);
1063
1064 int max_order = (*rit)->getMaxOrder();
1065 if ((*rit)->getNbOfCoeffs() * (*rit)->getOrderNbDofs(max_order) !=
1066 nb_dofs_on_ent) {
1067
1068
1069
1070
1071
1073 << "Warning: Number of Dofs in Row different than number "
1074 "of dofs for given entity order "
1075 << (*rit)->getNbOfCoeffs() * (*rit)->getOrderNbDofs(max_order)
1076 << " " << nb_dofs_on_ent;
1077 }
1078 }
1079 }
1080
1082 }
1083
1086
1087
1088 CHKERR MatAssemblyBegin(A, MAT_FLUSH_ASSEMBLY);
1089 CHKERR MatAssemblyEnd(A, MAT_FLUSH_ASSEMBLY);
1090
1092 }
1093 };
1094
1095
1096 CHKERR MatSetOption(A, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE);
1097
1099 MatView(A, PETSC_VIEWER_STDOUT_WORLD);
1100 }
1101
1102 if (verb >=
NOISY) {
1103 MatView(A, PETSC_VIEWER_DRAW_WORLD);
1104 std::string wait;
1105 std::cin >> wait;
1106 }
1107
1108 TestMatrixFillIn method(&m_field, A, row_print, col_print);
1109
1110
1112 auto &prb_set = problems_ptr->get<Problem_mi_tag>();
1113 auto p_miit = prb_set.find(problem_name);
1114 if (p_miit == prb_set.end())
1116 "problem < %s > not found (top tip: check spelling)",
1117 problem_name.c_str());
1118 MOFEM_LOG_C(
"WORLD", Sev::inform,
"check problem < %s >",
1119 problem_name.c_str());
1120
1121
1123 for (auto &fe : *fe_ptr) {
1124 MOFEM_LOG_C(
"WORLD", Sev::verbose,
"\tcheck element %s",
1125 fe->getName().c_str());
1129 }
1130
1131 CHKERR MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY);
1132 CHKERR MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY);
1133
1135
1137}
#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