27 "Assemble EP P+bubble stress diagnostics on one affine tet.\n"
28 " -diag_matrix_type gram|a00\n"
29 " -diag_include_bubble true|false\n"
30 " -diag_rank_tol <real>\n"
31 " -diag_check_full_rank true|false\n"
32 " -diag_view_matrix true|false\n"
33 " -broken_hdiv_base demkowicz|ainsworth\n\n";
42 char matrix_type[32] =
"gram";
44 matrix_type,
sizeof(matrix_type),
46 const std::string type_name(matrix_type);
48 if (type_name ==
"gram") {
50 }
else if (type_name ==
"a00") {
54 "Unknown -diag_matrix_type '%s'; use 'gram' or 'a00'",
90 double tet_coords[] = {0, 0, 0, 1.0, 0, 0,
91 0, 1.0, 0, 0, 0, 1.0};
93 for (
int nn = 0; nn < 4; nn++) {
94 CHKERR moab.create_vertex(&tet_coords[3 * nn], nodes[nn]);
98 CHKERR moab.create_element(MBTET, nodes, 4, tet);
99 CHKERR moab.create_meshset(MESHSET_SET | MESHSET_TRACK_OWNER, meshset);
103 CHKERR moab.add_entities(meshset, tets);
104 for (
int dim = 0; dim != 3; ++dim) {
106 CHKERR moab.get_adjacencies(tets, dim,
true, adj,
107 moab::Interface::UNION);
108 CHKERR moab.add_entities(meshset, adj);
118 PetscInt rows_nb, cols_nb;
119 CHKERR MatGetSize(
A, &rows_nb, &cols_nb);
120 dense.resize(rows_nb, cols_nb,
false);
123 std::vector<PetscInt> rows(rows_nb), cols(cols_nb);
124 std::iota(rows.begin(), rows.end(), 0);
125 std::iota(cols.begin(), cols.end(), 0);
127 std::vector<PetscScalar> values(rows_nb * cols_nb, 0);
128 CHKERR MatGetValues(
A, rows_nb, rows.data(), cols_nb, cols.data(),
130 for (PetscInt rr = 0; rr != rows_nb; ++rr) {
131 for (PetscInt cc = 0; cc != cols_nb; ++cc) {
132 dense(rr, cc) = PetscRealPart(values[rr * cols_nb + cc]);
142 for (
size_t rr = 0; rr != dense.size1(); ++rr) {
143 std::ostringstream line;
144 line << std::scientific << std::setprecision(16);
145 for (
size_t cc = 0; cc != dense.size2(); ++cc) {
146 line << (cc ?
" " :
"") << dense(rr, cc);
148 MOFEM_LOG(
"EP", Sev::inform) << line.str();
155 const double rel_rank_tol,
159 rank_data.
rowsNb = dense.size1();
160 rank_data.
colsNb = dense.size2();
163 for (
size_t rr = 0; rr != rank_data.
rowsNb; ++rr) {
164 for (
size_t cc = 0; cc != rank_data.
colsNb; ++cc) {
165 const double a = dense(rr, cc);
168 const double d =
a - dense(cc, rr);
179 const bool use_row_gram = rank_data.
rowsNb <= rank_data.
colsNb;
184 for (
size_t ii = 0; ii != rank_data.
rowsNb; ++ii) {
185 for (
size_t jj = ii; jj != rank_data.
rowsNb; ++jj) {
187 for (
size_t cc = 0; cc != rank_data.
colsNb; ++cc)
188 value += dense(ii, cc) * dense(jj, cc);
189 gram(ii, jj) = value;
190 gram(jj, ii) = value;
194 for (
size_t ii = 0; ii != rank_data.
colsNb; ++ii) {
195 for (
size_t jj = ii; jj != rank_data.
colsNb; ++jj) {
197 for (
size_t rr = 0; rr != rank_data.
rowsNb; ++rr)
198 value += dense(rr, ii) * dense(rr, jj);
199 gram(ii, jj) = value;
200 gram(jj, ii) = value;
210 for (
size_t ii = 0; ii != rank_data.
maxRank; ++ii)
211 max_eig = std::max(max_eig, std::abs(eig(ii)));
212 rank_data.
maxSingular = std::sqrt(std::max(max_eig, 0.0));
214 rel_rank_tol * std::max(rank_data.
maxSingular, 1.0);
217 double min_nonzero = std::numeric_limits<double>::max();
218 for (
size_t ii = 0; ii != rank_data.
maxRank; ++ii) {
219 const double a = std::abs(eig(ii));
220 if (
a > eig_abs_tol) {
222 min_nonzero = std::min(min_nonzero, std::sqrt(
a));
233 const PetscBool include_bubble,
const double rel_rank_tol,
234 const PetscBool check_full_rank,
const PetscBool view_matrix) {
244 <<
"stress basis: " << (include_bubble ?
"P+bubble" :
"P");
247 <<
"A00 fields: u, bubble, P, omega, wL2";
250 <<
"matrix size: " << rank_data.
rowsNb <<
" x " << rank_data.
colsNb;
252 << std::scientific << std::setprecision(16)
256 << std::scientific << std::setprecision(16)
260 << std::scientific << std::setprecision(16)
261 <<
"relative rank tolerance: " << rel_rank_tol;
263 << std::scientific << std::setprecision(16)
264 <<
"absolute singular tolerance: " << rank_data.
absRankTol;
266 << std::scientific << std::setprecision(16)
270 <<
"numerical rank: " << rank_data.
rank <<
" / " << rank_data.
maxRank;
273 MOFEM_LOG(
"EP", Sev::inform) <<
"dense diagnostic matrix:";
277 if (check_full_rank && rank_data.
rank != rank_data.
maxRank) {
279 "%s diagnostic block is rank deficient: rank %zu / %zu",
290 const double rel_rank_tol,
const PetscBool check_full_rank,
291 const PetscBool view_matrix) {
295 MPI_Comm_size(PETSC_COMM_WORLD, &comm_size);
296 if (comm_size != 1) {
298 "affine_tet_stress_gram is a serial diagnostic; run with -np 1");
301 DMType dm_name =
"DMMOFEM";
304 moab::Core moab_core;
305 moab::Interface &moab = moab_core;
306 ParallelComm *pcomm = ParallelComm::get_pcomm(&moab,
MYPCOMM_INDEX);
307 if (pcomm ==
nullptr) {
308 pcomm =
new ParallelComm(&moab, PETSC_COMM_SELF);
319 meshset, 3, bit_level0);
328 boost::make_shared<AnalyticalTractionBcVec>();
331 boost::make_shared<NormalDisplacementBcVec>();
333 boost::make_shared<AnalyticalDisplacementBcVec>();
365 switch (matrix_type) {
369 if (include_bubble) {
375 if (!include_bubble) {
377 "P-only diagnostic is implemented for -diag_matrix_type gram");
391 auto fe_lhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(m_field);
394 switch (matrix_type) {
396 if (include_bubble) {
422 CHKERR MatAssemblyBegin(
A, MAT_FINAL_ASSEMBLY);
423 CHKERR MatAssemblyEnd(
A, MAT_FINAL_ASSEMBLY);
429 rel_rank_tol, check_full_rank, view_matrix);
435int main(
int argc,
char *argv[]) {
438 auto core_log = logging::core::get();
452 PetscBool view_matrix = PETSC_FALSE;
454 &view_matrix, PETSC_NULLPTR);
455 double rel_rank_tol = 1e-10;
457 &rel_rank_tol, PETSC_NULLPTR);
458 PetscBool check_full_rank = PETSC_FALSE;
460 &check_full_rank, PETSC_NULLPTR);
461 PetscBool include_bubble = PETSC_TRUE;
463 &include_bubble, PETSC_NULLPTR);
467 check_full_rank, view_matrix);
Eshelbian plasticity interface.
static MoFEMErrorCode analyseDenseStressBlock(const MatrixDouble &dense, const DiagnosticMatrixType matrix_type, const PetscBool include_bubble, const double rel_rank_tol, const PetscBool check_full_rank, const PetscBool view_matrix)
Prints a compact rank summary for the assembled matrix.
static MoFEMErrorCode getDiagnosticMatrixType(DiagnosticMatrixType &type)
Reads -diag_matrix_type from PETSc options.
static MoFEMErrorCode getDenseMatrix(Mat A, MatrixDouble &dense)
Copies a PETSc matrix into a dense uBLAS matrix.
static const char * getDiagnosticMatrixTypeName(DiagnosticMatrixType type)
Returns the PETSc option name for a diagnostic matrix type.
static MoFEMErrorCode computeRankDiagnostic(const MatrixDouble &dense, const double rel_rank_tol, RankDiagnostic &rank_data)
Computes rank from the smaller of A*A^T and A^T*A.
static MoFEMErrorCode printDenseMatrix(const MatrixDouble &dense)
Prints a dense matrix row by row.
static MoFEMErrorCode createAffineTet(moab::Interface &moab, EntityHandle &meshset)
Creates one unit affine tetrahedron mesh.
static MoFEMErrorCode assembleStressDiagnostic(const DiagnosticMatrixType matrix_type, const PetscBool include_bubble, const double rel_rank_tol, const PetscBool check_full_rank, const PetscBool view_matrix)
Builds the affine tet problem and assembles the diagnostic matrix.
DiagnosticMatrixType
Selects which diagnostic matrix is assembled.
#define CATCH_ERRORS
Catch errors.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MYPCOMM_INDEX
default communicator number PCOMM
#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.
PetscErrorCode DMMoFEMSetIsPartitioned(DM dm, PetscBool is_partitioned)
PetscErrorCode DMMoFEMCreateSubDM(DM subdm, DM dm, const char problem_name[])
Must be called by user to set Sub DM MoFEM data structures.
PetscErrorCode DMMoFEMAddElement(DM dm, std::string fe_name)
add element to dm
PetscErrorCode DMMoFEMSetSquareProblem(DM dm, PetscBool square_problem)
set squared problem
PetscErrorCode DMMoFEMCreateMoFEM(DM dm, MoFEM::Interface *m_field_ptr, const char problem_name[], const MoFEM::BitRefLevel bit_level, const MoFEM::BitRefLevel bit_mask=MoFEM::BitRefLevel().set())
Must be called by user to set MoFEM data structures.
PetscErrorCode DMMoFEMAddSubFieldRow(DM dm, const char field_name[])
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
auto createDMVector(DM dm, RowColData rc=RowColData::COL)
Get smart vector from DM.
PetscErrorCode DMMoFEMAddSubFieldCol(DM dm, const char field_name[])
auto createDMMatrix(DM dm)
Get smart matrix from DM.
static LoggerType & setLog(const std::string channel)
Set ans resset chanel logger.
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
implementation of Data Operators for Forces and Sources
PetscErrorCode DMMoFEMSetDestroyProblem(DM dm, PetscBool destroy_problem)
PetscErrorCode PetscOptionsGetReal(PetscOptions *, const char pre[], const char name[], PetscReal *dval, PetscBool *set)
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
PetscErrorCode PetscOptionsGetString(PetscOptions *, const char pre[], const char name[], char str[], size_t size, PetscBool *set)
MoFEMErrorCode computeEigenValuesSymmetric(const MatrixDouble &mat, VectorDouble &eig, MatrixDouble &eigen_vec)
compute eigenvalues of a symmetric matrix using lapack dsyev
auto createDM(MPI_Comm comm, const std::string dm_type_name)
Creates smart DM object.
constexpr auto field_name
boost::shared_ptr< ExternalStrainVec > externalStrainVecPtr
boost::shared_ptr< TractionBcVec > bcSpatialTractionVecPtr
const std::string spatialL2Disp
MoFEMErrorCode addMaterial_Hencky(double E, double nu)
static enum StretchHandling stretchHandling
boost::shared_ptr< TractionFreeBc > bcSpatialFreeTractionVecPtr
MoFEMErrorCode getTractionFreeBc(const EntityHandle meshset, boost::shared_ptr< TractionFreeBc > &bc_ptr, const std::string contact_set_name)
Remove all, but entities where kinematic constrains are applied.
const std::string elementVolumeName
boost::shared_ptr< BcRotVec > bcSpatialRotationVecPtr
boost::shared_ptr< NormalDisplacementBcVec > bcSpatialNormalDisplacementVecPtr
const std::string piolaStress
const std::string bubbleField
boost::shared_ptr< AnalyticalDisplacementBcVec > bcSpatialAnalyticalDisplacementVecPtr
MoFEMErrorCode projectGeometry(const EntityHandle meshset=0, double time=0)
const std::string rotAxis
boost::shared_ptr< BcDispVec > bcSpatialDispVecPtr
MoFEMErrorCode addVolumeFiniteElement(const EntityHandle meshset=0, const bool add_bubble=true)
MoFEMErrorCode pushNoStretchVolumeA00Ops(boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe_lhs)
MoFEMErrorCode setBaseVolumeElementOps(const int tag, const bool do_rhs, const bool do_lhs, const bool calc_rates, boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe, const bool add_bubble=true)
boost::shared_ptr< AnalyticalTractionBcVec > bcSpatialAnalyticalTractionVecPtr
static bool hasNonHomogeneousMaterialBlock
MoFEMErrorCode pushStretchVolumeA00Ops(boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe_lhs)
boost::shared_ptr< PressureBcVec > bcSpatialPressureVecPtr
SmartPetscObj< Vec > solTSStep
const std::string stretchTensor
MoFEMErrorCode addFields(const EntityHandle meshset=0, const bool add_bubble=true)
MoFEMErrorCode pushStressGramOps(boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe_lhs)
MoFEMErrorCode pushPiolaStressGramOps(boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe_lhs)
virtual MoFEMErrorCode build_adjacencies(const Range &ents, int verb=DEFAULT_VERBOSITY)=0
build adjacencies
virtual MPI_Comm & get_comm() const =0
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.
Deprecated interface functions.
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 > getStrmWorld()
Get the strm world object.
static boost::shared_ptr< std::ostream > getStrmSync()
Get the strm sync object.
static boost::shared_ptr< std::ostream > getStrmSelf()
Get the strm self object.
static constexpr Switches CtxSetA
Jacobian matrix switch.
static constexpr Switches CtxSetX
Solution vector switch.
static constexpr Switches CtxSetX_T
First time derivative switch.
static constexpr Switches CtxSetB
Preconditioner matrix switch.
Problem manager is used to build and partition problems.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Stores a short rank summary for the assembled matrix.
double minNonzeroSingular