1557cf195SMatthew G. Knepley static char help[] = "Test adaptive interpolation of functions of a given polynomial order\n\n"; 2557cf195SMatthew G. Knepley 3557cf195SMatthew G. Knepley #include <petscdmplex.h> 4557cf195SMatthew G. Knepley #include <petscsnes.h> 5557cf195SMatthew G. Knepley 6557cf195SMatthew G. Knepley /* 7557cf195SMatthew G. Knepley What properties does the adapted interpolator have? 8557cf195SMatthew G. Knepley 9557cf195SMatthew G. Knepley 1) If we adapt to quadratics, we can get lower interpolation error for quadratics (than local interpolation) when using a linear basis 10557cf195SMatthew G. Knepley 11557cf195SMatthew G. Knepley $ ./ex8 -dm_refine 2 -petscspace_degree 1 -qorder 1 -dim 2 -porder 2 -K 2 -num_comp 1 -use_poly 1 12557cf195SMatthew G. Knepley Function tests FAIL for order 2 at tolerance 1e-10 error 0.00273757 13557cf195SMatthew G. Knepley Function tests FAIL for order 2 derivatives at tolerance 1e-10 error 0.0721688 14557cf195SMatthew G. Knepley Interpolation tests FAIL for order 2 at tolerance 1e-10 error 0.00284555 15557cf195SMatthew G. Knepley Interpolation tests FAIL for order 2 derivatives at tolerance 1e-10 error 0.0721688 16557cf195SMatthew G. Knepley Adapting interpolator using polynomials 17557cf195SMatthew G. Knepley The number of input vectors 4 < 7 the maximum number of column entries 18557cf195SMatthew G. Knepley Interpolation poly tests FAIL for order 2 at tolerance 1e-10 error 0.00659864 19557cf195SMatthew G. Knepley Interpolation poly tests FAIL for order 2 derivatives at tolerance 1e-10 error 0.0836582 20557cf195SMatthew G. Knepley Interpolation trig (0, 0) tests FAIL for order 1 at tolerance 1e-10 error 0.476194 21557cf195SMatthew G. Knepley Interpolation trig (0, 0) tests FAIL for order 1 derivatives at tolerance 1e-10 error 2.22144 22557cf195SMatthew G. Knepley Interpolation trig (0, 1) tests FAIL for order 1 at tolerance 1e-10 error 1.39768 23557cf195SMatthew G. Knepley Interpolation trig (0, 1) tests FAIL for order 1 derivatives at tolerance 1e-10 error 2.22144 24557cf195SMatthew G. Knepley Interpolation trig (1, 0) tests FAIL for order 2 at tolerance 1e-10 error 1.07315 25557cf195SMatthew G. Knepley Interpolation trig (1, 0) tests FAIL for order 2 derivatives at tolerance 1e-10 error 4.55403 26557cf195SMatthew G. Knepley Interpolation trig (1, 1) tests FAIL for order 2 at tolerance 1e-10 error 1.07315 27557cf195SMatthew G. Knepley Interpolation trig (1, 1) tests FAIL for order 2 derivatives at tolerance 1e-10 error 4.55403 28557cf195SMatthew G. Knepley 29557cf195SMatthew G. Knepley $ ./ex8 -dm_refine 2 -petscspace_degree 1 -qorder 1 -dim 2 -porder 2 -K 3 -num_comp 1 -use_poly 1 30557cf195SMatthew G. Knepley Function tests FAIL for order 2 at tolerance 1e-10 error 0.00273757 31557cf195SMatthew G. Knepley Function tests FAIL for order 2 derivatives at tolerance 1e-10 error 0.0721688 32557cf195SMatthew G. Knepley Interpolation tests FAIL for order 2 at tolerance 1e-10 error 0.00284555 33557cf195SMatthew G. Knepley Interpolation tests FAIL for order 2 derivatives at tolerance 1e-10 error 0.0721688 34557cf195SMatthew G. Knepley Adapting interpolator using polynomials 35557cf195SMatthew G. Knepley The number of input vectors 6 < 7 the maximum number of column entries 36557cf195SMatthew G. Knepley Interpolation poly tests FAIL for order 2 at tolerance 1e-10 error 0.00194055 37557cf195SMatthew G. Knepley Interpolation poly tests FAIL for order 2 derivatives at tolerance 1e-10 error 0.0525591 38557cf195SMatthew G. Knepley Interpolation trig (0, 0) tests FAIL for order 1 at tolerance 1e-10 error 0.476255 39557cf195SMatthew G. Knepley Interpolation trig (0, 0) tests FAIL for order 1 derivatives at tolerance 1e-10 error 2.22132 40557cf195SMatthew G. Knepley Interpolation trig (0, 1) tests FAIL for order 1 at tolerance 1e-10 error 1.39785 41557cf195SMatthew G. Knepley Interpolation trig (0, 1) tests FAIL for order 1 derivatives at tolerance 1e-10 error 2.22119 42557cf195SMatthew G. Knepley Interpolation trig (1, 0) tests FAIL for order 2 at tolerance 1e-10 error 1.0727 43557cf195SMatthew G. Knepley Interpolation trig (1, 0) tests FAIL for order 2 derivatives at tolerance 1e-10 error 4.55364 44557cf195SMatthew G. Knepley Interpolation trig (1, 1) tests FAIL for order 2 at tolerance 1e-10 error 1.0727 45557cf195SMatthew G. Knepley Interpolation trig (1, 1) tests FAIL for order 2 derivatives at tolerance 1e-10 error 4.55364 46557cf195SMatthew G. Knepley Interpolation trig (2, 0) tests FAIL for order 3 at tolerance 1e-10 error 0.705258 47557cf195SMatthew G. Knepley Interpolation trig (2, 0) tests FAIL for order 3 derivatives at tolerance 1e-10 error 6.82037 48557cf195SMatthew G. Knepley Interpolation trig (2, 1) tests FAIL for order 3 at tolerance 1e-10 error 0.705258 49557cf195SMatthew G. Knepley Interpolation trig (2, 1) tests FAIL for order 3 derivatives at tolerance 1e-10 error 6.82037 50557cf195SMatthew G. Knepley 51557cf195SMatthew G. Knepley 2) We can more accurately capture low harmonics 52557cf195SMatthew G. Knepley 53557cf195SMatthew G. Knepley If we adapt polynomials, we can be exact 54557cf195SMatthew G. Knepley 55557cf195SMatthew G. Knepley $ ./ex8 -dm_refine 2 -petscspace_degree 1 -qorder 1 -dim 2 -porder 1 -K 2 -num_comp 1 -use_poly 1 56557cf195SMatthew G. Knepley Function tests pass for order 1 at tolerance 1e-10 57557cf195SMatthew G. Knepley Function tests pass for order 1 derivatives at tolerance 1e-10 58557cf195SMatthew G. Knepley Interpolation tests pass for order 1 at tolerance 1e-10 59557cf195SMatthew G. Knepley Interpolation tests pass for order 1 derivatives at tolerance 1e-10 60557cf195SMatthew G. Knepley Adapting interpolator using polynomials 61557cf195SMatthew G. Knepley The number of input vectors 4 < 7 the maximum number of column entries 62557cf195SMatthew G. Knepley Interpolation poly tests pass for order 1 at tolerance 1e-10 63557cf195SMatthew G. Knepley Interpolation poly tests pass for order 1 derivatives at tolerance 1e-10 64557cf195SMatthew G. Knepley Interpolation trig (0, 0) tests FAIL for order 1 at tolerance 1e-10 error 0.476194 65557cf195SMatthew G. Knepley Interpolation trig (0, 0) tests FAIL for order 1 derivatives at tolerance 1e-10 error 2.22144 66557cf195SMatthew G. Knepley Interpolation trig (0, 1) tests FAIL for order 1 at tolerance 1e-10 error 1.39768 67557cf195SMatthew G. Knepley Interpolation trig (0, 1) tests FAIL for order 1 derivatives at tolerance 1e-10 error 2.22144 68557cf195SMatthew G. Knepley Interpolation trig (1, 0) tests FAIL for order 2 at tolerance 1e-10 error 1.07315 69557cf195SMatthew G. Knepley Interpolation trig (1, 0) tests FAIL for order 2 derivatives at tolerance 1e-10 error 4.55403 70557cf195SMatthew G. Knepley Interpolation trig (1, 1) tests FAIL for order 2 at tolerance 1e-10 error 1.07315 71557cf195SMatthew G. Knepley Interpolation trig (1, 1) tests FAIL for order 2 derivatives at tolerance 1e-10 error 4.55403 72557cf195SMatthew G. Knepley 73557cf195SMatthew G. Knepley and least for small K, 74557cf195SMatthew G. Knepley 75557cf195SMatthew G. Knepley $ ./ex8 -dm_refine 2 -petscspace_degree 1 -qorder 1 -dim 2 -porder 1 -K 4 -num_comp 1 -use_poly 1 76557cf195SMatthew G. Knepley Function tests pass for order 1 at tolerance 1e-10 77557cf195SMatthew G. Knepley Function tests pass for order 1 derivatives at tolerance 1e-10 78557cf195SMatthew G. Knepley Interpolation tests pass for order 1 at tolerance 1e-10 79557cf195SMatthew G. Knepley Interpolation tests pass for order 1 derivatives at tolerance 1e-10 80557cf195SMatthew G. Knepley Adapting interpolator using polynomials 81557cf195SMatthew G. Knepley Interpolation poly tests FAIL for order 1 at tolerance 1e-10 error 0.0015351 82557cf195SMatthew G. Knepley Interpolation poly tests FAIL for order 1 derivatives at tolerance 1e-10 error 0.0427369 83557cf195SMatthew G. Knepley Interpolation trig (0, 0) tests FAIL for order 1 at tolerance 1e-10 error 0.476359 84557cf195SMatthew G. Knepley Interpolation trig (0, 0) tests FAIL for order 1 derivatives at tolerance 1e-10 error 2.22115 85557cf195SMatthew G. Knepley Interpolation trig (0, 1) tests FAIL for order 1 at tolerance 1e-10 error 1.3981 86557cf195SMatthew G. Knepley Interpolation trig (0, 1) tests FAIL for order 1 derivatives at tolerance 1e-10 error 2.22087 87557cf195SMatthew G. Knepley Interpolation trig (1, 0) tests FAIL for order 2 at tolerance 1e-10 error 1.07228 88557cf195SMatthew G. Knepley Interpolation trig (1, 0) tests FAIL for order 2 derivatives at tolerance 1e-10 error 4.55238 89557cf195SMatthew G. Knepley Interpolation trig (1, 1) tests FAIL for order 2 at tolerance 1e-10 error 1.07228 90557cf195SMatthew G. Knepley Interpolation trig (1, 1) tests FAIL for order 2 derivatives at tolerance 1e-10 error 4.55238 91557cf195SMatthew G. Knepley Interpolation trig (2, 0) tests FAIL for order 3 at tolerance 1e-10 error 0.704947 92557cf195SMatthew G. Knepley Interpolation trig (2, 0) tests FAIL for order 3 derivatives at tolerance 1e-10 error 6.82254 93557cf195SMatthew G. Knepley Interpolation trig (2, 1) tests FAIL for order 3 at tolerance 1e-10 error 0.704948 94557cf195SMatthew G. Knepley Interpolation trig (2, 1) tests FAIL for order 3 derivatives at tolerance 1e-10 error 6.82254 95557cf195SMatthew G. Knepley Interpolation trig (3, 0) tests FAIL for order 4 at tolerance 1e-10 error 0.893279 96557cf195SMatthew G. Knepley Interpolation trig (3, 0) tests FAIL for order 4 derivatives at tolerance 1e-10 error 8.93718 97557cf195SMatthew G. Knepley Interpolation trig (3, 1) tests FAIL for order 4 at tolerance 1e-10 error 0.89328 98557cf195SMatthew G. Knepley Interpolation trig (3, 1) tests FAIL for order 4 derivatives at tolerance 1e-10 error 8.93717 99557cf195SMatthew G. Knepley 100557cf195SMatthew G. Knepley but adapting to harmonics gives alright polynomials errors and much better harmonics errors. 101557cf195SMatthew G. Knepley 102557cf195SMatthew G. Knepley $ ./ex8 -dm_refine 2 -petscspace_degree 1 -qorder 1 -dim 2 -porder 1 -K 4 -num_comp 1 -use_poly 0 103557cf195SMatthew G. Knepley Function tests pass for order 1 at tolerance 1e-10 104557cf195SMatthew G. Knepley Function tests pass for order 1 derivatives at tolerance 1e-10 105557cf195SMatthew G. Knepley Interpolation tests pass for order 1 at tolerance 1e-10 106557cf195SMatthew G. Knepley Interpolation tests pass for order 1 derivatives at tolerance 1e-10 107557cf195SMatthew G. Knepley Adapting interpolator using harmonics 108557cf195SMatthew G. Knepley Interpolation poly tests FAIL for order 1 at tolerance 1e-10 error 0.0720606 109557cf195SMatthew G. Knepley Interpolation poly tests FAIL for order 1 derivatives at tolerance 1e-10 error 1.97779 110557cf195SMatthew G. Knepley Interpolation trig (0, 0) tests FAIL for order 1 at tolerance 1e-10 error 0.0398055 111557cf195SMatthew G. Knepley Interpolation trig (0, 0) tests FAIL for order 1 derivatives at tolerance 1e-10 error 0.995963 112557cf195SMatthew G. Knepley Interpolation trig (0, 1) tests FAIL for order 1 at tolerance 1e-10 error 0.0398051 113557cf195SMatthew G. Knepley Interpolation trig (0, 1) tests FAIL for order 1 derivatives at tolerance 1e-10 error 0.995964 114557cf195SMatthew G. Knepley Interpolation trig (1, 0) tests FAIL for order 2 at tolerance 1e-10 error 0.0238441 115557cf195SMatthew G. Knepley Interpolation trig (1, 0) tests FAIL for order 2 derivatives at tolerance 1e-10 error 0.888611 116557cf195SMatthew G. Knepley Interpolation trig (1, 1) tests FAIL for order 2 at tolerance 1e-10 error 0.0238346 117557cf195SMatthew G. Knepley Interpolation trig (1, 1) tests FAIL for order 2 derivatives at tolerance 1e-10 error 0.888612 118557cf195SMatthew G. Knepley Interpolation trig (2, 0) tests FAIL for order 3 at tolerance 1e-10 error 0.0537968 119557cf195SMatthew G. Knepley Interpolation trig (2, 0) tests FAIL for order 3 derivatives at tolerance 1e-10 error 1.57665 120557cf195SMatthew G. Knepley Interpolation trig (2, 1) tests FAIL for order 3 at tolerance 1e-10 error 0.0537779 121557cf195SMatthew G. Knepley Interpolation trig (2, 1) tests FAIL for order 3 derivatives at tolerance 1e-10 error 1.57666 122557cf195SMatthew G. Knepley Interpolation trig (3, 0) tests FAIL for order 4 at tolerance 1e-10 error 0.0775838 123557cf195SMatthew G. Knepley Interpolation trig (3, 0) tests FAIL for order 4 derivatives at tolerance 1e-10 error 2.36926 124557cf195SMatthew G. Knepley Interpolation trig (3, 1) tests FAIL for order 4 at tolerance 1e-10 error 0.0775464 125557cf195SMatthew G. Knepley Interpolation trig (3, 1) tests FAIL for order 4 derivatives at tolerance 1e-10 error 2.36929 126557cf195SMatthew G. Knepley */ 127557cf195SMatthew G. Knepley 128557cf195SMatthew G. Knepley typedef struct { 129557cf195SMatthew G. Knepley /* Element definition */ 130557cf195SMatthew G. Knepley PetscInt qorder; /* Order of the quadrature */ 131557cf195SMatthew G. Knepley PetscInt Nc; /* Number of field components */ 132557cf195SMatthew G. Knepley /* Testing space */ 133557cf195SMatthew G. Knepley PetscInt porder; /* Order of polynomials to test */ 134557cf195SMatthew G. Knepley PetscReal constants[3]; /* Constant values for each dimension */ 135557cf195SMatthew G. Knepley PetscInt m; /* The frequency of sinusoids to use */ 136557cf195SMatthew G. Knepley PetscInt dir; /* The direction of sinusoids to use */ 137557cf195SMatthew G. Knepley /* Adaptation */ 138557cf195SMatthew G. Knepley PetscInt K; /* Number of coarse modes used for optimization */ 139557cf195SMatthew G. Knepley PetscBool usePoly; /* Use polynomials, or harmonics, to adapt interpolator */ 140557cf195SMatthew G. Knepley } AppCtx; 141557cf195SMatthew G. Knepley 1429371c9d4SSatish Balay typedef enum { 1439371c9d4SSatish Balay INTERPOLATION, 1449371c9d4SSatish Balay RESTRICTION, 1459371c9d4SSatish Balay INJECTION 1469371c9d4SSatish Balay } InterpType; 147557cf195SMatthew G. Knepley 148557cf195SMatthew G. Knepley /* u = 1 */ 149*2a8381b2SBarry Smith PetscErrorCode constant(PetscInt dim, PetscReal time, const PetscReal coords[], PetscInt Nc, PetscScalar *u, PetscCtx ctx) 150d71ae5a4SJacob Faibussowitsch { 151557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *)ctx; 152557cf195SMatthew G. Knepley PetscInt d = user->dir; 153557cf195SMatthew G. Knepley 154557cf195SMatthew G. Knepley if (Nc > 1) { 155557cf195SMatthew G. Knepley for (d = 0; d < Nc; ++d) u[d] = user->constants[d]; 156557cf195SMatthew G. Knepley } else { 157557cf195SMatthew G. Knepley u[0] = user->constants[d]; 158557cf195SMatthew G. Knepley } 1593ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 160557cf195SMatthew G. Knepley } 161*2a8381b2SBarry Smith PetscErrorCode constantDer(PetscInt dim, PetscReal time, const PetscReal coords[], const PetscReal n[], PetscInt Nc, PetscScalar *u, PetscCtx ctx) 162d71ae5a4SJacob Faibussowitsch { 163557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *)ctx; 164557cf195SMatthew G. Knepley PetscInt d = user->dir; 165557cf195SMatthew G. Knepley 166557cf195SMatthew G. Knepley if (Nc > 1) { 167557cf195SMatthew G. Knepley for (d = 0; d < Nc; ++d) u[d] = 0.0; 168557cf195SMatthew G. Knepley } else { 169557cf195SMatthew G. Knepley u[0] = user->constants[d]; 170557cf195SMatthew G. Knepley } 1713ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 172557cf195SMatthew G. Knepley } 173557cf195SMatthew G. Knepley 174557cf195SMatthew G. Knepley /* u = x */ 175*2a8381b2SBarry Smith PetscErrorCode linear(PetscInt dim, PetscReal time, const PetscReal coords[], PetscInt Nc, PetscScalar *u, PetscCtx ctx) 176d71ae5a4SJacob Faibussowitsch { 177557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *)ctx; 178557cf195SMatthew G. Knepley PetscInt d = user->dir; 179557cf195SMatthew G. Knepley 180557cf195SMatthew G. Knepley if (Nc > 1) { 181557cf195SMatthew G. Knepley for (d = 0; d < Nc; ++d) u[d] = coords[d]; 182557cf195SMatthew G. Knepley } else { 183557cf195SMatthew G. Knepley u[0] = coords[d]; 184557cf195SMatthew G. Knepley } 1853ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 186557cf195SMatthew G. Knepley } 187*2a8381b2SBarry Smith PetscErrorCode linearDer(PetscInt dim, PetscReal time, const PetscReal coords[], const PetscReal n[], PetscInt Nc, PetscScalar *u, PetscCtx ctx) 188d71ae5a4SJacob Faibussowitsch { 189557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *)ctx; 190557cf195SMatthew G. Knepley PetscInt d = user->dir; 191557cf195SMatthew G. Knepley 192557cf195SMatthew G. Knepley if (Nc > 1) { 193557cf195SMatthew G. Knepley PetscInt e; 194557cf195SMatthew G. Knepley for (d = 0; d < Nc; ++d) { 195557cf195SMatthew G. Knepley u[d] = 0.0; 196557cf195SMatthew G. Knepley for (e = 0; e < dim; ++e) u[d] += (d == e ? 1.0 : 0.0) * n[e]; 197557cf195SMatthew G. Knepley } 198557cf195SMatthew G. Knepley } else { 199557cf195SMatthew G. Knepley u[0] = n[d]; 200557cf195SMatthew G. Knepley } 2013ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 202557cf195SMatthew G. Knepley } 203557cf195SMatthew G. Knepley 204557cf195SMatthew G. Knepley /* u = x^2 or u = (x^2, xy) or u = (xy, yz, zx) */ 205*2a8381b2SBarry Smith PetscErrorCode quadratic(PetscInt dim, PetscReal time, const PetscReal coords[], PetscInt Nc, PetscScalar *u, PetscCtx ctx) 206d71ae5a4SJacob Faibussowitsch { 207557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *)ctx; 208557cf195SMatthew G. Knepley PetscInt d = user->dir; 209557cf195SMatthew G. Knepley 210557cf195SMatthew G. Knepley if (Nc > 1) { 2119371c9d4SSatish Balay if (Nc > 2) { 2129371c9d4SSatish Balay u[0] = coords[0] * coords[1]; 2139371c9d4SSatish Balay u[1] = coords[1] * coords[2]; 2149371c9d4SSatish Balay u[2] = coords[2] * coords[0]; 2159371c9d4SSatish Balay } else { 2169371c9d4SSatish Balay u[0] = coords[0] * coords[0]; 2179371c9d4SSatish Balay u[1] = coords[0] * coords[1]; 2189371c9d4SSatish Balay } 219557cf195SMatthew G. Knepley } else { 220557cf195SMatthew G. Knepley u[0] = coords[d] * coords[d]; 221557cf195SMatthew G. Knepley } 2223ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 223557cf195SMatthew G. Knepley } 224*2a8381b2SBarry Smith PetscErrorCode quadraticDer(PetscInt dim, PetscReal time, const PetscReal coords[], const PetscReal n[], PetscInt Nc, PetscScalar *u, PetscCtx ctx) 225d71ae5a4SJacob Faibussowitsch { 226557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *)ctx; 227557cf195SMatthew G. Knepley PetscInt d = user->dir; 228557cf195SMatthew G. Knepley 229557cf195SMatthew G. Knepley if (Nc > 1) { 2309371c9d4SSatish Balay if (Nc > 2) { 2319371c9d4SSatish Balay u[0] = coords[1] * n[0] + coords[0] * n[1]; 2329371c9d4SSatish Balay u[1] = coords[2] * n[1] + coords[1] * n[2]; 2339371c9d4SSatish Balay u[2] = coords[2] * n[0] + coords[0] * n[2]; 2349371c9d4SSatish Balay } else { 2359371c9d4SSatish Balay u[0] = 2.0 * coords[0] * n[0]; 2369371c9d4SSatish Balay u[1] = coords[1] * n[0] + coords[0] * n[1]; 2379371c9d4SSatish Balay } 238557cf195SMatthew G. Knepley } else { 239557cf195SMatthew G. Knepley u[0] = 2.0 * coords[d] * n[d]; 240557cf195SMatthew G. Knepley } 2413ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 242557cf195SMatthew G. Knepley } 243557cf195SMatthew G. Knepley 244557cf195SMatthew G. Knepley /* u = x^3 or u = (x^3, x^2y) or u = (x^2y, y^2z, z^2x) */ 245*2a8381b2SBarry Smith PetscErrorCode cubic(PetscInt dim, PetscReal time, const PetscReal coords[], PetscInt Nc, PetscScalar *u, PetscCtx ctx) 246d71ae5a4SJacob Faibussowitsch { 247557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *)ctx; 248557cf195SMatthew G. Knepley PetscInt d = user->dir; 249557cf195SMatthew G. Knepley 250557cf195SMatthew G. Knepley if (Nc > 1) { 2519371c9d4SSatish Balay if (Nc > 2) { 2529371c9d4SSatish Balay u[0] = coords[0] * coords[0] * coords[1]; 2539371c9d4SSatish Balay u[1] = coords[1] * coords[1] * coords[2]; 2549371c9d4SSatish Balay u[2] = coords[2] * coords[2] * coords[0]; 2559371c9d4SSatish Balay } else { 2569371c9d4SSatish Balay u[0] = coords[0] * coords[0] * coords[0]; 2579371c9d4SSatish Balay u[1] = coords[0] * coords[0] * coords[1]; 2589371c9d4SSatish Balay } 259557cf195SMatthew G. Knepley } else { 260557cf195SMatthew G. Knepley u[0] = coords[d] * coords[d] * coords[d]; 261557cf195SMatthew G. Knepley } 2623ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 263557cf195SMatthew G. Knepley } 264*2a8381b2SBarry Smith PetscErrorCode cubicDer(PetscInt dim, PetscReal time, const PetscReal coords[], const PetscReal n[], PetscInt Nc, PetscScalar *u, PetscCtx ctx) 265d71ae5a4SJacob Faibussowitsch { 266557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *)ctx; 267557cf195SMatthew G. Knepley PetscInt d = user->dir; 268557cf195SMatthew G. Knepley 269557cf195SMatthew G. Knepley if (Nc > 1) { 2709371c9d4SSatish Balay if (Nc > 2) { 2719371c9d4SSatish Balay u[0] = 2.0 * coords[0] * coords[1] * n[0] + coords[0] * coords[0] * n[1]; 2729371c9d4SSatish Balay u[1] = 2.0 * coords[1] * coords[2] * n[1] + coords[1] * coords[1] * n[2]; 2739371c9d4SSatish Balay u[2] = 2.0 * coords[2] * coords[0] * n[2] + coords[2] * coords[2] * n[0]; 2749371c9d4SSatish Balay } else { 2759371c9d4SSatish Balay u[0] = 3.0 * coords[0] * coords[0] * n[0]; 2769371c9d4SSatish Balay u[1] = 2.0 * coords[0] * coords[1] * n[0] + coords[0] * coords[0] * n[1]; 2779371c9d4SSatish Balay } 278557cf195SMatthew G. Knepley } else { 279557cf195SMatthew G. Knepley u[0] = 3.0 * coords[d] * coords[d] * n[d]; 280557cf195SMatthew G. Knepley } 2813ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 282557cf195SMatthew G. Knepley } 283557cf195SMatthew G. Knepley 284557cf195SMatthew G. Knepley /* u = x^4 or u = (x^4, x^2y^2) or u = (x^2y^2, y^2z^2, z^2x^2) */ 285*2a8381b2SBarry Smith PetscErrorCode quartic(PetscInt dim, PetscReal time, const PetscReal coords[], PetscInt Nc, PetscScalar *u, PetscCtx ctx) 286d71ae5a4SJacob Faibussowitsch { 287557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *)ctx; 288557cf195SMatthew G. Knepley PetscInt d = user->dir; 289557cf195SMatthew G. Knepley 290557cf195SMatthew G. Knepley if (Nc > 1) { 2919371c9d4SSatish Balay if (Nc > 2) { 2929371c9d4SSatish Balay u[0] = coords[0] * coords[0] * coords[1] * coords[1]; 2939371c9d4SSatish Balay u[1] = coords[1] * coords[1] * coords[2] * coords[2]; 2949371c9d4SSatish Balay u[2] = coords[2] * coords[2] * coords[0] * coords[0]; 2959371c9d4SSatish Balay } else { 2969371c9d4SSatish Balay u[0] = coords[0] * coords[0] * coords[0] * coords[0]; 2979371c9d4SSatish Balay u[1] = coords[0] * coords[0] * coords[1] * coords[1]; 2989371c9d4SSatish Balay } 299557cf195SMatthew G. Knepley } else { 300557cf195SMatthew G. Knepley u[0] = coords[d] * coords[d] * coords[d] * coords[d]; 301557cf195SMatthew G. Knepley } 3023ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 303557cf195SMatthew G. Knepley } 304*2a8381b2SBarry Smith PetscErrorCode quarticDer(PetscInt dim, PetscReal time, const PetscReal coords[], const PetscReal n[], PetscInt Nc, PetscScalar *u, PetscCtx ctx) 305d71ae5a4SJacob Faibussowitsch { 306557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *)ctx; 307557cf195SMatthew G. Knepley PetscInt d = user->dir; 308557cf195SMatthew G. Knepley 309557cf195SMatthew G. Knepley if (Nc > 1) { 3109371c9d4SSatish Balay if (Nc > 2) { 3119371c9d4SSatish Balay u[0] = 2.0 * coords[0] * coords[1] * coords[1] * n[0] + 2.0 * coords[0] * coords[0] * coords[1] * n[1]; 312557cf195SMatthew G. Knepley u[1] = 2.0 * coords[1] * coords[2] * coords[2] * n[1] + 2.0 * coords[1] * coords[1] * coords[2] * n[2]; 3139371c9d4SSatish Balay u[2] = 2.0 * coords[2] * coords[0] * coords[0] * n[2] + 2.0 * coords[2] * coords[2] * coords[0] * n[0]; 3149371c9d4SSatish Balay } else { 3159371c9d4SSatish Balay u[0] = 4.0 * coords[0] * coords[0] * coords[0] * n[0]; 3169371c9d4SSatish Balay u[1] = 2.0 * coords[0] * coords[1] * coords[1] * n[0] + 2.0 * coords[0] * coords[0] * coords[1] * n[1]; 3179371c9d4SSatish Balay } 318557cf195SMatthew G. Knepley } else { 319557cf195SMatthew G. Knepley u[0] = 4.0 * coords[d] * coords[d] * coords[d] * n[d]; 320557cf195SMatthew G. Knepley } 3213ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 322557cf195SMatthew G. Knepley } 323557cf195SMatthew G. Knepley 324*2a8381b2SBarry Smith PetscErrorCode mytanh(PetscInt dim, PetscReal time, const PetscReal coords[], PetscInt Nc, PetscScalar *u, PetscCtx ctx) 325d71ae5a4SJacob Faibussowitsch { 326557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *)ctx; 327557cf195SMatthew G. Knepley PetscInt d = user->dir; 328557cf195SMatthew G. Knepley 329557cf195SMatthew G. Knepley if (Nc > 1) { 330557cf195SMatthew G. Knepley for (d = 0; d < Nc; ++d) u[d] = PetscTanhReal(coords[d] - 0.5); 331557cf195SMatthew G. Knepley } else { 332557cf195SMatthew G. Knepley u[0] = PetscTanhReal(coords[d] - 0.5); 333557cf195SMatthew G. Knepley } 3343ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 335557cf195SMatthew G. Knepley } 336*2a8381b2SBarry Smith PetscErrorCode mytanhDer(PetscInt dim, PetscReal time, const PetscReal coords[], const PetscReal n[], PetscInt Nc, PetscScalar *u, PetscCtx ctx) 337d71ae5a4SJacob Faibussowitsch { 338557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *)ctx; 339557cf195SMatthew G. Knepley PetscInt d = user->dir; 340557cf195SMatthew G. Knepley 341557cf195SMatthew G. Knepley if (Nc > 1) { 342557cf195SMatthew G. Knepley for (d = 0; d < Nc; ++d) u[d] = 1.0 / PetscSqr(PetscCoshReal(coords[d] - 0.5)) * n[d]; 343557cf195SMatthew G. Knepley } else { 344557cf195SMatthew G. Knepley u[0] = 1.0 / PetscSqr(PetscCoshReal(coords[d] - 0.5)) * n[d]; 345557cf195SMatthew G. Knepley } 3463ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 347557cf195SMatthew G. Knepley } 348557cf195SMatthew G. Knepley 349*2a8381b2SBarry Smith PetscErrorCode trig(PetscInt dim, PetscReal time, const PetscReal coords[], PetscInt Nc, PetscScalar *u, PetscCtx ctx) 350d71ae5a4SJacob Faibussowitsch { 351557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *)ctx; 352557cf195SMatthew G. Knepley PetscInt m = user->m, d = user->dir; 353557cf195SMatthew G. Knepley 354557cf195SMatthew G. Knepley if (Nc > 1) { 355557cf195SMatthew G. Knepley for (d = 0; d < Nc; ++d) u[d] = PetscSinReal(PETSC_PI * m * coords[d]); 356557cf195SMatthew G. Knepley } else { 357557cf195SMatthew G. Knepley u[0] = PetscSinReal(PETSC_PI * m * coords[d]); 358557cf195SMatthew G. Knepley } 3593ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 360557cf195SMatthew G. Knepley } 361*2a8381b2SBarry Smith PetscErrorCode trigDer(PetscInt dim, PetscReal time, const PetscReal coords[], const PetscReal n[], PetscInt Nc, PetscScalar *u, PetscCtx ctx) 362d71ae5a4SJacob Faibussowitsch { 363557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *)ctx; 364557cf195SMatthew G. Knepley PetscInt m = user->m, d = user->dir; 365557cf195SMatthew G. Knepley 366557cf195SMatthew G. Knepley if (Nc > 1) { 367557cf195SMatthew G. Knepley for (d = 0; d < Nc; ++d) u[d] = PETSC_PI * m * PetscCosReal(PETSC_PI * m * coords[d]) * n[d]; 368557cf195SMatthew G. Knepley } else { 369557cf195SMatthew G. Knepley u[0] = PETSC_PI * m * PetscCosReal(PETSC_PI * m * coords[d]) * n[d]; 370557cf195SMatthew G. Knepley } 3713ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 372557cf195SMatthew G. Knepley } 373557cf195SMatthew G. Knepley 374d71ae5a4SJacob Faibussowitsch static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options) 375d71ae5a4SJacob Faibussowitsch { 376557cf195SMatthew G. Knepley PetscFunctionBeginUser; 377557cf195SMatthew G. Knepley options->qorder = 0; 378557cf195SMatthew G. Knepley options->Nc = PETSC_DEFAULT; 379557cf195SMatthew G. Knepley options->porder = 0; 380557cf195SMatthew G. Knepley options->m = 1; 381557cf195SMatthew G. Knepley options->dir = 0; 382557cf195SMatthew G. Knepley options->K = 0; 383557cf195SMatthew G. Knepley options->usePoly = PETSC_TRUE; 384557cf195SMatthew G. Knepley 385d0609cedSBarry Smith PetscOptionsBegin(comm, "", "Projection Test Options", "DMPlex"); 3869566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-qorder", "The quadrature order", "ex8.c", options->qorder, &options->qorder, NULL)); 3879566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-num_comp", "The number of field components", "ex8.c", options->Nc, &options->Nc, NULL)); 3889566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-porder", "The order of polynomials to test", "ex8.c", options->porder, &options->porder, NULL)); 3899566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-K", "The number of coarse modes used in optimization", "ex8.c", options->K, &options->K, NULL)); 3909566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-use_poly", "Use polynomials (or harmonics) to adapt interpolator", "ex8.c", options->usePoly, &options->usePoly, NULL)); 391d0609cedSBarry Smith PetscOptionsEnd(); 3923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 393557cf195SMatthew G. Knepley } 394557cf195SMatthew G. Knepley 395d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm) 396d71ae5a4SJacob Faibussowitsch { 397557cf195SMatthew G. Knepley PetscFunctionBeginUser; 3989566063dSJacob Faibussowitsch PetscCall(DMCreate(comm, dm)); 3999566063dSJacob Faibussowitsch PetscCall(DMSetType(*dm, DMPLEX)); 4009566063dSJacob Faibussowitsch PetscCall(DMSetFromOptions(*dm)); 4019566063dSJacob Faibussowitsch PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view")); 4023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 403557cf195SMatthew G. Knepley } 404557cf195SMatthew G. Knepley 405557cf195SMatthew G. Knepley /* Setup functions to approximate */ 406d71ae5a4SJacob Faibussowitsch static PetscErrorCode SetupFunctions(DM dm, PetscBool usePoly, PetscInt order, PetscInt dir, PetscErrorCode (**exactFuncs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), PetscErrorCode (**exactFuncDers)(PetscInt, PetscReal, const PetscReal[], const PetscReal[], PetscInt, PetscScalar *, void *), AppCtx *user) 407d71ae5a4SJacob Faibussowitsch { 408557cf195SMatthew G. Knepley PetscInt dim; 409557cf195SMatthew G. Knepley 410557cf195SMatthew G. Knepley PetscFunctionBeginUser; 411557cf195SMatthew G. Knepley user->dir = dir; 412557cf195SMatthew G. Knepley if (usePoly) { 413557cf195SMatthew G. Knepley switch (order) { 414557cf195SMatthew G. Knepley case 0: 415557cf195SMatthew G. Knepley exactFuncs[0] = constant; 416557cf195SMatthew G. Knepley exactFuncDers[0] = constantDer; 417557cf195SMatthew G. Knepley break; 418557cf195SMatthew G. Knepley case 1: 419557cf195SMatthew G. Knepley exactFuncs[0] = linear; 420557cf195SMatthew G. Knepley exactFuncDers[0] = linearDer; 421557cf195SMatthew G. Knepley break; 422557cf195SMatthew G. Knepley case 2: 423557cf195SMatthew G. Knepley exactFuncs[0] = quadratic; 424557cf195SMatthew G. Knepley exactFuncDers[0] = quadraticDer; 425557cf195SMatthew G. Knepley break; 426557cf195SMatthew G. Knepley case 3: 427557cf195SMatthew G. Knepley exactFuncs[0] = cubic; 428557cf195SMatthew G. Knepley exactFuncDers[0] = cubicDer; 429557cf195SMatthew G. Knepley break; 430557cf195SMatthew G. Knepley case 4: 431557cf195SMatthew G. Knepley exactFuncs[0] = quartic; 432557cf195SMatthew G. Knepley exactFuncDers[0] = quarticDer; 433557cf195SMatthew G. Knepley break; 434d71ae5a4SJacob Faibussowitsch default: 435d71ae5a4SJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 436d71ae5a4SJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Could not determine functions to test for dimension %" PetscInt_FMT " order %" PetscInt_FMT, dim, order); 437557cf195SMatthew G. Knepley } 438557cf195SMatthew G. Knepley } else { 439557cf195SMatthew G. Knepley user->m = order; 440557cf195SMatthew G. Knepley exactFuncs[0] = trig; 441557cf195SMatthew G. Knepley exactFuncDers[0] = trigDer; 442557cf195SMatthew G. Knepley } 4433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 444557cf195SMatthew G. Knepley } 445557cf195SMatthew G. Knepley 446d71ae5a4SJacob Faibussowitsch static PetscErrorCode ComputeError(DM dm, PetscErrorCode (**exactFuncs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), PetscErrorCode (**exactFuncDers)(PetscInt, PetscReal, const PetscReal[], const PetscReal[], PetscInt, PetscScalar *, void *), void **exactCtxs, PetscReal *error, PetscReal *errorDer, AppCtx *user) 447d71ae5a4SJacob Faibussowitsch { 448557cf195SMatthew G. Knepley Vec u; 449557cf195SMatthew G. Knepley PetscReal n[3] = {1.0, 1.0, 1.0}; 450557cf195SMatthew G. Knepley 451557cf195SMatthew G. Knepley PetscFunctionBeginUser; 4529566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(dm, &u)); 453557cf195SMatthew G. Knepley /* Project function into FE function space */ 4549566063dSJacob Faibussowitsch PetscCall(DMProjectFunction(dm, 0.0, exactFuncs, exactCtxs, INSERT_ALL_VALUES, u)); 4559566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(u, NULL, "-projection_view")); 456557cf195SMatthew G. Knepley /* Compare approximation to exact in L_2 */ 4579566063dSJacob Faibussowitsch PetscCall(DMComputeL2Diff(dm, 0.0, exactFuncs, exactCtxs, u, error)); 4589566063dSJacob Faibussowitsch PetscCall(DMComputeL2GradientDiff(dm, 0.0, exactFuncDers, exactCtxs, u, n, errorDer)); 4599566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(dm, &u)); 4603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 461557cf195SMatthew G. Knepley } 462557cf195SMatthew G. Knepley 463d71ae5a4SJacob Faibussowitsch static PetscErrorCode CheckFunctions(DM dm, PetscInt order, AppCtx *user) 464d71ae5a4SJacob Faibussowitsch { 465*2a8381b2SBarry Smith PetscErrorCode (*exactFuncs[1])(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar *u, PetscCtx ctx); 466*2a8381b2SBarry Smith PetscErrorCode (*exactFuncDers[1])(PetscInt dim, PetscReal time, const PetscReal x[], const PetscReal n[], PetscInt Nf, PetscScalar *u, PetscCtx ctx); 467557cf195SMatthew G. Knepley void *exactCtxs[3]; 468557cf195SMatthew G. Knepley MPI_Comm comm; 469557cf195SMatthew G. Knepley PetscReal error, errorDer, tol = PETSC_SMALL; 470557cf195SMatthew G. Knepley 471557cf195SMatthew G. Knepley PetscFunctionBeginUser; 472557cf195SMatthew G. Knepley exactCtxs[0] = user; 473557cf195SMatthew G. Knepley exactCtxs[1] = user; 474557cf195SMatthew G. Knepley exactCtxs[2] = user; 475557cf195SMatthew G. Knepley user->constants[0] = 1.0; 476557cf195SMatthew G. Knepley user->constants[1] = 2.0; 477557cf195SMatthew G. Knepley user->constants[2] = 3.0; 4789566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 4799566063dSJacob Faibussowitsch PetscCall(SetupFunctions(dm, PETSC_TRUE, order, 0, exactFuncs, exactFuncDers, user)); 4809566063dSJacob Faibussowitsch PetscCall(ComputeError(dm, exactFuncs, exactFuncDers, exactCtxs, &error, &errorDer, user)); 481557cf195SMatthew G. Knepley /* Report result */ 48263a3b9bcSJacob Faibussowitsch if (error > tol) PetscCall(PetscPrintf(comm, "Function tests FAIL for order %" PetscInt_FMT " at tolerance %g error %g\n", order, (double)tol, (double)error)); 48363a3b9bcSJacob Faibussowitsch else PetscCall(PetscPrintf(comm, "Function tests pass for order %" PetscInt_FMT " at tolerance %g\n", order, (double)tol)); 48463a3b9bcSJacob Faibussowitsch if (errorDer > tol) PetscCall(PetscPrintf(comm, "Function tests FAIL for order %" PetscInt_FMT " derivatives at tolerance %g error %g\n", order, (double)tol, (double)errorDer)); 48563a3b9bcSJacob Faibussowitsch else PetscCall(PetscPrintf(comm, "Function tests pass for order %" PetscInt_FMT " derivatives at tolerance %g\n", order, (double)tol)); 4863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 487557cf195SMatthew G. Knepley } 488557cf195SMatthew G. Knepley 489557cf195SMatthew G. Knepley /* Compare approximation to exact in L_2 */ 490d71ae5a4SJacob Faibussowitsch static PetscErrorCode CheckTransferError(DM fdm, PetscBool usePoly, PetscInt order, PetscInt dir, const char *testname, Vec fu, AppCtx *user) 491d71ae5a4SJacob Faibussowitsch { 492*2a8381b2SBarry Smith PetscErrorCode (*exactFuncs[1])(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar *u, PetscCtx ctx); 493*2a8381b2SBarry Smith PetscErrorCode (*exactFuncDers[1])(PetscInt dim, PetscReal time, const PetscReal x[], const PetscReal n[], PetscInt Nf, PetscScalar *u, PetscCtx ctx); 494557cf195SMatthew G. Knepley PetscReal n[3] = {1.0, 1.0, 1.0}; 495557cf195SMatthew G. Knepley void *exactCtxs[3]; 496557cf195SMatthew G. Knepley MPI_Comm comm; 497557cf195SMatthew G. Knepley PetscReal error, errorDer, tol = PETSC_SMALL; 498557cf195SMatthew G. Knepley 499557cf195SMatthew G. Knepley PetscFunctionBeginUser; 500557cf195SMatthew G. Knepley exactCtxs[0] = user; 501557cf195SMatthew G. Knepley exactCtxs[1] = user; 502557cf195SMatthew G. Knepley exactCtxs[2] = user; 503557cf195SMatthew G. Knepley user->constants[0] = 1.0; 504557cf195SMatthew G. Knepley user->constants[1] = 2.0; 505557cf195SMatthew G. Knepley user->constants[2] = 3.0; 5069566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)fdm, &comm)); 5079566063dSJacob Faibussowitsch PetscCall(SetupFunctions(fdm, usePoly, order, dir, exactFuncs, exactFuncDers, user)); 50838cc584fSMatthew G. Knepley PetscCall(DMGetCoordinatesLocalSetUp(fdm)); 5099566063dSJacob Faibussowitsch PetscCall(DMComputeL2Diff(fdm, 0.0, exactFuncs, exactCtxs, fu, &error)); 5109566063dSJacob Faibussowitsch PetscCall(DMComputeL2GradientDiff(fdm, 0.0, exactFuncDers, exactCtxs, fu, n, &errorDer)); 511557cf195SMatthew G. Knepley /* Report result */ 51263a3b9bcSJacob Faibussowitsch if (error > tol) PetscCall(PetscPrintf(comm, "%s tests FAIL for order %" PetscInt_FMT " at tolerance %g error %g\n", testname, order, (double)tol, (double)error)); 51363a3b9bcSJacob Faibussowitsch else PetscCall(PetscPrintf(comm, "%s tests pass for order %" PetscInt_FMT " at tolerance %g\n", testname, order, (double)tol)); 51463a3b9bcSJacob Faibussowitsch if (errorDer > tol) PetscCall(PetscPrintf(comm, "%s tests FAIL for order %" PetscInt_FMT " derivatives at tolerance %g error %g\n", testname, order, (double)tol, (double)errorDer)); 51563a3b9bcSJacob Faibussowitsch else PetscCall(PetscPrintf(comm, "%s tests pass for order %" PetscInt_FMT " derivatives at tolerance %g\n", testname, order, (double)tol)); 5163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 517557cf195SMatthew G. Knepley } 518557cf195SMatthew G. Knepley 519d71ae5a4SJacob Faibussowitsch static PetscErrorCode CheckTransfer(DM dm, InterpType inType, PetscInt order, AppCtx *user) 520d71ae5a4SJacob Faibussowitsch { 521*2a8381b2SBarry Smith PetscErrorCode (*exactFuncs[1])(PetscInt, PetscReal, const PetscReal x[], PetscInt, PetscScalar *u, PetscCtx ctx); 522*2a8381b2SBarry Smith PetscErrorCode (*exactFuncDers[1])(PetscInt, PetscReal, const PetscReal x[], const PetscReal n[], PetscInt, PetscScalar *u, PetscCtx ctx); 523d6837840SMatthew G. Knepley void *exactCtxs[3]; 524d6837840SMatthew G. Knepley DM rdm = NULL, idm = NULL, fdm = NULL; 525557cf195SMatthew G. Knepley Mat Interp, InterpAdapt = NULL; 526d6837840SMatthew G. Knepley Vec iu, fu, scaling = NULL; 527557cf195SMatthew G. Knepley MPI_Comm comm; 528d6837840SMatthew G. Knepley const char *testname = "Unknown"; 529557cf195SMatthew G. Knepley char checkname[PETSC_MAX_PATH_LEN]; 530557cf195SMatthew G. Knepley 531557cf195SMatthew G. Knepley PetscFunctionBeginUser; 532d6837840SMatthew G. Knepley exactCtxs[0] = exactCtxs[1] = exactCtxs[2] = user; 5339566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 5349566063dSJacob Faibussowitsch PetscCall(DMRefine(dm, comm, &rdm)); 5359566063dSJacob Faibussowitsch PetscCall(DMViewFromOptions(rdm, NULL, "-ref_dm_view")); 5369566063dSJacob Faibussowitsch PetscCall(DMSetCoarseDM(rdm, dm)); 5379566063dSJacob Faibussowitsch PetscCall(DMCopyDisc(dm, rdm)); 538557cf195SMatthew G. Knepley switch (inType) { 539557cf195SMatthew G. Knepley case INTERPOLATION: 540557cf195SMatthew G. Knepley testname = "Interpolation"; 541557cf195SMatthew G. Knepley idm = dm; 542557cf195SMatthew G. Knepley fdm = rdm; 543557cf195SMatthew G. Knepley break; 544557cf195SMatthew G. Knepley case RESTRICTION: 545557cf195SMatthew G. Knepley testname = "Restriction"; 546557cf195SMatthew G. Knepley idm = rdm; 547557cf195SMatthew G. Knepley fdm = dm; 548557cf195SMatthew G. Knepley break; 549557cf195SMatthew G. Knepley case INJECTION: 550557cf195SMatthew G. Knepley testname = "Injection"; 551557cf195SMatthew G. Knepley idm = rdm; 552557cf195SMatthew G. Knepley fdm = dm; 553557cf195SMatthew G. Knepley break; 554557cf195SMatthew G. Knepley } 5559566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(idm, &iu)); 5569566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(fdm, &fu)); 5579566063dSJacob Faibussowitsch PetscCall(DMSetApplicationContext(dm, user)); 5589566063dSJacob Faibussowitsch PetscCall(DMSetApplicationContext(rdm, user)); 559557cf195SMatthew G. Knepley /* Project function into initial FE function space */ 5609566063dSJacob Faibussowitsch PetscCall(SetupFunctions(dm, PETSC_TRUE, order, 0, exactFuncs, exactFuncDers, user)); 5619566063dSJacob Faibussowitsch PetscCall(DMProjectFunction(idm, 0.0, exactFuncs, exactCtxs, INSERT_ALL_VALUES, iu)); 562557cf195SMatthew G. Knepley /* Interpolate function into final FE function space */ 563557cf195SMatthew G. Knepley switch (inType) { 564557cf195SMatthew G. Knepley case INTERPOLATION: 5659566063dSJacob Faibussowitsch PetscCall(DMCreateInterpolation(dm, rdm, &Interp, &scaling)); 5669566063dSJacob Faibussowitsch PetscCall(MatInterpolate(Interp, iu, fu)); 567557cf195SMatthew G. Knepley break; 568557cf195SMatthew G. Knepley case RESTRICTION: 5699566063dSJacob Faibussowitsch PetscCall(DMCreateInterpolation(dm, rdm, &Interp, &scaling)); 5709566063dSJacob Faibussowitsch PetscCall(MatRestrict(Interp, iu, fu)); 5719566063dSJacob Faibussowitsch PetscCall(VecPointwiseMult(fu, scaling, fu)); 572557cf195SMatthew G. Knepley break; 573557cf195SMatthew G. Knepley case INJECTION: 5749566063dSJacob Faibussowitsch PetscCall(DMCreateInjection(dm, rdm, &Interp)); 5759566063dSJacob Faibussowitsch PetscCall(MatRestrict(Interp, iu, fu)); 576557cf195SMatthew G. Knepley break; 577557cf195SMatthew G. Knepley } 5789566063dSJacob Faibussowitsch PetscCall(CheckTransferError(fdm, PETSC_TRUE, order, 0, testname, fu, user)); 579557cf195SMatthew G. Knepley if (user->K && (inType == INTERPOLATION)) { 580557cf195SMatthew G. Knepley KSP smoother; 5812b3cbbdaSStefano Zampini Mat A, iVM, fVM; 5822b3cbbdaSStefano Zampini Vec iV, fV; 5832b3cbbdaSStefano Zampini PetscInt k, dim, d, im, fm; 584557cf195SMatthew G. Knepley 5859566063dSJacob Faibussowitsch PetscCall(PetscPrintf(comm, " Adapting interpolator using %s\n", user->usePoly ? "polynomials" : "harmonics")); 5869566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 587557cf195SMatthew G. Knepley /* Project coarse modes into initial and final FE function space */ 5882b3cbbdaSStefano Zampini PetscCall(DMGetGlobalVector(idm, &iV)); 5892b3cbbdaSStefano Zampini PetscCall(DMGetGlobalVector(fdm, &fV)); 5902b3cbbdaSStefano Zampini PetscCall(VecGetLocalSize(iV, &im)); 5912b3cbbdaSStefano Zampini PetscCall(VecGetLocalSize(fV, &fm)); 5922b3cbbdaSStefano Zampini PetscCall(MatCreateDense(PetscObjectComm((PetscObject)dm), im, PETSC_DECIDE, PETSC_DECIDE, user->K * dim, NULL, &iVM)); 5932b3cbbdaSStefano Zampini PetscCall(MatCreateDense(PetscObjectComm((PetscObject)dm), fm, PETSC_DECIDE, PETSC_DECIDE, user->K * dim, NULL, &fVM)); 5942b3cbbdaSStefano Zampini PetscCall(DMRestoreGlobalVector(idm, &iV)); 5952b3cbbdaSStefano Zampini PetscCall(DMRestoreGlobalVector(fdm, &fV)); 596557cf195SMatthew G. Knepley for (k = 0; k < user->K; ++k) { 597557cf195SMatthew G. Knepley for (d = 0; d < dim; ++d) { 5982b3cbbdaSStefano Zampini PetscCall(MatDenseGetColumnVecWrite(iVM, k * dim + d, &iV)); 5992b3cbbdaSStefano Zampini PetscCall(MatDenseGetColumnVecWrite(fVM, k * dim + d, &fV)); 6009566063dSJacob Faibussowitsch PetscCall(SetupFunctions(idm, user->usePoly, user->usePoly ? k : k + 1, d, exactFuncs, exactFuncDers, user)); 6012b3cbbdaSStefano Zampini PetscCall(DMProjectFunction(idm, 0.0, exactFuncs, exactCtxs, INSERT_ALL_VALUES, iV)); 6022b3cbbdaSStefano Zampini PetscCall(DMProjectFunction(fdm, 0.0, exactFuncs, exactCtxs, INSERT_ALL_VALUES, fV)); 6032b3cbbdaSStefano Zampini PetscCall(MatDenseRestoreColumnVecWrite(iVM, k * dim + d, &iV)); 6042b3cbbdaSStefano Zampini PetscCall(MatDenseRestoreColumnVecWrite(fVM, k * dim + d, &fV)); 605557cf195SMatthew G. Knepley } 606557cf195SMatthew G. Knepley } 6072b3cbbdaSStefano Zampini 608557cf195SMatthew G. Knepley /* Adapt interpolator */ 6099566063dSJacob Faibussowitsch PetscCall(DMCreateMatrix(rdm, &A)); 6109566063dSJacob Faibussowitsch PetscCall(MatShift(A, 1.0)); 6119566063dSJacob Faibussowitsch PetscCall(KSPCreate(comm, &smoother)); 6129566063dSJacob Faibussowitsch PetscCall(KSPSetFromOptions(smoother)); 6139566063dSJacob Faibussowitsch PetscCall(KSPSetOperators(smoother, A, A)); 6142b3cbbdaSStefano Zampini PetscCall(DMAdaptInterpolator(dm, rdm, Interp, smoother, fVM, iVM, &InterpAdapt, user)); 615557cf195SMatthew G. Knepley /* Interpolate function into final FE function space */ 6169566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(checkname, PETSC_MAX_PATH_LEN, " %s poly", testname)); 6179566063dSJacob Faibussowitsch PetscCall(MatInterpolate(InterpAdapt, iu, fu)); 6189566063dSJacob Faibussowitsch PetscCall(CheckTransferError(fdm, PETSC_TRUE, order, 0, checkname, fu, user)); 619557cf195SMatthew G. Knepley for (k = 0; k < user->K; ++k) { 620557cf195SMatthew G. Knepley for (d = 0; d < dim; ++d) { 62163a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(checkname, PETSC_MAX_PATH_LEN, " %s trig (%" PetscInt_FMT ", %" PetscInt_FMT ")", testname, k, d)); 6222b3cbbdaSStefano Zampini PetscCall(MatDenseGetColumnVecRead(iVM, k * dim + d, &iV)); 6232b3cbbdaSStefano Zampini PetscCall(MatDenseGetColumnVecWrite(fVM, k * dim + d, &fV)); 6242b3cbbdaSStefano Zampini PetscCall(MatInterpolate(InterpAdapt, iV, fV)); 6252b3cbbdaSStefano Zampini PetscCall(CheckTransferError(fdm, PETSC_FALSE, k + 1, d, checkname, fV, user)); 6262b3cbbdaSStefano Zampini PetscCall(MatDenseRestoreColumnVecRead(iVM, k * dim + d, &iV)); 6272b3cbbdaSStefano Zampini PetscCall(MatDenseRestoreColumnVecWrite(fVM, k * dim + d, &fV)); 628557cf195SMatthew G. Knepley } 629557cf195SMatthew G. Knepley } 630557cf195SMatthew G. Knepley /* Cleanup */ 6319566063dSJacob Faibussowitsch PetscCall(KSPDestroy(&smoother)); 6329566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 6339566063dSJacob Faibussowitsch PetscCall(MatDestroy(&InterpAdapt)); 6342b3cbbdaSStefano Zampini PetscCall(MatDestroy(&iVM)); 6352b3cbbdaSStefano Zampini PetscCall(MatDestroy(&fVM)); 636557cf195SMatthew G. Knepley } 6379566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(idm, &iu)); 6389566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(fdm, &fu)); 6399566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Interp)); 6409566063dSJacob Faibussowitsch PetscCall(VecDestroy(&scaling)); 6419566063dSJacob Faibussowitsch PetscCall(DMDestroy(&rdm)); 6423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 643557cf195SMatthew G. Knepley } 644557cf195SMatthew G. Knepley 645d71ae5a4SJacob Faibussowitsch int main(int argc, char **argv) 646d71ae5a4SJacob Faibussowitsch { 647557cf195SMatthew G. Knepley DM dm; 64830602db0SMatthew G. Knepley PetscFE fe; 64930602db0SMatthew G. Knepley AppCtx user; 65030602db0SMatthew G. Knepley PetscInt dim; 65130602db0SMatthew G. Knepley PetscBool simplex; 652557cf195SMatthew G. Knepley 653327415f7SBarry Smith PetscFunctionBeginUser; 6549566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 6559566063dSJacob Faibussowitsch PetscCall(ProcessOptions(PETSC_COMM_WORLD, &user)); 6569566063dSJacob Faibussowitsch PetscCall(CreateMesh(PETSC_COMM_WORLD, &user, &dm)); 65730602db0SMatthew G. Knepley 6589566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 6599566063dSJacob Faibussowitsch PetscCall(DMPlexIsSimplex(dm, &simplex)); 6609566063dSJacob Faibussowitsch PetscCall(PetscFECreateDefault(PETSC_COMM_WORLD, dim, user.Nc < 0 ? dim : user.Nc, simplex, NULL, user.qorder, &fe)); 6619566063dSJacob Faibussowitsch PetscCall(DMSetField(dm, 0, NULL, (PetscObject)fe)); 6629566063dSJacob Faibussowitsch PetscCall(PetscFEDestroy(&fe)); 6639566063dSJacob Faibussowitsch PetscCall(DMCreateDS(dm)); 66430602db0SMatthew G. Knepley 6659566063dSJacob Faibussowitsch PetscCall(CheckFunctions(dm, user.porder, &user)); 6669566063dSJacob Faibussowitsch PetscCall(CheckTransfer(dm, INTERPOLATION, user.porder, &user)); 6679566063dSJacob Faibussowitsch PetscCall(CheckTransfer(dm, INJECTION, user.porder, &user)); 6689566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm)); 6699566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 670b122ec5aSJacob Faibussowitsch return 0; 671557cf195SMatthew G. Knepley } 672557cf195SMatthew G. Knepley 673557cf195SMatthew G. Knepley /*TEST 674557cf195SMatthew G. Knepley 675557cf195SMatthew G. Knepley # TODO dim 3 will not work until I get composite elements in 3D (see plexrefine.c:34) 676557cf195SMatthew G. Knepley # 2D/3D P_1 on a simplex 677557cf195SMatthew G. Knepley test: 678557cf195SMatthew G. Knepley suffix: p1 679557cf195SMatthew G. Knepley requires: triangle ctetgen 68030602db0SMatthew G. Knepley args: -dm_plex_dim {{2}separate output} -dm_plex_box_faces 2,2,2 -petscspace_degree 1 -num_comp 1 -qorder 1 -porder {{1}separate output} 681557cf195SMatthew G. Knepley test: 682557cf195SMatthew G. Knepley suffix: p1_pragmatic 683557cf195SMatthew G. Knepley requires: triangle ctetgen pragmatic 68430602db0SMatthew G. Knepley args: -dm_plex_dim {{2}separate output} -dm_plex_box_faces 2,2,2 -petscspace_degree 1 -qorder 1 -dm_plex_hash_location -porder {{1 2}separate output} 685557cf195SMatthew G. Knepley test: 686557cf195SMatthew G. Knepley suffix: p1_adapt 687557cf195SMatthew G. Knepley requires: triangle ctetgen 68830602db0SMatthew G. Knepley args: -dm_plex_dim {{2}separate output} -dm_plex_box_faces 2,2,2 -dm_refine 3 -petscspace_degree 1 -qorder 1 -porder {{1 2}separate output} 689557cf195SMatthew G. Knepley 690557cf195SMatthew G. Knepley # TODO dim 3 will not work until I get composite elements in 3D (see plexrefine.c:34) 691557cf195SMatthew G. Knepley # 2D/3D P_2 on a simplex 692557cf195SMatthew G. Knepley test: 693557cf195SMatthew G. Knepley suffix: p2 694557cf195SMatthew G. Knepley requires: triangle ctetgen 69530602db0SMatthew G. Knepley args: -dm_plex_dim {{2}separate output} -dm_plex_box_faces 2,2,2 -petscspace_degree 2 -qorder 2 -porder {{1 2 3}separate output} 696557cf195SMatthew G. Knepley test: 697557cf195SMatthew G. Knepley suffix: p2_pragmatic 698557cf195SMatthew G. Knepley requires: triangle ctetgen pragmatic 69930602db0SMatthew G. Knepley args: -dm_plex_dim {{2}separate output} -dm_plex_box_faces 2,2,2 -petscspace_degree 2 -qorder 2 -dm_plex_hash_location -porder {{1 2 3}separate output} 700557cf195SMatthew G. Knepley 701557cf195SMatthew G. Knepley # TODO dim 3 will not work until I get composite elements in 3D (see plexrefine.c:34) 702557cf195SMatthew G. Knepley # TODO This is broken. Check ex3 which worked 703557cf195SMatthew G. Knepley # 2D/3D P_3 on a simplex 704557cf195SMatthew G. Knepley test: 705d6837840SMatthew G. Knepley TODO: gll Lagrange nodes break this 706557cf195SMatthew G. Knepley suffix: p3 707557cf195SMatthew G. Knepley requires: triangle ctetgen !single 70830602db0SMatthew G. Knepley args: -dm_plex_dim {{2}separate output} -dm_plex_box_faces 2,2,2 -petscspace_degree 3 -qorder 3 -porder {{1 2 3 4}separate output} 709557cf195SMatthew G. Knepley test: 710d6837840SMatthew G. Knepley TODO: gll Lagrange nodes break this 711557cf195SMatthew G. Knepley suffix: p3_pragmatic 712557cf195SMatthew G. Knepley requires: triangle ctetgen pragmatic !single 71330602db0SMatthew G. Knepley args: -dm_plex_dim {{2}separate output} -dm_plex_box_faces 2,2,2 -petscspace_degree 3 -qorder 3 -dm_plex_hash_location -porder {{1 2 3 4}separate output} 714557cf195SMatthew G. Knepley 715557cf195SMatthew G. Knepley # 2D/3D Q_1 on a tensor cell 716557cf195SMatthew G. Knepley test: 717557cf195SMatthew G. Knepley suffix: q1 71830602db0SMatthew G. Knepley args: -dm_plex_dim {{2 3}separate output} -dm_plex_box_faces 2,2,2 -dm_plex_simplex 0 -petscspace_degree 1 -qorder 1 -porder {{1 2}separate output} 719557cf195SMatthew G. Knepley 720557cf195SMatthew G. Knepley # 2D/3D Q_2 on a tensor cell 721557cf195SMatthew G. Knepley test: 722557cf195SMatthew G. Knepley suffix: q2 72399a192c5SJunchao Zhang requires: !single 72430602db0SMatthew G. Knepley args: -dm_plex_dim {{2 3}separate output} -dm_plex_box_faces 2,2,2 -dm_plex_simplex 0 -petscspace_degree 2 -qorder 2 -porder {{1 2 3}separate output} 725557cf195SMatthew G. Knepley 726557cf195SMatthew G. Knepley # 2D/3D Q_3 on a tensor cell 727557cf195SMatthew G. Knepley test: 728d6837840SMatthew G. Knepley TODO: gll Lagrange nodes break this 729557cf195SMatthew G. Knepley suffix: q3 73099a192c5SJunchao Zhang requires: !single 73130602db0SMatthew G. Knepley args: -dm_plex_dim {{2 3}separate output} -dm_plex_box_faces 2,2,2 -dm_plex_simplex 0 -petscspace_degree 3 -qorder 3 -porder {{1 2 3 4}separate output} 732557cf195SMatthew G. Knepley 733557cf195SMatthew G. Knepley # 2D/3D P_1disc on a triangle/quadrilateral 734557cf195SMatthew G. Knepley # TODO Missing injection functional for simplices 735557cf195SMatthew G. Knepley test: 736557cf195SMatthew G. Knepley suffix: p1d 737557cf195SMatthew G. Knepley requires: triangle ctetgen 73830602db0SMatthew G. Knepley args: -dm_plex_dim {{2}separate output} -dm_plex_box_faces 2,2,2 -dm_plex_simplex {{0}separate output} -petscspace_degree 1 -petscdualspace_lagrange_continuity 0 -qorder 1 -porder {{1 2}separate output} 739557cf195SMatthew G. Knepley 740557cf195SMatthew G. Knepley TEST*/ 741