@@ -68,3 +68,59 @@ PetscErrorCode PerturbVerticesSmooth(DM dm) {
6868 PetscCall ( VecRestoreArray (coordinates ,& coords ) );
6969 PetscFunctionReturn (0 );
7070}
71+
72+
73+ PetscErrorCode PerturbVerticesRandom (DM dm ) {
74+
75+ PetscFunctionBegin ;
76+ Vec coordinates ;
77+ PetscSection coordSection ;
78+ PetscScalar * coords ;
79+ PetscInt v ,vStart ,vEnd ,offset , dim ;
80+ PetscReal x , y , z ;
81+
82+ PetscCall ( DMGetDimension (dm ,& dim ) );
83+ PetscCall ( DMGetCoordinateSection (dm , & coordSection ) );
84+ PetscCall ( DMGetCoordinatesLocal (dm , & coordinates ) );
85+ PetscCall ( DMPlexGetDepthStratum (dm , 0 , & vStart , & vEnd ) );
86+ PetscCall ( VecGetArray (coordinates ,& coords ) );
87+ PetscInt c_end , c_start , num_elem ;
88+ PetscCall ( DMPlexGetHeightStratum (dm , 0 , & c_start , & c_end ) );
89+ num_elem = c_end - c_start ;
90+
91+ for (v = vStart ; v < vEnd ; v ++ ) {
92+ PetscCall ( PetscSectionGetOffset (coordSection ,v ,& offset ) );
93+ if (dim == 2 ) {
94+ PetscScalar nx = sqrt (num_elem );
95+ PetscReal domain_min [2 ], domain_max [2 ], domain_size [2 ];
96+ PetscCall ( DMGetBoundingBox (dm , domain_min , domain_max ) );
97+ for (PetscInt i = 0 ; i < 2 ; i ++ ) domain_size [i ] = domain_max [i ] - domain_min [i ];
98+ PetscReal hx = domain_size [0 ]/nx , hy = domain_size [1 ]/nx ;
99+ x = coords [offset ]; y = coords [offset + 1 ];
100+ // perturb randomly O(h*sqrt(2)/3)
101+ PetscReal rx = ((PetscReal )rand ())/((PetscReal )RAND_MAX )* (hx * 0.471404 );
102+ PetscReal ry = ((PetscReal )rand ())/((PetscReal )RAND_MAX )* (hy * 0.471404 );
103+ PetscReal t = ((PetscReal )rand ())/((PetscReal )RAND_MAX )* PETSC_PI ;
104+ coords [offset ] = x + rx * PetscCosReal (t );
105+ coords [offset + 1 ] = y + ry * PetscSinReal (t );
106+ } else {
107+ PetscScalar nx = cbrt (num_elem );
108+ PetscReal domain_min [3 ], domain_max [3 ], domain_size [3 ];
109+ PetscCall ( DMGetBoundingBox (dm , domain_min , domain_max ) );
110+ for (PetscInt i = 0 ; i < 3 ; i ++ ) domain_size [i ] = domain_max [i ] - domain_min [i ];
111+ PetscReal hx = domain_size [0 ]/nx , hy = domain_size [1 ]/nx ,
112+ hz = domain_size [2 ]/nx ;
113+ x = coords [offset ]; y = coords [offset + 1 ], z = coords [offset + 2 ];
114+ // This is because 'boundary' is broken in 3D
115+ PetscReal rx = ((PetscReal )rand ())/((PetscReal )RAND_MAX )* (hx * 0.471404 );
116+ PetscReal ry = ((PetscReal )rand ())/((PetscReal )RAND_MAX )* (hy * 0.471404 );
117+ PetscReal rz = ((PetscReal )rand ())/((PetscReal )RAND_MAX )* (hz * 0.471404 );
118+ PetscReal t = ((PetscReal )rand ())/((PetscReal )RAND_MAX )* PETSC_PI ;
119+ coords [offset ] = x + rx * PetscCosReal (t );
120+ coords [offset + 1 ] = y + ry * PetscCosReal (t );
121+ coords [offset + 2 ] = z + rz * PetscSinReal (t );
122+ }
123+ }
124+ PetscCall ( VecRestoreArray (coordinates ,& coords ) );
125+ PetscFunctionReturn (0 );
126+ }
0 commit comments