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*d71ae5a4SJacob Faibussowitsch PetscErrorCode constant(PetscInt dim, PetscReal time, const PetscReal coords[], PetscInt Nc, PetscScalar *u, void *ctx) 150*d71ae5a4SJacob 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 } 159557cf195SMatthew G. Knepley return 0; 160557cf195SMatthew G. Knepley } 161*d71ae5a4SJacob Faibussowitsch PetscErrorCode constantDer(PetscInt dim, PetscReal time, const PetscReal coords[], const PetscReal n[], PetscInt Nc, PetscScalar *u, void *ctx) 162*d71ae5a4SJacob 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 } 171557cf195SMatthew G. Knepley return 0; 172557cf195SMatthew G. Knepley } 173557cf195SMatthew G. Knepley 174557cf195SMatthew G. Knepley /* u = x */ 175*d71ae5a4SJacob Faibussowitsch PetscErrorCode linear(PetscInt dim, PetscReal time, const PetscReal coords[], PetscInt Nc, PetscScalar *u, void *ctx) 176*d71ae5a4SJacob 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 } 185557cf195SMatthew G. Knepley return 0; 186557cf195SMatthew G. Knepley } 187*d71ae5a4SJacob Faibussowitsch PetscErrorCode linearDer(PetscInt dim, PetscReal time, const PetscReal coords[], const PetscReal n[], PetscInt Nc, PetscScalar *u, void *ctx) 188*d71ae5a4SJacob 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 } 201557cf195SMatthew G. Knepley return 0; 202557cf195SMatthew G. Knepley } 203557cf195SMatthew G. Knepley 204557cf195SMatthew G. Knepley /* u = x^2 or u = (x^2, xy) or u = (xy, yz, zx) */ 205*d71ae5a4SJacob Faibussowitsch PetscErrorCode quadratic(PetscInt dim, PetscReal time, const PetscReal coords[], PetscInt Nc, PetscScalar *u, void *ctx) 206*d71ae5a4SJacob 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 } 222557cf195SMatthew G. Knepley return 0; 223557cf195SMatthew G. Knepley } 224*d71ae5a4SJacob Faibussowitsch PetscErrorCode quadraticDer(PetscInt dim, PetscReal time, const PetscReal coords[], const PetscReal n[], PetscInt Nc, PetscScalar *u, void *ctx) 225*d71ae5a4SJacob 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 } 241557cf195SMatthew G. Knepley return 0; 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*d71ae5a4SJacob Faibussowitsch PetscErrorCode cubic(PetscInt dim, PetscReal time, const PetscReal coords[], PetscInt Nc, PetscScalar *u, void *ctx) 246*d71ae5a4SJacob 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 } 262557cf195SMatthew G. Knepley return 0; 263557cf195SMatthew G. Knepley } 264*d71ae5a4SJacob Faibussowitsch PetscErrorCode cubicDer(PetscInt dim, PetscReal time, const PetscReal coords[], const PetscReal n[], PetscInt Nc, PetscScalar *u, void *ctx) 265*d71ae5a4SJacob 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 } 281557cf195SMatthew G. Knepley return 0; 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*d71ae5a4SJacob Faibussowitsch PetscErrorCode quartic(PetscInt dim, PetscReal time, const PetscReal coords[], PetscInt Nc, PetscScalar *u, void *ctx) 286*d71ae5a4SJacob 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 } 302557cf195SMatthew G. Knepley return 0; 303557cf195SMatthew G. Knepley } 304*d71ae5a4SJacob Faibussowitsch PetscErrorCode quarticDer(PetscInt dim, PetscReal time, const PetscReal coords[], const PetscReal n[], PetscInt Nc, PetscScalar *u, void *ctx) 305*d71ae5a4SJacob 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 } 321557cf195SMatthew G. Knepley return 0; 322557cf195SMatthew G. Knepley } 323557cf195SMatthew G. Knepley 324*d71ae5a4SJacob Faibussowitsch PetscErrorCode mytanh(PetscInt dim, PetscReal time, const PetscReal coords[], PetscInt Nc, PetscScalar *u, void *ctx) 325*d71ae5a4SJacob 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 } 334557cf195SMatthew G. Knepley return 0; 335557cf195SMatthew G. Knepley } 336*d71ae5a4SJacob Faibussowitsch PetscErrorCode mytanhDer(PetscInt dim, PetscReal time, const PetscReal coords[], const PetscReal n[], PetscInt Nc, PetscScalar *u, void *ctx) 337*d71ae5a4SJacob 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 } 346557cf195SMatthew G. Knepley return 0; 347557cf195SMatthew G. Knepley } 348557cf195SMatthew G. Knepley 349*d71ae5a4SJacob Faibussowitsch PetscErrorCode trig(PetscInt dim, PetscReal time, const PetscReal coords[], PetscInt Nc, PetscScalar *u, void *ctx) 350*d71ae5a4SJacob 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 } 359557cf195SMatthew G. Knepley return 0; 360557cf195SMatthew G. Knepley } 361*d71ae5a4SJacob Faibussowitsch PetscErrorCode trigDer(PetscInt dim, PetscReal time, const PetscReal coords[], const PetscReal n[], PetscInt Nc, PetscScalar *u, void *ctx) 362*d71ae5a4SJacob 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 } 371557cf195SMatthew G. Knepley return 0; 372557cf195SMatthew G. Knepley } 373557cf195SMatthew G. Knepley 374*d71ae5a4SJacob Faibussowitsch static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options) 375*d71ae5a4SJacob 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(); 392557cf195SMatthew G. Knepley PetscFunctionReturn(0); 393557cf195SMatthew G. Knepley } 394557cf195SMatthew G. Knepley 395*d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm) 396*d71ae5a4SJacob 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")); 402557cf195SMatthew G. Knepley PetscFunctionReturn(0); 403557cf195SMatthew G. Knepley } 404557cf195SMatthew G. Knepley 405557cf195SMatthew G. Knepley /* Setup functions to approximate */ 406*d71ae5a4SJacob 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) 407*d71ae5a4SJacob 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; 434*d71ae5a4SJacob Faibussowitsch default: 435*d71ae5a4SJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 436*d71ae5a4SJacob 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 } 443557cf195SMatthew G. Knepley PetscFunctionReturn(0); 444557cf195SMatthew G. Knepley } 445557cf195SMatthew G. Knepley 446*d71ae5a4SJacob 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) 447*d71ae5a4SJacob 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)); 460557cf195SMatthew G. Knepley PetscFunctionReturn(0); 461557cf195SMatthew G. Knepley } 462557cf195SMatthew G. Knepley 463*d71ae5a4SJacob Faibussowitsch static PetscErrorCode CheckFunctions(DM dm, PetscInt order, AppCtx *user) 464*d71ae5a4SJacob Faibussowitsch { 465557cf195SMatthew G. Knepley PetscErrorCode (*exactFuncs[1])(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar *u, void *ctx); 466557cf195SMatthew G. Knepley PetscErrorCode (*exactFuncDers[1])(PetscInt dim, PetscReal time, const PetscReal x[], const PetscReal n[], PetscInt Nf, PetscScalar *u, void *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)); 486557cf195SMatthew G. Knepley PetscFunctionReturn(0); 487557cf195SMatthew G. Knepley } 488557cf195SMatthew G. Knepley 489557cf195SMatthew G. Knepley /* Compare approximation to exact in L_2 */ 490*d71ae5a4SJacob Faibussowitsch static PetscErrorCode CheckTransferError(DM fdm, PetscBool usePoly, PetscInt order, PetscInt dir, const char *testname, Vec fu, AppCtx *user) 491*d71ae5a4SJacob Faibussowitsch { 492557cf195SMatthew G. Knepley PetscErrorCode (*exactFuncs[1])(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar *u, void *ctx); 493557cf195SMatthew G. Knepley PetscErrorCode (*exactFuncDers[1])(PetscInt dim, PetscReal time, const PetscReal x[], const PetscReal n[], PetscInt Nf, PetscScalar *u, void *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)); 5089566063dSJacob Faibussowitsch PetscCall(DMComputeL2Diff(fdm, 0.0, exactFuncs, exactCtxs, fu, &error)); 5099566063dSJacob Faibussowitsch PetscCall(DMComputeL2GradientDiff(fdm, 0.0, exactFuncDers, exactCtxs, fu, n, &errorDer)); 510557cf195SMatthew G. Knepley /* Report result */ 51163a3b9bcSJacob 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)); 51263a3b9bcSJacob Faibussowitsch else PetscCall(PetscPrintf(comm, "%s tests pass for order %" PetscInt_FMT " at tolerance %g\n", testname, order, (double)tol)); 51363a3b9bcSJacob 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)); 51463a3b9bcSJacob Faibussowitsch else PetscCall(PetscPrintf(comm, "%s tests pass for order %" PetscInt_FMT " derivatives at tolerance %g\n", testname, order, (double)tol)); 515557cf195SMatthew G. Knepley PetscFunctionReturn(0); 516557cf195SMatthew G. Knepley } 517557cf195SMatthew G. Knepley 518*d71ae5a4SJacob Faibussowitsch static PetscErrorCode CheckTransfer(DM dm, InterpType inType, PetscInt order, AppCtx *user) 519*d71ae5a4SJacob Faibussowitsch { 520557cf195SMatthew G. Knepley PetscErrorCode (*exactFuncs[1])(PetscInt, PetscReal, const PetscReal x[], PetscInt, PetscScalar *u, void *ctx); 521557cf195SMatthew G. Knepley PetscErrorCode (*exactFuncDers[1])(PetscInt, PetscReal, const PetscReal x[], const PetscReal n[], PetscInt, PetscScalar *u, void *ctx); 522d6837840SMatthew G. Knepley void *exactCtxs[3]; 523d6837840SMatthew G. Knepley DM rdm = NULL, idm = NULL, fdm = NULL; 524557cf195SMatthew G. Knepley Mat Interp, InterpAdapt = NULL; 525d6837840SMatthew G. Knepley Vec iu, fu, scaling = NULL; 526557cf195SMatthew G. Knepley MPI_Comm comm; 527d6837840SMatthew G. Knepley const char *testname = "Unknown"; 528557cf195SMatthew G. Knepley char checkname[PETSC_MAX_PATH_LEN]; 529557cf195SMatthew G. Knepley 530557cf195SMatthew G. Knepley PetscFunctionBeginUser; 531d6837840SMatthew G. Knepley exactCtxs[0] = exactCtxs[1] = exactCtxs[2] = user; 5329566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 5339566063dSJacob Faibussowitsch PetscCall(DMRefine(dm, comm, &rdm)); 5349566063dSJacob Faibussowitsch PetscCall(DMViewFromOptions(rdm, NULL, "-ref_dm_view")); 5359566063dSJacob Faibussowitsch PetscCall(DMSetCoarseDM(rdm, dm)); 5369566063dSJacob Faibussowitsch PetscCall(DMCopyDisc(dm, rdm)); 537557cf195SMatthew G. Knepley switch (inType) { 538557cf195SMatthew G. Knepley case INTERPOLATION: 539557cf195SMatthew G. Knepley testname = "Interpolation"; 540557cf195SMatthew G. Knepley idm = dm; 541557cf195SMatthew G. Knepley fdm = rdm; 542557cf195SMatthew G. Knepley break; 543557cf195SMatthew G. Knepley case RESTRICTION: 544557cf195SMatthew G. Knepley testname = "Restriction"; 545557cf195SMatthew G. Knepley idm = rdm; 546557cf195SMatthew G. Knepley fdm = dm; 547557cf195SMatthew G. Knepley break; 548557cf195SMatthew G. Knepley case INJECTION: 549557cf195SMatthew G. Knepley testname = "Injection"; 550557cf195SMatthew G. Knepley idm = rdm; 551557cf195SMatthew G. Knepley fdm = dm; 552557cf195SMatthew G. Knepley break; 553557cf195SMatthew G. Knepley } 5549566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(idm, &iu)); 5559566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(fdm, &fu)); 5569566063dSJacob Faibussowitsch PetscCall(DMSetApplicationContext(dm, user)); 5579566063dSJacob Faibussowitsch PetscCall(DMSetApplicationContext(rdm, user)); 558557cf195SMatthew G. Knepley /* Project function into initial FE function space */ 5599566063dSJacob Faibussowitsch PetscCall(SetupFunctions(dm, PETSC_TRUE, order, 0, exactFuncs, exactFuncDers, user)); 5609566063dSJacob Faibussowitsch PetscCall(DMProjectFunction(idm, 0.0, exactFuncs, exactCtxs, INSERT_ALL_VALUES, iu)); 561557cf195SMatthew G. Knepley /* Interpolate function into final FE function space */ 562557cf195SMatthew G. Knepley switch (inType) { 563557cf195SMatthew G. Knepley case INTERPOLATION: 5649566063dSJacob Faibussowitsch PetscCall(DMCreateInterpolation(dm, rdm, &Interp, &scaling)); 5659566063dSJacob Faibussowitsch PetscCall(MatInterpolate(Interp, iu, fu)); 566557cf195SMatthew G. Knepley break; 567557cf195SMatthew G. Knepley case RESTRICTION: 5689566063dSJacob Faibussowitsch PetscCall(DMCreateInterpolation(dm, rdm, &Interp, &scaling)); 5699566063dSJacob Faibussowitsch PetscCall(MatRestrict(Interp, iu, fu)); 5709566063dSJacob Faibussowitsch PetscCall(VecPointwiseMult(fu, scaling, fu)); 571557cf195SMatthew G. Knepley break; 572557cf195SMatthew G. Knepley case INJECTION: 5739566063dSJacob Faibussowitsch PetscCall(DMCreateInjection(dm, rdm, &Interp)); 5749566063dSJacob Faibussowitsch PetscCall(MatRestrict(Interp, iu, fu)); 575557cf195SMatthew G. Knepley break; 576557cf195SMatthew G. Knepley } 5779566063dSJacob Faibussowitsch PetscCall(CheckTransferError(fdm, PETSC_TRUE, order, 0, testname, fu, user)); 578557cf195SMatthew G. Knepley if (user->K && (inType == INTERPOLATION)) { 579557cf195SMatthew G. Knepley KSP smoother; 5802b3cbbdaSStefano Zampini Mat A, iVM, fVM; 5812b3cbbdaSStefano Zampini Vec iV, fV; 5822b3cbbdaSStefano Zampini PetscInt k, dim, d, im, fm; 583557cf195SMatthew G. Knepley 5849566063dSJacob Faibussowitsch PetscCall(PetscPrintf(comm, " Adapting interpolator using %s\n", user->usePoly ? "polynomials" : "harmonics")); 5859566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 586557cf195SMatthew G. Knepley /* Project coarse modes into initial and final FE function space */ 5872b3cbbdaSStefano Zampini PetscCall(DMGetGlobalVector(idm, &iV)); 5882b3cbbdaSStefano Zampini PetscCall(DMGetGlobalVector(fdm, &fV)); 5892b3cbbdaSStefano Zampini PetscCall(VecGetLocalSize(iV, &im)); 5902b3cbbdaSStefano Zampini PetscCall(VecGetLocalSize(fV, &fm)); 5912b3cbbdaSStefano Zampini PetscCall(MatCreateDense(PetscObjectComm((PetscObject)dm), im, PETSC_DECIDE, PETSC_DECIDE, user->K * dim, NULL, &iVM)); 5922b3cbbdaSStefano Zampini PetscCall(MatCreateDense(PetscObjectComm((PetscObject)dm), fm, PETSC_DECIDE, PETSC_DECIDE, user->K * dim, NULL, &fVM)); 5932b3cbbdaSStefano Zampini PetscCall(DMRestoreGlobalVector(idm, &iV)); 5942b3cbbdaSStefano Zampini PetscCall(DMRestoreGlobalVector(fdm, &fV)); 595557cf195SMatthew G. Knepley for (k = 0; k < user->K; ++k) { 596557cf195SMatthew G. Knepley for (d = 0; d < dim; ++d) { 5972b3cbbdaSStefano Zampini PetscCall(MatDenseGetColumnVecWrite(iVM, k * dim + d, &iV)); 5982b3cbbdaSStefano Zampini PetscCall(MatDenseGetColumnVecWrite(fVM, k * dim + d, &fV)); 5999566063dSJacob Faibussowitsch PetscCall(SetupFunctions(idm, user->usePoly, user->usePoly ? k : k + 1, d, exactFuncs, exactFuncDers, user)); 6002b3cbbdaSStefano Zampini PetscCall(DMProjectFunction(idm, 0.0, exactFuncs, exactCtxs, INSERT_ALL_VALUES, iV)); 6012b3cbbdaSStefano Zampini PetscCall(DMProjectFunction(fdm, 0.0, exactFuncs, exactCtxs, INSERT_ALL_VALUES, fV)); 6022b3cbbdaSStefano Zampini PetscCall(MatDenseRestoreColumnVecWrite(iVM, k * dim + d, &iV)); 6032b3cbbdaSStefano Zampini PetscCall(MatDenseRestoreColumnVecWrite(fVM, k * dim + d, &fV)); 604557cf195SMatthew G. Knepley } 605557cf195SMatthew G. Knepley } 6062b3cbbdaSStefano Zampini 607557cf195SMatthew G. Knepley /* Adapt interpolator */ 6089566063dSJacob Faibussowitsch PetscCall(DMCreateMatrix(rdm, &A)); 6099566063dSJacob Faibussowitsch PetscCall(MatShift(A, 1.0)); 6109566063dSJacob Faibussowitsch PetscCall(KSPCreate(comm, &smoother)); 6119566063dSJacob Faibussowitsch PetscCall(KSPSetFromOptions(smoother)); 6129566063dSJacob Faibussowitsch PetscCall(KSPSetOperators(smoother, A, A)); 6132b3cbbdaSStefano Zampini PetscCall(DMAdaptInterpolator(dm, rdm, Interp, smoother, fVM, iVM, &InterpAdapt, user)); 614557cf195SMatthew G. Knepley /* Interpolate function into final FE function space */ 6159566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(checkname, PETSC_MAX_PATH_LEN, " %s poly", testname)); 6169566063dSJacob Faibussowitsch PetscCall(MatInterpolate(InterpAdapt, iu, fu)); 6179566063dSJacob Faibussowitsch PetscCall(CheckTransferError(fdm, PETSC_TRUE, order, 0, checkname, fu, user)); 618557cf195SMatthew G. Knepley for (k = 0; k < user->K; ++k) { 619557cf195SMatthew G. Knepley for (d = 0; d < dim; ++d) { 62063a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(checkname, PETSC_MAX_PATH_LEN, " %s trig (%" PetscInt_FMT ", %" PetscInt_FMT ")", testname, k, d)); 6212b3cbbdaSStefano Zampini PetscCall(MatDenseGetColumnVecRead(iVM, k * dim + d, &iV)); 6222b3cbbdaSStefano Zampini PetscCall(MatDenseGetColumnVecWrite(fVM, k * dim + d, &fV)); 6232b3cbbdaSStefano Zampini PetscCall(MatInterpolate(InterpAdapt, iV, fV)); 6242b3cbbdaSStefano Zampini PetscCall(CheckTransferError(fdm, PETSC_FALSE, k + 1, d, checkname, fV, user)); 6252b3cbbdaSStefano Zampini PetscCall(MatDenseRestoreColumnVecRead(iVM, k * dim + d, &iV)); 6262b3cbbdaSStefano Zampini PetscCall(MatDenseRestoreColumnVecWrite(fVM, k * dim + d, &fV)); 627557cf195SMatthew G. Knepley } 628557cf195SMatthew G. Knepley } 629557cf195SMatthew G. Knepley /* Cleanup */ 6309566063dSJacob Faibussowitsch PetscCall(KSPDestroy(&smoother)); 6319566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 6329566063dSJacob Faibussowitsch PetscCall(MatDestroy(&InterpAdapt)); 6332b3cbbdaSStefano Zampini PetscCall(MatDestroy(&iVM)); 6342b3cbbdaSStefano Zampini PetscCall(MatDestroy(&fVM)); 635557cf195SMatthew G. Knepley } 6369566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(idm, &iu)); 6379566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(fdm, &fu)); 6389566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Interp)); 6399566063dSJacob Faibussowitsch PetscCall(VecDestroy(&scaling)); 6409566063dSJacob Faibussowitsch PetscCall(DMDestroy(&rdm)); 641557cf195SMatthew G. Knepley PetscFunctionReturn(0); 642557cf195SMatthew G. Knepley } 643557cf195SMatthew G. Knepley 644*d71ae5a4SJacob Faibussowitsch int main(int argc, char **argv) 645*d71ae5a4SJacob Faibussowitsch { 646557cf195SMatthew G. Knepley DM dm; 64730602db0SMatthew G. Knepley PetscFE fe; 64830602db0SMatthew G. Knepley AppCtx user; 64930602db0SMatthew G. Knepley PetscInt dim; 65030602db0SMatthew G. Knepley PetscBool simplex; 651557cf195SMatthew G. Knepley 652327415f7SBarry Smith PetscFunctionBeginUser; 6539566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 6549566063dSJacob Faibussowitsch PetscCall(ProcessOptions(PETSC_COMM_WORLD, &user)); 6559566063dSJacob Faibussowitsch PetscCall(CreateMesh(PETSC_COMM_WORLD, &user, &dm)); 65630602db0SMatthew G. Knepley 6579566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 6589566063dSJacob Faibussowitsch PetscCall(DMPlexIsSimplex(dm, &simplex)); 6599566063dSJacob Faibussowitsch PetscCall(PetscFECreateDefault(PETSC_COMM_WORLD, dim, user.Nc < 0 ? dim : user.Nc, simplex, NULL, user.qorder, &fe)); 6609566063dSJacob Faibussowitsch PetscCall(DMSetField(dm, 0, NULL, (PetscObject)fe)); 6619566063dSJacob Faibussowitsch PetscCall(PetscFEDestroy(&fe)); 6629566063dSJacob Faibussowitsch PetscCall(DMCreateDS(dm)); 66330602db0SMatthew G. Knepley 6649566063dSJacob Faibussowitsch PetscCall(CheckFunctions(dm, user.porder, &user)); 6659566063dSJacob Faibussowitsch PetscCall(CheckTransfer(dm, INTERPOLATION, user.porder, &user)); 6669566063dSJacob Faibussowitsch PetscCall(CheckTransfer(dm, INJECTION, user.porder, &user)); 6679566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm)); 6689566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 669b122ec5aSJacob Faibussowitsch return 0; 670557cf195SMatthew G. Knepley } 671557cf195SMatthew G. Knepley 672557cf195SMatthew G. Knepley /*TEST 673557cf195SMatthew G. Knepley 674557cf195SMatthew G. Knepley # TODO dim 3 will not work until I get composite elements in 3D (see plexrefine.c:34) 675557cf195SMatthew G. Knepley # 2D/3D P_1 on a simplex 676557cf195SMatthew G. Knepley test: 677557cf195SMatthew G. Knepley suffix: p1 678557cf195SMatthew G. Knepley requires: triangle ctetgen 67930602db0SMatthew 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} 680557cf195SMatthew G. Knepley test: 681557cf195SMatthew G. Knepley suffix: p1_pragmatic 682557cf195SMatthew G. Knepley requires: triangle ctetgen pragmatic 68330602db0SMatthew 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} 684557cf195SMatthew G. Knepley test: 685557cf195SMatthew G. Knepley suffix: p1_adapt 686557cf195SMatthew G. Knepley requires: triangle ctetgen 68730602db0SMatthew 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} 688557cf195SMatthew G. Knepley 689557cf195SMatthew G. Knepley # TODO dim 3 will not work until I get composite elements in 3D (see plexrefine.c:34) 690557cf195SMatthew G. Knepley # 2D/3D P_2 on a simplex 691557cf195SMatthew G. Knepley test: 692557cf195SMatthew G. Knepley suffix: p2 693557cf195SMatthew G. Knepley requires: triangle ctetgen 69430602db0SMatthew 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} 695557cf195SMatthew G. Knepley test: 696557cf195SMatthew G. Knepley suffix: p2_pragmatic 697557cf195SMatthew G. Knepley requires: triangle ctetgen pragmatic 69830602db0SMatthew 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} 699557cf195SMatthew G. Knepley 700557cf195SMatthew G. Knepley # TODO dim 3 will not work until I get composite elements in 3D (see plexrefine.c:34) 701557cf195SMatthew G. Knepley # TODO This is broken. Check ex3 which worked 702557cf195SMatthew G. Knepley # 2D/3D P_3 on a simplex 703557cf195SMatthew G. Knepley test: 704d6837840SMatthew G. Knepley TODO: gll Lagrange nodes break this 705557cf195SMatthew G. Knepley suffix: p3 706557cf195SMatthew G. Knepley requires: triangle ctetgen !single 70730602db0SMatthew 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} 708557cf195SMatthew G. Knepley test: 709d6837840SMatthew G. Knepley TODO: gll Lagrange nodes break this 710557cf195SMatthew G. Knepley suffix: p3_pragmatic 711557cf195SMatthew G. Knepley requires: triangle ctetgen pragmatic !single 71230602db0SMatthew 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} 713557cf195SMatthew G. Knepley 714557cf195SMatthew G. Knepley # 2D/3D Q_1 on a tensor cell 715557cf195SMatthew G. Knepley test: 716557cf195SMatthew G. Knepley suffix: q1 71730602db0SMatthew 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} 718557cf195SMatthew G. Knepley 719557cf195SMatthew G. Knepley # 2D/3D Q_2 on a tensor cell 720557cf195SMatthew G. Knepley test: 721557cf195SMatthew G. Knepley suffix: q2 72299a192c5SJunchao Zhang requires: !single 72330602db0SMatthew 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} 724557cf195SMatthew G. Knepley 725557cf195SMatthew G. Knepley # 2D/3D Q_3 on a tensor cell 726557cf195SMatthew G. Knepley test: 727d6837840SMatthew G. Knepley TODO: gll Lagrange nodes break this 728557cf195SMatthew G. Knepley suffix: q3 72999a192c5SJunchao Zhang requires: !single 73030602db0SMatthew 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} 731557cf195SMatthew G. Knepley 732557cf195SMatthew G. Knepley # 2D/3D P_1disc on a triangle/quadrilateral 733557cf195SMatthew G. Knepley # TODO Missing injection functional for simplices 734557cf195SMatthew G. Knepley test: 735557cf195SMatthew G. Knepley suffix: p1d 736557cf195SMatthew G. Knepley requires: triangle ctetgen 73730602db0SMatthew 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} 738557cf195SMatthew G. Knepley 739557cf195SMatthew G. Knepley TEST*/ 740