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 142557cf195SMatthew G. Knepley typedef enum {INTERPOLATION, RESTRICTION, INJECTION} InterpType; 143557cf195SMatthew G. Knepley 144557cf195SMatthew G. Knepley /* u = 1 */ 145557cf195SMatthew G. Knepley PetscErrorCode constant(PetscInt dim, PetscReal time, const PetscReal coords[], PetscInt Nc, PetscScalar *u, void *ctx) 146557cf195SMatthew G. Knepley { 147557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *) ctx; 148557cf195SMatthew G. Knepley PetscInt d = user->dir; 149557cf195SMatthew G. Knepley 150557cf195SMatthew G. Knepley if (Nc > 1) { 151557cf195SMatthew G. Knepley for (d = 0; d < Nc; ++d) u[d] = user->constants[d]; 152557cf195SMatthew G. Knepley } else { 153557cf195SMatthew G. Knepley u[0] = user->constants[d]; 154557cf195SMatthew G. Knepley } 155557cf195SMatthew G. Knepley return 0; 156557cf195SMatthew G. Knepley } 157557cf195SMatthew G. Knepley PetscErrorCode constantDer(PetscInt dim, PetscReal time, const PetscReal coords[], const PetscReal n[], PetscInt Nc, PetscScalar *u, void *ctx) 158557cf195SMatthew G. Knepley { 159557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *) ctx; 160557cf195SMatthew G. Knepley PetscInt d = user->dir; 161557cf195SMatthew G. Knepley 162557cf195SMatthew G. Knepley if (Nc > 1) { 163557cf195SMatthew G. Knepley for (d = 0; d < Nc; ++d) u[d] = 0.0; 164557cf195SMatthew G. Knepley } else { 165557cf195SMatthew G. Knepley u[0] = user->constants[d]; 166557cf195SMatthew G. Knepley } 167557cf195SMatthew G. Knepley return 0; 168557cf195SMatthew G. Knepley } 169557cf195SMatthew G. Knepley 170557cf195SMatthew G. Knepley /* u = x */ 171557cf195SMatthew G. Knepley PetscErrorCode linear(PetscInt dim, PetscReal time, const PetscReal coords[], PetscInt Nc, PetscScalar *u, void *ctx) 172557cf195SMatthew G. Knepley { 173557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *) ctx; 174557cf195SMatthew G. Knepley PetscInt d = user->dir; 175557cf195SMatthew G. Knepley 176557cf195SMatthew G. Knepley if (Nc > 1) { 177557cf195SMatthew G. Knepley for (d = 0; d < Nc; ++d) u[d] = coords[d]; 178557cf195SMatthew G. Knepley } else { 179557cf195SMatthew G. Knepley u[0] = coords[d]; 180557cf195SMatthew G. Knepley } 181557cf195SMatthew G. Knepley return 0; 182557cf195SMatthew G. Knepley } 183557cf195SMatthew G. Knepley PetscErrorCode linearDer(PetscInt dim, PetscReal time, const PetscReal coords[], const PetscReal n[], PetscInt Nc, PetscScalar *u, void *ctx) 184557cf195SMatthew G. Knepley { 185557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *) ctx; 186557cf195SMatthew G. Knepley PetscInt d = user->dir; 187557cf195SMatthew G. Knepley 188557cf195SMatthew G. Knepley if (Nc > 1) { 189557cf195SMatthew G. Knepley PetscInt e; 190557cf195SMatthew G. Knepley for (d = 0; d < Nc; ++d) { 191557cf195SMatthew G. Knepley u[d] = 0.0; 192557cf195SMatthew G. Knepley for (e = 0; e < dim; ++e) u[d] += (d == e ? 1.0 : 0.0) * n[e]; 193557cf195SMatthew G. Knepley } 194557cf195SMatthew G. Knepley } else { 195557cf195SMatthew G. Knepley u[0] = n[d]; 196557cf195SMatthew G. Knepley } 197557cf195SMatthew G. Knepley return 0; 198557cf195SMatthew G. Knepley } 199557cf195SMatthew G. Knepley 200557cf195SMatthew G. Knepley /* u = x^2 or u = (x^2, xy) or u = (xy, yz, zx) */ 201557cf195SMatthew G. Knepley PetscErrorCode quadratic(PetscInt dim, PetscReal time, const PetscReal coords[], PetscInt Nc, PetscScalar *u, void *ctx) 202557cf195SMatthew G. Knepley { 203557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *) ctx; 204557cf195SMatthew G. Knepley PetscInt d = user->dir; 205557cf195SMatthew G. Knepley 206557cf195SMatthew G. Knepley if (Nc > 1) { 207557cf195SMatthew G. Knepley if (Nc > 2) {u[0] = coords[0]*coords[1]; u[1] = coords[1]*coords[2]; u[2] = coords[2]*coords[0];} 208557cf195SMatthew G. Knepley else {u[0] = coords[0]*coords[0]; u[1] = coords[0]*coords[1];} 209557cf195SMatthew G. Knepley } else { 210557cf195SMatthew G. Knepley u[0] = coords[d]*coords[d]; 211557cf195SMatthew G. Knepley } 212557cf195SMatthew G. Knepley return 0; 213557cf195SMatthew G. Knepley } 214557cf195SMatthew G. Knepley PetscErrorCode quadraticDer(PetscInt dim, PetscReal time, const PetscReal coords[], const PetscReal n[], PetscInt Nc, PetscScalar *u, void *ctx) 215557cf195SMatthew G. Knepley { 216557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *) ctx; 217557cf195SMatthew G. Knepley PetscInt d = user->dir; 218557cf195SMatthew G. Knepley 219557cf195SMatthew G. Knepley if (Nc > 1) { 220557cf195SMatthew G. Knepley if (Nc > 2) {u[0] = coords[1]*n[0] + coords[0]*n[1]; u[1] = coords[2]*n[1] + coords[1]*n[2]; u[2] = coords[2]*n[0] + coords[0]*n[2];} 221557cf195SMatthew G. Knepley else {u[0] = 2.0*coords[0]*n[0]; u[1] = coords[1]*n[0] + coords[0]*n[1];} 222557cf195SMatthew G. Knepley } else { 223557cf195SMatthew G. Knepley u[0] = 2.0*coords[d]*n[d]; 224557cf195SMatthew G. Knepley } 225557cf195SMatthew G. Knepley return 0; 226557cf195SMatthew G. Knepley } 227557cf195SMatthew G. Knepley 228557cf195SMatthew G. Knepley /* u = x^3 or u = (x^3, x^2y) or u = (x^2y, y^2z, z^2x) */ 229557cf195SMatthew G. Knepley PetscErrorCode cubic(PetscInt dim, PetscReal time, const PetscReal coords[], PetscInt Nc, PetscScalar *u, void *ctx) 230557cf195SMatthew G. Knepley { 231557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *) ctx; 232557cf195SMatthew G. Knepley PetscInt d = user->dir; 233557cf195SMatthew G. Knepley 234557cf195SMatthew G. Knepley if (Nc > 1) { 235557cf195SMatthew G. Knepley if (Nc > 2) {u[0] = coords[0]*coords[0]*coords[1]; u[1] = coords[1]*coords[1]*coords[2]; u[2] = coords[2]*coords[2]*coords[0];} 236557cf195SMatthew G. Knepley else {u[0] = coords[0]*coords[0]*coords[0]; u[1] = coords[0]*coords[0]*coords[1];} 237557cf195SMatthew G. Knepley } else { 238557cf195SMatthew G. Knepley u[0] = coords[d]*coords[d]*coords[d]; 239557cf195SMatthew G. Knepley } 240557cf195SMatthew G. Knepley return 0; 241557cf195SMatthew G. Knepley } 242557cf195SMatthew G. Knepley PetscErrorCode cubicDer(PetscInt dim, PetscReal time, const PetscReal coords[], const PetscReal n[], PetscInt Nc, PetscScalar *u, void *ctx) 243557cf195SMatthew G. Knepley { 244557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *) ctx; 245557cf195SMatthew G. Knepley PetscInt d = user->dir; 246557cf195SMatthew G. Knepley 247557cf195SMatthew G. Knepley if (Nc > 1) { 248557cf195SMatthew G. Knepley if (Nc > 2) {u[0] = 2.0*coords[0]*coords[1]*n[0] + coords[0]*coords[0]*n[1]; u[1] = 2.0*coords[1]*coords[2]*n[1] + coords[1]*coords[1]*n[2]; u[2] = 2.0*coords[2]*coords[0]*n[2] + coords[2]*coords[2]*n[0];} 249557cf195SMatthew G. Knepley else {u[0] = 3.0*coords[0]*coords[0]*n[0]; u[1] = 2.0*coords[0]*coords[1]*n[0] + coords[0]*coords[0]*n[1];} 250557cf195SMatthew G. Knepley } else { 251557cf195SMatthew G. Knepley u[0] = 3.0*coords[d]*coords[d]*n[d]; 252557cf195SMatthew G. Knepley } 253557cf195SMatthew G. Knepley return 0; 254557cf195SMatthew G. Knepley } 255557cf195SMatthew G. Knepley 256557cf195SMatthew G. Knepley /* u = x^4 or u = (x^4, x^2y^2) or u = (x^2y^2, y^2z^2, z^2x^2) */ 257557cf195SMatthew G. Knepley PetscErrorCode quartic(PetscInt dim, PetscReal time, const PetscReal coords[], PetscInt Nc, PetscScalar *u, void *ctx) 258557cf195SMatthew G. Knepley { 259557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *) ctx; 260557cf195SMatthew G. Knepley PetscInt d = user->dir; 261557cf195SMatthew G. Knepley 262557cf195SMatthew G. Knepley if (Nc > 1) { 263557cf195SMatthew G. Knepley if (Nc > 2) {u[0] = coords[0]*coords[0]*coords[1]*coords[1]; u[1] = coords[1]*coords[1]*coords[2]*coords[2]; u[2] = coords[2]*coords[2]*coords[0]*coords[0];} 264557cf195SMatthew G. Knepley else {u[0] = coords[0]*coords[0]*coords[0]*coords[0]; u[1] = coords[0]*coords[0]*coords[1]*coords[1];} 265557cf195SMatthew G. Knepley } else { 266557cf195SMatthew G. Knepley u[0] = coords[d]*coords[d]*coords[d]*coords[d]; 267557cf195SMatthew G. Knepley } 268557cf195SMatthew G. Knepley return 0; 269557cf195SMatthew G. Knepley } 270557cf195SMatthew G. Knepley PetscErrorCode quarticDer(PetscInt dim, PetscReal time, const PetscReal coords[], const PetscReal n[], PetscInt Nc, PetscScalar *u, void *ctx) 271557cf195SMatthew G. Knepley { 272557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *) ctx; 273557cf195SMatthew G. Knepley PetscInt d = user->dir; 274557cf195SMatthew G. Knepley 275557cf195SMatthew G. Knepley if (Nc > 1) { 276557cf195SMatthew G. Knepley if (Nc > 2) {u[0] = 2.0*coords[0]*coords[1]*coords[1]*n[0] + 2.0*coords[0]*coords[0]*coords[1]*n[1]; 277557cf195SMatthew G. Knepley u[1] = 2.0*coords[1]*coords[2]*coords[2]*n[1] + 2.0*coords[1]*coords[1]*coords[2]*n[2]; 278557cf195SMatthew G. Knepley u[2] = 2.0*coords[2]*coords[0]*coords[0]*n[2] + 2.0*coords[2]*coords[2]*coords[0]*n[0];} 279557cf195SMatthew G. Knepley else {u[0] = 4.0*coords[0]*coords[0]*coords[0]*n[0]; u[1] = 2.0*coords[0]*coords[1]*coords[1]*n[0] + 2.0*coords[0]*coords[0]*coords[1]*n[1];} 280557cf195SMatthew G. Knepley } else { 281557cf195SMatthew G. Knepley u[0] = 4.0*coords[d]*coords[d]*coords[d]*n[d]; 282557cf195SMatthew G. Knepley } 283557cf195SMatthew G. Knepley return 0; 284557cf195SMatthew G. Knepley } 285557cf195SMatthew G. Knepley 286557cf195SMatthew G. Knepley PetscErrorCode mytanh(PetscInt dim, PetscReal time, const PetscReal coords[], PetscInt Nc, PetscScalar *u, void *ctx) 287557cf195SMatthew G. Knepley { 288557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *) ctx; 289557cf195SMatthew G. Knepley PetscInt d = user->dir; 290557cf195SMatthew G. Knepley 291557cf195SMatthew G. Knepley if (Nc > 1) { 292557cf195SMatthew G. Knepley for (d = 0; d < Nc; ++d) u[d] = PetscTanhReal(coords[d] - 0.5); 293557cf195SMatthew G. Knepley } else { 294557cf195SMatthew G. Knepley u[0] = PetscTanhReal(coords[d] - 0.5); 295557cf195SMatthew G. Knepley } 296557cf195SMatthew G. Knepley return 0; 297557cf195SMatthew G. Knepley } 298557cf195SMatthew G. Knepley PetscErrorCode mytanhDer(PetscInt dim, PetscReal time, const PetscReal coords[], const PetscReal n[], PetscInt Nc, PetscScalar *u, void *ctx) 299557cf195SMatthew G. Knepley { 300557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *) ctx; 301557cf195SMatthew G. Knepley PetscInt d = user->dir; 302557cf195SMatthew G. Knepley 303557cf195SMatthew G. Knepley if (Nc > 1) { 304557cf195SMatthew G. Knepley for (d = 0; d < Nc; ++d) u[d] = 1.0/PetscSqr(PetscCoshReal(coords[d] - 0.5)) * n[d]; 305557cf195SMatthew G. Knepley } else { 306557cf195SMatthew G. Knepley u[0] = 1.0/PetscSqr(PetscCoshReal(coords[d] - 0.5)) * n[d]; 307557cf195SMatthew G. Knepley } 308557cf195SMatthew G. Knepley return 0; 309557cf195SMatthew G. Knepley } 310557cf195SMatthew G. Knepley 311557cf195SMatthew G. Knepley PetscErrorCode trig(PetscInt dim, PetscReal time, const PetscReal coords[], PetscInt Nc, PetscScalar *u, void *ctx) 312557cf195SMatthew G. Knepley { 313557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *) ctx; 314557cf195SMatthew G. Knepley PetscInt m = user->m, d = user->dir; 315557cf195SMatthew G. Knepley 316557cf195SMatthew G. Knepley if (Nc > 1) { 317557cf195SMatthew G. Knepley for (d = 0; d < Nc; ++d) u[d] = PetscSinReal(PETSC_PI*m*coords[d]); 318557cf195SMatthew G. Knepley } else { 319557cf195SMatthew G. Knepley u[0] = PetscSinReal(PETSC_PI*m*coords[d]); 320557cf195SMatthew G. Knepley } 321557cf195SMatthew G. Knepley return 0; 322557cf195SMatthew G. Knepley } 323557cf195SMatthew G. Knepley PetscErrorCode trigDer(PetscInt dim, PetscReal time, const PetscReal coords[], const PetscReal n[], PetscInt Nc, PetscScalar *u, void *ctx) 324557cf195SMatthew G. Knepley { 325557cf195SMatthew G. Knepley AppCtx *user = (AppCtx *) ctx; 326557cf195SMatthew G. Knepley PetscInt m = user->m, d = user->dir; 327557cf195SMatthew G. Knepley 328557cf195SMatthew G. Knepley if (Nc > 1) { 329557cf195SMatthew G. Knepley for (d = 0; d < Nc; ++d) u[d] = PETSC_PI*m*PetscCosReal(PETSC_PI*m*coords[d]) * n[d]; 330557cf195SMatthew G. Knepley } else { 331557cf195SMatthew G. Knepley u[0] = PETSC_PI*m*PetscCosReal(PETSC_PI*m*coords[d]) * n[d]; 332557cf195SMatthew G. Knepley } 333557cf195SMatthew G. Knepley return 0; 334557cf195SMatthew G. Knepley } 335557cf195SMatthew G. Knepley 336557cf195SMatthew G. Knepley static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options) 337557cf195SMatthew G. Knepley { 338557cf195SMatthew G. Knepley PetscFunctionBeginUser; 339557cf195SMatthew G. Knepley options->qorder = 0; 340557cf195SMatthew G. Knepley options->Nc = PETSC_DEFAULT; 341557cf195SMatthew G. Knepley options->porder = 0; 342557cf195SMatthew G. Knepley options->m = 1; 343557cf195SMatthew G. Knepley options->dir = 0; 344557cf195SMatthew G. Knepley options->K = 0; 345557cf195SMatthew G. Knepley options->usePoly = PETSC_TRUE; 346557cf195SMatthew G. Knepley 347d0609cedSBarry Smith PetscOptionsBegin(comm, "", "Projection Test Options", "DMPlex"); 3489566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-qorder", "The quadrature order", "ex8.c", options->qorder, &options->qorder, NULL)); 3499566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-num_comp", "The number of field components", "ex8.c", options->Nc, &options->Nc, NULL)); 3509566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-porder", "The order of polynomials to test", "ex8.c", options->porder, &options->porder, NULL)); 3519566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-K", "The number of coarse modes used in optimization", "ex8.c", options->K, &options->K, NULL)); 3529566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-use_poly", "Use polynomials (or harmonics) to adapt interpolator", "ex8.c", options->usePoly, &options->usePoly, NULL)); 353d0609cedSBarry Smith PetscOptionsEnd(); 354557cf195SMatthew G. Knepley PetscFunctionReturn(0); 355557cf195SMatthew G. Knepley } 356557cf195SMatthew G. Knepley 357557cf195SMatthew G. Knepley static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm) 358557cf195SMatthew G. Knepley { 359557cf195SMatthew G. Knepley PetscFunctionBeginUser; 3609566063dSJacob Faibussowitsch PetscCall(DMCreate(comm, dm)); 3619566063dSJacob Faibussowitsch PetscCall(DMSetType(*dm, DMPLEX)); 3629566063dSJacob Faibussowitsch PetscCall(DMSetFromOptions(*dm)); 3639566063dSJacob Faibussowitsch PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view")); 364557cf195SMatthew G. Knepley PetscFunctionReturn(0); 365557cf195SMatthew G. Knepley } 366557cf195SMatthew G. Knepley 367557cf195SMatthew G. Knepley /* Setup functions to approximate */ 368557cf195SMatthew G. Knepley static PetscErrorCode SetupFunctions(DM dm, PetscBool usePoly, PetscInt order, PetscInt dir, PetscErrorCode (**exactFuncs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), 369557cf195SMatthew G. Knepley PetscErrorCode (**exactFuncDers)(PetscInt, PetscReal, const PetscReal[], const PetscReal[], PetscInt, PetscScalar *, void *), AppCtx *user) 370557cf195SMatthew G. Knepley { 371557cf195SMatthew G. Knepley PetscInt dim; 372557cf195SMatthew G. Knepley 373557cf195SMatthew G. Knepley PetscFunctionBeginUser; 374557cf195SMatthew G. Knepley user->dir = dir; 375557cf195SMatthew G. Knepley if (usePoly) { 376557cf195SMatthew G. Knepley switch (order) { 377557cf195SMatthew G. Knepley case 0: 378557cf195SMatthew G. Knepley exactFuncs[0] = constant; 379557cf195SMatthew G. Knepley exactFuncDers[0] = constantDer; 380557cf195SMatthew G. Knepley break; 381557cf195SMatthew G. Knepley case 1: 382557cf195SMatthew G. Knepley exactFuncs[0] = linear; 383557cf195SMatthew G. Knepley exactFuncDers[0] = linearDer; 384557cf195SMatthew G. Knepley break; 385557cf195SMatthew G. Knepley case 2: 386557cf195SMatthew G. Knepley exactFuncs[0] = quadratic; 387557cf195SMatthew G. Knepley exactFuncDers[0] = quadraticDer; 388557cf195SMatthew G. Knepley break; 389557cf195SMatthew G. Knepley case 3: 390557cf195SMatthew G. Knepley exactFuncs[0] = cubic; 391557cf195SMatthew G. Knepley exactFuncDers[0] = cubicDer; 392557cf195SMatthew G. Knepley break; 393557cf195SMatthew G. Knepley case 4: 394557cf195SMatthew G. Knepley exactFuncs[0] = quartic; 395557cf195SMatthew G. Knepley exactFuncDers[0] = quarticDer; 396557cf195SMatthew G. Knepley break; 397557cf195SMatthew G. Knepley default: 3989566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 39963a3b9bcSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Could not determine functions to test for dimension %" PetscInt_FMT " order %" PetscInt_FMT, dim, order); 400557cf195SMatthew G. Knepley } 401557cf195SMatthew G. Knepley } else { 402557cf195SMatthew G. Knepley user->m = order; 403557cf195SMatthew G. Knepley exactFuncs[0] = trig; 404557cf195SMatthew G. Knepley exactFuncDers[0] = trigDer; 405557cf195SMatthew G. Knepley } 406557cf195SMatthew G. Knepley PetscFunctionReturn(0); 407557cf195SMatthew G. Knepley } 408557cf195SMatthew G. Knepley 409557cf195SMatthew G. Knepley static PetscErrorCode ComputeError(DM dm, PetscErrorCode (**exactFuncs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), 410557cf195SMatthew G. Knepley PetscErrorCode (**exactFuncDers)(PetscInt, PetscReal, const PetscReal[], const PetscReal[], PetscInt, PetscScalar *, void *), 411557cf195SMatthew G. Knepley void **exactCtxs, PetscReal *error, PetscReal *errorDer, AppCtx *user) 412557cf195SMatthew G. Knepley { 413557cf195SMatthew G. Knepley Vec u; 414557cf195SMatthew G. Knepley PetscReal n[3] = {1.0, 1.0, 1.0}; 415557cf195SMatthew G. Knepley 416557cf195SMatthew G. Knepley PetscFunctionBeginUser; 4179566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(dm, &u)); 418557cf195SMatthew G. Knepley /* Project function into FE function space */ 4199566063dSJacob Faibussowitsch PetscCall(DMProjectFunction(dm, 0.0, exactFuncs, exactCtxs, INSERT_ALL_VALUES, u)); 4209566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(u, NULL, "-projection_view")); 421557cf195SMatthew G. Knepley /* Compare approximation to exact in L_2 */ 4229566063dSJacob Faibussowitsch PetscCall(DMComputeL2Diff(dm, 0.0, exactFuncs, exactCtxs, u, error)); 4239566063dSJacob Faibussowitsch PetscCall(DMComputeL2GradientDiff(dm, 0.0, exactFuncDers, exactCtxs, u, n, errorDer)); 4249566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(dm, &u)); 425557cf195SMatthew G. Knepley PetscFunctionReturn(0); 426557cf195SMatthew G. Knepley } 427557cf195SMatthew G. Knepley 428557cf195SMatthew G. Knepley static PetscErrorCode CheckFunctions(DM dm, PetscInt order, AppCtx *user) 429557cf195SMatthew G. Knepley { 430557cf195SMatthew G. Knepley PetscErrorCode (*exactFuncs[1]) (PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar *u, void *ctx); 431557cf195SMatthew G. Knepley PetscErrorCode (*exactFuncDers[1]) (PetscInt dim, PetscReal time, const PetscReal x[], const PetscReal n[], PetscInt Nf, PetscScalar *u, void *ctx); 432557cf195SMatthew G. Knepley void *exactCtxs[3]; 433557cf195SMatthew G. Knepley MPI_Comm comm; 434557cf195SMatthew G. Knepley PetscReal error, errorDer, tol = PETSC_SMALL; 435557cf195SMatthew G. Knepley 436557cf195SMatthew G. Knepley PetscFunctionBeginUser; 437557cf195SMatthew G. Knepley exactCtxs[0] = user; 438557cf195SMatthew G. Knepley exactCtxs[1] = user; 439557cf195SMatthew G. Knepley exactCtxs[2] = user; 440557cf195SMatthew G. Knepley user->constants[0] = 1.0; 441557cf195SMatthew G. Knepley user->constants[1] = 2.0; 442557cf195SMatthew G. Knepley user->constants[2] = 3.0; 4439566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 4449566063dSJacob Faibussowitsch PetscCall(SetupFunctions(dm, PETSC_TRUE, order, 0, exactFuncs, exactFuncDers, user)); 4459566063dSJacob Faibussowitsch PetscCall(ComputeError(dm, exactFuncs, exactFuncDers, exactCtxs, &error, &errorDer, user)); 446557cf195SMatthew G. Knepley /* Report result */ 44763a3b9bcSJacob 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)); 44863a3b9bcSJacob Faibussowitsch else PetscCall(PetscPrintf(comm, "Function tests pass for order %" PetscInt_FMT " at tolerance %g\n", order, (double)tol)); 44963a3b9bcSJacob 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)); 45063a3b9bcSJacob Faibussowitsch else PetscCall(PetscPrintf(comm, "Function tests pass for order %" PetscInt_FMT " derivatives at tolerance %g\n", order, (double)tol)); 451557cf195SMatthew G. Knepley PetscFunctionReturn(0); 452557cf195SMatthew G. Knepley } 453557cf195SMatthew G. Knepley 454557cf195SMatthew G. Knepley /* Compare approximation to exact in L_2 */ 455557cf195SMatthew G. Knepley static PetscErrorCode CheckTransferError(DM fdm, PetscBool usePoly, PetscInt order, PetscInt dir, const char *testname, Vec fu, AppCtx *user) 456557cf195SMatthew G. Knepley { 457557cf195SMatthew G. Knepley PetscErrorCode (*exactFuncs[1]) (PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar *u, void *ctx); 458557cf195SMatthew G. Knepley PetscErrorCode (*exactFuncDers[1]) (PetscInt dim, PetscReal time, const PetscReal x[], const PetscReal n[], PetscInt Nf, PetscScalar *u, void *ctx); 459557cf195SMatthew G. Knepley PetscReal n[3] = {1.0, 1.0, 1.0}; 460557cf195SMatthew G. Knepley void *exactCtxs[3]; 461557cf195SMatthew G. Knepley MPI_Comm comm; 462557cf195SMatthew G. Knepley PetscReal error, errorDer, tol = PETSC_SMALL; 463557cf195SMatthew G. Knepley 464557cf195SMatthew G. Knepley PetscFunctionBeginUser; 465557cf195SMatthew G. Knepley exactCtxs[0] = user; 466557cf195SMatthew G. Knepley exactCtxs[1] = user; 467557cf195SMatthew G. Knepley exactCtxs[2] = user; 468557cf195SMatthew G. Knepley user->constants[0] = 1.0; 469557cf195SMatthew G. Knepley user->constants[1] = 2.0; 470557cf195SMatthew G. Knepley user->constants[2] = 3.0; 4719566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject) fdm, &comm)); 4729566063dSJacob Faibussowitsch PetscCall(SetupFunctions(fdm, usePoly, order, dir, exactFuncs, exactFuncDers, user)); 4739566063dSJacob Faibussowitsch PetscCall(DMComputeL2Diff(fdm, 0.0, exactFuncs, exactCtxs, fu, &error)); 4749566063dSJacob Faibussowitsch PetscCall(DMComputeL2GradientDiff(fdm, 0.0, exactFuncDers, exactCtxs, fu, n, &errorDer)); 475557cf195SMatthew G. Knepley /* Report result */ 47663a3b9bcSJacob 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)); 47763a3b9bcSJacob Faibussowitsch else PetscCall(PetscPrintf(comm, "%s tests pass for order %" PetscInt_FMT " at tolerance %g\n", testname, order, (double)tol)); 47863a3b9bcSJacob 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)); 47963a3b9bcSJacob Faibussowitsch else PetscCall(PetscPrintf(comm, "%s tests pass for order %" PetscInt_FMT " derivatives at tolerance %g\n", testname, order, (double)tol)); 480557cf195SMatthew G. Knepley PetscFunctionReturn(0); 481557cf195SMatthew G. Knepley } 482557cf195SMatthew G. Knepley 483557cf195SMatthew G. Knepley static PetscErrorCode CheckTransfer(DM dm, InterpType inType, PetscInt order, AppCtx *user) 484557cf195SMatthew G. Knepley { 485557cf195SMatthew G. Knepley PetscErrorCode (*exactFuncs[1]) (PetscInt, PetscReal, const PetscReal x[], PetscInt, PetscScalar *u, void *ctx); 486557cf195SMatthew G. Knepley PetscErrorCode (*exactFuncDers[1]) (PetscInt, PetscReal, const PetscReal x[], const PetscReal n[], PetscInt, PetscScalar *u, void *ctx); 487d6837840SMatthew G. Knepley void *exactCtxs[3]; 488d6837840SMatthew G. Knepley DM rdm = NULL, idm = NULL, fdm = NULL; 489557cf195SMatthew G. Knepley Mat Interp, InterpAdapt = NULL; 490d6837840SMatthew G. Knepley Vec iu, fu, scaling = NULL; 491557cf195SMatthew G. Knepley MPI_Comm comm; 492d6837840SMatthew G. Knepley const char *testname = "Unknown"; 493557cf195SMatthew G. Knepley char checkname[PETSC_MAX_PATH_LEN]; 494557cf195SMatthew G. Knepley 495557cf195SMatthew G. Knepley PetscFunctionBeginUser; 496d6837840SMatthew G. Knepley exactCtxs[0] = exactCtxs[1] = exactCtxs[2] = user; 4979566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm,&comm)); 4989566063dSJacob Faibussowitsch PetscCall(DMRefine(dm, comm, &rdm)); 4999566063dSJacob Faibussowitsch PetscCall(DMViewFromOptions(rdm, NULL, "-ref_dm_view")); 5009566063dSJacob Faibussowitsch PetscCall(DMSetCoarseDM(rdm, dm)); 5019566063dSJacob Faibussowitsch PetscCall(DMCopyDisc(dm, rdm)); 502557cf195SMatthew G. Knepley switch (inType) { 503557cf195SMatthew G. Knepley case INTERPOLATION: 504557cf195SMatthew G. Knepley testname = "Interpolation"; 505557cf195SMatthew G. Knepley idm = dm; 506557cf195SMatthew G. Knepley fdm = rdm; 507557cf195SMatthew G. Knepley break; 508557cf195SMatthew G. Knepley case RESTRICTION: 509557cf195SMatthew G. Knepley testname = "Restriction"; 510557cf195SMatthew G. Knepley idm = rdm; 511557cf195SMatthew G. Knepley fdm = dm; 512557cf195SMatthew G. Knepley break; 513557cf195SMatthew G. Knepley case INJECTION: 514557cf195SMatthew G. Knepley testname = "Injection"; 515557cf195SMatthew G. Knepley idm = rdm; 516557cf195SMatthew G. Knepley fdm = dm; 517557cf195SMatthew G. Knepley break; 518557cf195SMatthew G. Knepley } 5199566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(idm, &iu)); 5209566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(fdm, &fu)); 5219566063dSJacob Faibussowitsch PetscCall(DMSetApplicationContext(dm, user)); 5229566063dSJacob Faibussowitsch PetscCall(DMSetApplicationContext(rdm, user)); 523557cf195SMatthew G. Knepley /* Project function into initial FE function space */ 5249566063dSJacob Faibussowitsch PetscCall(SetupFunctions(dm, PETSC_TRUE, order, 0, exactFuncs, exactFuncDers, user)); 5259566063dSJacob Faibussowitsch PetscCall(DMProjectFunction(idm, 0.0, exactFuncs, exactCtxs, INSERT_ALL_VALUES, iu)); 526557cf195SMatthew G. Knepley /* Interpolate function into final FE function space */ 527557cf195SMatthew G. Knepley switch (inType) { 528557cf195SMatthew G. Knepley case INTERPOLATION: 5299566063dSJacob Faibussowitsch PetscCall(DMCreateInterpolation(dm, rdm, &Interp, &scaling)); 5309566063dSJacob Faibussowitsch PetscCall(MatInterpolate(Interp, iu, fu)); 531557cf195SMatthew G. Knepley break; 532557cf195SMatthew G. Knepley case RESTRICTION: 5339566063dSJacob Faibussowitsch PetscCall(DMCreateInterpolation(dm, rdm, &Interp, &scaling)); 5349566063dSJacob Faibussowitsch PetscCall(MatRestrict(Interp, iu, fu)); 5359566063dSJacob Faibussowitsch PetscCall(VecPointwiseMult(fu, scaling, fu)); 536557cf195SMatthew G. Knepley break; 537557cf195SMatthew G. Knepley case INJECTION: 5389566063dSJacob Faibussowitsch PetscCall(DMCreateInjection(dm, rdm, &Interp)); 5399566063dSJacob Faibussowitsch PetscCall(MatRestrict(Interp, iu, fu)); 540557cf195SMatthew G. Knepley break; 541557cf195SMatthew G. Knepley } 5429566063dSJacob Faibussowitsch PetscCall(CheckTransferError(fdm, PETSC_TRUE, order, 0, testname, fu, user)); 543557cf195SMatthew G. Knepley if (user->K && (inType == INTERPOLATION)) { 544557cf195SMatthew G. Knepley KSP smoother; 545*2b3cbbdaSStefano Zampini Mat A, iVM, fVM; 546*2b3cbbdaSStefano Zampini Vec iV, fV; 547*2b3cbbdaSStefano Zampini PetscInt k, dim, d, im, fm; 548557cf195SMatthew G. Knepley 5499566063dSJacob Faibussowitsch PetscCall(PetscPrintf(comm, " Adapting interpolator using %s\n", user->usePoly ? "polynomials" : "harmonics")); 5509566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 551557cf195SMatthew G. Knepley /* Project coarse modes into initial and final FE function space */ 552*2b3cbbdaSStefano Zampini PetscCall(DMGetGlobalVector(idm, &iV)); 553*2b3cbbdaSStefano Zampini PetscCall(DMGetGlobalVector(fdm, &fV)); 554*2b3cbbdaSStefano Zampini PetscCall(VecGetLocalSize(iV,&im)); 555*2b3cbbdaSStefano Zampini PetscCall(VecGetLocalSize(fV,&fm)); 556*2b3cbbdaSStefano Zampini PetscCall(MatCreateDense(PetscObjectComm((PetscObject)dm),im,PETSC_DECIDE,PETSC_DECIDE,user->K*dim,NULL,&iVM)); 557*2b3cbbdaSStefano Zampini PetscCall(MatCreateDense(PetscObjectComm((PetscObject)dm),fm,PETSC_DECIDE,PETSC_DECIDE,user->K*dim,NULL,&fVM)); 558*2b3cbbdaSStefano Zampini PetscCall(DMRestoreGlobalVector(idm, &iV)); 559*2b3cbbdaSStefano Zampini PetscCall(DMRestoreGlobalVector(fdm, &fV)); 560557cf195SMatthew G. Knepley for (k = 0; k < user->K; ++k) { 561557cf195SMatthew G. Knepley for (d = 0; d < dim; ++d) { 562*2b3cbbdaSStefano Zampini PetscCall(MatDenseGetColumnVecWrite(iVM,k*dim+d,&iV)); 563*2b3cbbdaSStefano Zampini PetscCall(MatDenseGetColumnVecWrite(fVM,k*dim+d,&fV)); 5649566063dSJacob Faibussowitsch PetscCall(SetupFunctions(idm, user->usePoly, user->usePoly ? k : k+1, d, exactFuncs, exactFuncDers, user)); 565*2b3cbbdaSStefano Zampini PetscCall(DMProjectFunction(idm, 0.0, exactFuncs, exactCtxs, INSERT_ALL_VALUES, iV)); 566*2b3cbbdaSStefano Zampini PetscCall(DMProjectFunction(fdm, 0.0, exactFuncs, exactCtxs, INSERT_ALL_VALUES, fV)); 567*2b3cbbdaSStefano Zampini PetscCall(MatDenseRestoreColumnVecWrite(iVM,k*dim+d,&iV)); 568*2b3cbbdaSStefano Zampini PetscCall(MatDenseRestoreColumnVecWrite(fVM,k*dim+d,&fV)); 569557cf195SMatthew G. Knepley } 570557cf195SMatthew G. Knepley } 571*2b3cbbdaSStefano Zampini 572557cf195SMatthew G. Knepley /* Adapt interpolator */ 5739566063dSJacob Faibussowitsch PetscCall(DMCreateMatrix(rdm, &A)); 5749566063dSJacob Faibussowitsch PetscCall(MatShift(A, 1.0)); 5759566063dSJacob Faibussowitsch PetscCall(KSPCreate(comm, &smoother)); 5769566063dSJacob Faibussowitsch PetscCall(KSPSetFromOptions(smoother)); 5779566063dSJacob Faibussowitsch PetscCall(KSPSetOperators(smoother, A, A)); 578*2b3cbbdaSStefano Zampini PetscCall(DMAdaptInterpolator(dm, rdm, Interp, smoother, fVM, iVM, &InterpAdapt, user)); 579557cf195SMatthew G. Knepley /* Interpolate function into final FE function space */ 5809566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(checkname, PETSC_MAX_PATH_LEN, " %s poly", testname)); 5819566063dSJacob Faibussowitsch PetscCall(MatInterpolate(InterpAdapt, iu, fu)); 5829566063dSJacob Faibussowitsch PetscCall(CheckTransferError(fdm, PETSC_TRUE, order, 0, checkname, fu, user)); 583557cf195SMatthew G. Knepley for (k = 0; k < user->K; ++k) { 584557cf195SMatthew G. Knepley for (d = 0; d < dim; ++d) { 58563a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(checkname, PETSC_MAX_PATH_LEN, " %s trig (%" PetscInt_FMT ", %" PetscInt_FMT ")", testname, k, d)); 586*2b3cbbdaSStefano Zampini PetscCall(MatDenseGetColumnVecRead(iVM,k*dim+d,&iV)); 587*2b3cbbdaSStefano Zampini PetscCall(MatDenseGetColumnVecWrite(fVM,k*dim+d,&fV)); 588*2b3cbbdaSStefano Zampini PetscCall(MatInterpolate(InterpAdapt, iV, fV)); 589*2b3cbbdaSStefano Zampini PetscCall(CheckTransferError(fdm, PETSC_FALSE, k+1, d, checkname, fV, user)); 590*2b3cbbdaSStefano Zampini PetscCall(MatDenseRestoreColumnVecRead(iVM,k*dim+d,&iV)); 591*2b3cbbdaSStefano Zampini PetscCall(MatDenseRestoreColumnVecWrite(fVM,k*dim+d,&fV)); 592557cf195SMatthew G. Knepley } 593557cf195SMatthew G. Knepley } 594557cf195SMatthew G. Knepley /* Cleanup */ 5959566063dSJacob Faibussowitsch PetscCall(KSPDestroy(&smoother)); 5969566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 5979566063dSJacob Faibussowitsch PetscCall(MatDestroy(&InterpAdapt)); 598*2b3cbbdaSStefano Zampini PetscCall(MatDestroy(&iVM)); 599*2b3cbbdaSStefano Zampini PetscCall(MatDestroy(&fVM)); 600557cf195SMatthew G. Knepley } 6019566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(idm, &iu)); 6029566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(fdm, &fu)); 6039566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Interp)); 6049566063dSJacob Faibussowitsch PetscCall(VecDestroy(&scaling)); 6059566063dSJacob Faibussowitsch PetscCall(DMDestroy(&rdm)); 606557cf195SMatthew G. Knepley PetscFunctionReturn(0); 607557cf195SMatthew G. Knepley } 608557cf195SMatthew G. Knepley 609557cf195SMatthew G. Knepley int main(int argc, char **argv) 610557cf195SMatthew G. Knepley { 611557cf195SMatthew G. Knepley DM dm; 61230602db0SMatthew G. Knepley PetscFE fe; 61330602db0SMatthew G. Knepley AppCtx user; 61430602db0SMatthew G. Knepley PetscInt dim; 61530602db0SMatthew G. Knepley PetscBool simplex; 616557cf195SMatthew G. Knepley 6179566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 6189566063dSJacob Faibussowitsch PetscCall(ProcessOptions(PETSC_COMM_WORLD, &user)); 6199566063dSJacob Faibussowitsch PetscCall(CreateMesh(PETSC_COMM_WORLD, &user, &dm)); 62030602db0SMatthew G. Knepley 6219566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 6229566063dSJacob Faibussowitsch PetscCall(DMPlexIsSimplex(dm, &simplex)); 6239566063dSJacob Faibussowitsch PetscCall(PetscFECreateDefault(PETSC_COMM_WORLD, dim, user.Nc < 0 ? dim : user.Nc, simplex, NULL, user.qorder, &fe)); 6249566063dSJacob Faibussowitsch PetscCall(DMSetField(dm, 0, NULL, (PetscObject) fe)); 6259566063dSJacob Faibussowitsch PetscCall(PetscFEDestroy(&fe)); 6269566063dSJacob Faibussowitsch PetscCall(DMCreateDS(dm)); 62730602db0SMatthew G. Knepley 6289566063dSJacob Faibussowitsch PetscCall(CheckFunctions(dm, user.porder, &user)); 6299566063dSJacob Faibussowitsch PetscCall(CheckTransfer(dm, INTERPOLATION, user.porder, &user)); 6309566063dSJacob Faibussowitsch PetscCall(CheckTransfer(dm, INJECTION, user.porder, &user)); 6319566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm)); 6329566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 633b122ec5aSJacob Faibussowitsch return 0; 634557cf195SMatthew G. Knepley } 635557cf195SMatthew G. Knepley 636557cf195SMatthew G. Knepley /*TEST 637557cf195SMatthew G. Knepley 638557cf195SMatthew G. Knepley # TODO dim 3 will not work until I get composite elements in 3D (see plexrefine.c:34) 639557cf195SMatthew G. Knepley # 2D/3D P_1 on a simplex 640557cf195SMatthew G. Knepley test: 641557cf195SMatthew G. Knepley suffix: p1 642557cf195SMatthew G. Knepley requires: triangle ctetgen 64330602db0SMatthew 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} 644557cf195SMatthew G. Knepley test: 645557cf195SMatthew G. Knepley suffix: p1_pragmatic 646557cf195SMatthew G. Knepley requires: triangle ctetgen pragmatic 64730602db0SMatthew 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} 648557cf195SMatthew G. Knepley test: 649557cf195SMatthew G. Knepley suffix: p1_adapt 650557cf195SMatthew G. Knepley requires: triangle ctetgen 65130602db0SMatthew 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} 652557cf195SMatthew G. Knepley 653557cf195SMatthew G. Knepley # TODO dim 3 will not work until I get composite elements in 3D (see plexrefine.c:34) 654557cf195SMatthew G. Knepley # 2D/3D P_2 on a simplex 655557cf195SMatthew G. Knepley test: 656557cf195SMatthew G. Knepley suffix: p2 657557cf195SMatthew G. Knepley requires: triangle ctetgen 65830602db0SMatthew 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} 659557cf195SMatthew G. Knepley test: 660557cf195SMatthew G. Knepley suffix: p2_pragmatic 661557cf195SMatthew G. Knepley requires: triangle ctetgen pragmatic 66230602db0SMatthew 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} 663557cf195SMatthew G. Knepley 664557cf195SMatthew G. Knepley # TODO dim 3 will not work until I get composite elements in 3D (see plexrefine.c:34) 665557cf195SMatthew G. Knepley # TODO This is broken. Check ex3 which worked 666557cf195SMatthew G. Knepley # 2D/3D P_3 on a simplex 667557cf195SMatthew G. Knepley test: 668d6837840SMatthew G. Knepley TODO: gll Lagrange nodes break this 669557cf195SMatthew G. Knepley suffix: p3 670557cf195SMatthew G. Knepley requires: triangle ctetgen !single 67130602db0SMatthew 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} 672557cf195SMatthew G. Knepley test: 673d6837840SMatthew G. Knepley TODO: gll Lagrange nodes break this 674557cf195SMatthew G. Knepley suffix: p3_pragmatic 675557cf195SMatthew G. Knepley requires: triangle ctetgen pragmatic !single 67630602db0SMatthew 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} 677557cf195SMatthew G. Knepley 678557cf195SMatthew G. Knepley # 2D/3D Q_1 on a tensor cell 679557cf195SMatthew G. Knepley test: 680557cf195SMatthew G. Knepley suffix: q1 68130602db0SMatthew 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} 682557cf195SMatthew G. Knepley 683557cf195SMatthew G. Knepley # 2D/3D Q_2 on a tensor cell 684557cf195SMatthew G. Knepley test: 685557cf195SMatthew G. Knepley suffix: q2 68699a192c5SJunchao Zhang requires: !single 68730602db0SMatthew 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} 688557cf195SMatthew G. Knepley 689557cf195SMatthew G. Knepley # 2D/3D Q_3 on a tensor cell 690557cf195SMatthew G. Knepley test: 691d6837840SMatthew G. Knepley TODO: gll Lagrange nodes break this 692557cf195SMatthew G. Knepley suffix: q3 69399a192c5SJunchao Zhang requires: !single 69430602db0SMatthew 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} 695557cf195SMatthew G. Knepley 696557cf195SMatthew G. Knepley # 2D/3D P_1disc on a triangle/quadrilateral 697557cf195SMatthew G. Knepley # TODO Missing injection functional for simplices 698557cf195SMatthew G. Knepley test: 699557cf195SMatthew G. Knepley suffix: p1d 700557cf195SMatthew G. Knepley requires: triangle ctetgen 70130602db0SMatthew 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} 702557cf195SMatthew G. Knepley 703557cf195SMatthew G. Knepley TEST*/ 704