@@ -613,6 +613,24 @@ PetscVector<T>::PetscVector (Vec v,
613613 VecType ptype;
614614 LibmeshPetscCall (VecGetType (_vec, &ptype));
615615
616+ // PETSc supports some exotic types nowadays. Just use Vec sizes to
617+ // determine whether we're SERIAL vs PARALLEL-or-GHOSTED.
618+ PetscInt petsc_global_size = 0 ;
619+ LibmeshPetscCall (VecGetSize (_vec, &petsc_global_size));
620+
621+ // If we have a parallel Vec with all its DoFs on one processor, we
622+ // might be unable to tell on that processor that it's not a serial
623+ // vector unless we communicate.
624+ bool is_serial = (petsc_local_size == petsc_global_size);
625+ comm_in.min (is_serial);
626+
627+ #ifdef DEBUG
628+ dof_id_type sum_of_local_sizes = petsc_local_size;
629+ comm_in.sum (sum_of_local_sizes);
630+ libmesh_assert_equal_to (sum_of_local_sizes,
631+ cast_int<dof_id_type>(petsc_global_size));
632+ #endif
633+
616634#if PETSC_RELEASE_GREATER_EQUALS(3, 21, 0)
617635 // Fande only implemented VecGhostGetGhostIS for VECMPI
618636 if (std::strcmp (ptype, VECMPI) == 0 )
@@ -642,9 +660,9 @@ PetscVector<T>::PetscVector (Vec v,
642660 else
643661 this ->_type = PARALLEL;
644662 }
645- else if (std::strcmp (ptype,VECSHARED) == 0 )
663+ else if (!is_serial )
646664#else // PETSc < 3.21.0
647- if (( std::strcmp (ptype,VECSHARED) == 0 ) || ( std::strcmp (ptype,VECMPI) == 0 ) )
665+ if (!is_serial )
648666#endif
649667 {
650668 ISLocalToGlobalMapping mapping;
0 commit comments