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 PetscErrorCode ierr; 339557cf195SMatthew G. Knepley 340557cf195SMatthew G. Knepley PetscFunctionBeginUser; 341557cf195SMatthew G. Knepley options->qorder = 0; 342557cf195SMatthew G. Knepley options->Nc = PETSC_DEFAULT; 343557cf195SMatthew G. Knepley options->porder = 0; 344557cf195SMatthew G. Knepley options->m = 1; 345557cf195SMatthew G. Knepley options->dir = 0; 346557cf195SMatthew G. Knepley options->K = 0; 347557cf195SMatthew G. Knepley options->usePoly = PETSC_TRUE; 348557cf195SMatthew G. Knepley 349557cf195SMatthew G. Knepley ierr = PetscOptionsBegin(comm, "", "Projection Test Options", "DMPlex");CHKERRQ(ierr); 3505f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsInt("-qorder", "The quadrature order", "ex8.c", options->qorder, &options->qorder, NULL)); 3515f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsInt("-num_comp", "The number of field components", "ex8.c", options->Nc, &options->Nc, NULL)); 3525f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsInt("-porder", "The order of polynomials to test", "ex8.c", options->porder, &options->porder, NULL)); 3535f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsInt("-K", "The number of coarse modes used in optimization", "ex8.c", options->K, &options->K, NULL)); 3545f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsBool("-use_poly", "Use polynomials (or harmonics) to adapt interpolator", "ex8.c", options->usePoly, &options->usePoly, NULL)); 355557cf195SMatthew G. Knepley ierr = PetscOptionsEnd();CHKERRQ(ierr); 356557cf195SMatthew G. Knepley PetscFunctionReturn(0); 357557cf195SMatthew G. Knepley } 358557cf195SMatthew G. Knepley 359557cf195SMatthew G. Knepley static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm) 360557cf195SMatthew G. Knepley { 361557cf195SMatthew G. Knepley PetscFunctionBeginUser; 3625f80ce2aSJacob Faibussowitsch CHKERRQ(DMCreate(comm, dm)); 3635f80ce2aSJacob Faibussowitsch CHKERRQ(DMSetType(*dm, DMPLEX)); 3645f80ce2aSJacob Faibussowitsch CHKERRQ(DMSetFromOptions(*dm)); 3655f80ce2aSJacob Faibussowitsch CHKERRQ(DMViewFromOptions(*dm, NULL, "-dm_view")); 366557cf195SMatthew G. Knepley PetscFunctionReturn(0); 367557cf195SMatthew G. Knepley } 368557cf195SMatthew G. Knepley 369557cf195SMatthew G. Knepley /* Setup functions to approximate */ 370557cf195SMatthew G. Knepley static PetscErrorCode SetupFunctions(DM dm, PetscBool usePoly, PetscInt order, PetscInt dir, PetscErrorCode (**exactFuncs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), 371557cf195SMatthew G. Knepley PetscErrorCode (**exactFuncDers)(PetscInt, PetscReal, const PetscReal[], const PetscReal[], PetscInt, PetscScalar *, void *), AppCtx *user) 372557cf195SMatthew G. Knepley { 373557cf195SMatthew G. Knepley PetscInt dim; 374557cf195SMatthew G. Knepley 375557cf195SMatthew G. Knepley PetscFunctionBeginUser; 376557cf195SMatthew G. Knepley user->dir = dir; 377557cf195SMatthew G. Knepley if (usePoly) { 378557cf195SMatthew G. Knepley switch (order) { 379557cf195SMatthew G. Knepley case 0: 380557cf195SMatthew G. Knepley exactFuncs[0] = constant; 381557cf195SMatthew G. Knepley exactFuncDers[0] = constantDer; 382557cf195SMatthew G. Knepley break; 383557cf195SMatthew G. Knepley case 1: 384557cf195SMatthew G. Knepley exactFuncs[0] = linear; 385557cf195SMatthew G. Knepley exactFuncDers[0] = linearDer; 386557cf195SMatthew G. Knepley break; 387557cf195SMatthew G. Knepley case 2: 388557cf195SMatthew G. Knepley exactFuncs[0] = quadratic; 389557cf195SMatthew G. Knepley exactFuncDers[0] = quadraticDer; 390557cf195SMatthew G. Knepley break; 391557cf195SMatthew G. Knepley case 3: 392557cf195SMatthew G. Knepley exactFuncs[0] = cubic; 393557cf195SMatthew G. Knepley exactFuncDers[0] = cubicDer; 394557cf195SMatthew G. Knepley break; 395557cf195SMatthew G. Knepley case 4: 396557cf195SMatthew G. Knepley exactFuncs[0] = quartic; 397557cf195SMatthew G. Knepley exactFuncDers[0] = quarticDer; 398557cf195SMatthew G. Knepley break; 399557cf195SMatthew G. Knepley default: 4005f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetDimension(dm, &dim)); 40198921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Could not determine functions to test for dimension %d order %d", dim, order); 402557cf195SMatthew G. Knepley } 403557cf195SMatthew G. Knepley } else { 404557cf195SMatthew G. Knepley user->m = order; 405557cf195SMatthew G. Knepley exactFuncs[0] = trig; 406557cf195SMatthew G. Knepley exactFuncDers[0] = trigDer; 407557cf195SMatthew G. Knepley } 408557cf195SMatthew G. Knepley PetscFunctionReturn(0); 409557cf195SMatthew G. Knepley } 410557cf195SMatthew G. Knepley 411557cf195SMatthew G. Knepley static PetscErrorCode ComputeError(DM dm, PetscErrorCode (**exactFuncs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), 412557cf195SMatthew G. Knepley PetscErrorCode (**exactFuncDers)(PetscInt, PetscReal, const PetscReal[], const PetscReal[], PetscInt, PetscScalar *, void *), 413557cf195SMatthew G. Knepley void **exactCtxs, PetscReal *error, PetscReal *errorDer, AppCtx *user) 414557cf195SMatthew G. Knepley { 415557cf195SMatthew G. Knepley Vec u; 416557cf195SMatthew G. Knepley PetscReal n[3] = {1.0, 1.0, 1.0}; 417557cf195SMatthew G. Knepley 418557cf195SMatthew G. Knepley PetscFunctionBeginUser; 4195f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetGlobalVector(dm, &u)); 420557cf195SMatthew G. Knepley /* Project function into FE function space */ 4215f80ce2aSJacob Faibussowitsch CHKERRQ(DMProjectFunction(dm, 0.0, exactFuncs, exactCtxs, INSERT_ALL_VALUES, u)); 4225f80ce2aSJacob Faibussowitsch CHKERRQ(VecViewFromOptions(u, NULL, "-projection_view")); 423557cf195SMatthew G. Knepley /* Compare approximation to exact in L_2 */ 4245f80ce2aSJacob Faibussowitsch CHKERRQ(DMComputeL2Diff(dm, 0.0, exactFuncs, exactCtxs, u, error)); 4255f80ce2aSJacob Faibussowitsch CHKERRQ(DMComputeL2GradientDiff(dm, 0.0, exactFuncDers, exactCtxs, u, n, errorDer)); 4265f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreGlobalVector(dm, &u)); 427557cf195SMatthew G. Knepley PetscFunctionReturn(0); 428557cf195SMatthew G. Knepley } 429557cf195SMatthew G. Knepley 430557cf195SMatthew G. Knepley static PetscErrorCode CheckFunctions(DM dm, PetscInt order, AppCtx *user) 431557cf195SMatthew G. Knepley { 432557cf195SMatthew G. Knepley PetscErrorCode (*exactFuncs[1]) (PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar *u, void *ctx); 433557cf195SMatthew G. Knepley PetscErrorCode (*exactFuncDers[1]) (PetscInt dim, PetscReal time, const PetscReal x[], const PetscReal n[], PetscInt Nf, PetscScalar *u, void *ctx); 434557cf195SMatthew G. Knepley void *exactCtxs[3]; 435557cf195SMatthew G. Knepley MPI_Comm comm; 436557cf195SMatthew G. Knepley PetscReal error, errorDer, tol = PETSC_SMALL; 437557cf195SMatthew G. Knepley 438557cf195SMatthew G. Knepley PetscFunctionBeginUser; 439557cf195SMatthew G. Knepley exactCtxs[0] = user; 440557cf195SMatthew G. Knepley exactCtxs[1] = user; 441557cf195SMatthew G. Knepley exactCtxs[2] = user; 442557cf195SMatthew G. Knepley user->constants[0] = 1.0; 443557cf195SMatthew G. Knepley user->constants[1] = 2.0; 444557cf195SMatthew G. Knepley user->constants[2] = 3.0; 4455f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectGetComm((PetscObject)dm, &comm)); 4465f80ce2aSJacob Faibussowitsch CHKERRQ(SetupFunctions(dm, PETSC_TRUE, order, 0, exactFuncs, exactFuncDers, user)); 4475f80ce2aSJacob Faibussowitsch CHKERRQ(ComputeError(dm, exactFuncs, exactFuncDers, exactCtxs, &error, &errorDer, user)); 448557cf195SMatthew G. Knepley /* Report result */ 4495f80ce2aSJacob Faibussowitsch if (error > tol) CHKERRQ(PetscPrintf(comm, "Function tests FAIL for order %D at tolerance %g error %g\n", order, (double)tol,(double) error)); 4505f80ce2aSJacob Faibussowitsch else CHKERRQ(PetscPrintf(comm, "Function tests pass for order %D at tolerance %g\n", order, (double)tol)); 4515f80ce2aSJacob Faibussowitsch if (errorDer > tol) CHKERRQ(PetscPrintf(comm, "Function tests FAIL for order %D derivatives at tolerance %g error %g\n", order, (double)tol, (double)errorDer)); 4525f80ce2aSJacob Faibussowitsch else CHKERRQ(PetscPrintf(comm, "Function tests pass for order %D derivatives at tolerance %g\n", order, (double)tol)); 453557cf195SMatthew G. Knepley PetscFunctionReturn(0); 454557cf195SMatthew G. Knepley } 455557cf195SMatthew G. Knepley 456557cf195SMatthew G. Knepley /* Compare approximation to exact in L_2 */ 457557cf195SMatthew G. Knepley static PetscErrorCode CheckTransferError(DM fdm, PetscBool usePoly, PetscInt order, PetscInt dir, const char *testname, Vec fu, AppCtx *user) 458557cf195SMatthew G. Knepley { 459557cf195SMatthew G. Knepley PetscErrorCode (*exactFuncs[1]) (PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar *u, void *ctx); 460557cf195SMatthew G. Knepley PetscErrorCode (*exactFuncDers[1]) (PetscInt dim, PetscReal time, const PetscReal x[], const PetscReal n[], PetscInt Nf, PetscScalar *u, void *ctx); 461557cf195SMatthew G. Knepley PetscReal n[3] = {1.0, 1.0, 1.0}; 462557cf195SMatthew G. Knepley void *exactCtxs[3]; 463557cf195SMatthew G. Knepley MPI_Comm comm; 464557cf195SMatthew G. Knepley PetscReal error, errorDer, tol = PETSC_SMALL; 465557cf195SMatthew G. Knepley 466557cf195SMatthew G. Knepley PetscFunctionBeginUser; 467557cf195SMatthew G. Knepley exactCtxs[0] = user; 468557cf195SMatthew G. Knepley exactCtxs[1] = user; 469557cf195SMatthew G. Knepley exactCtxs[2] = user; 470557cf195SMatthew G. Knepley user->constants[0] = 1.0; 471557cf195SMatthew G. Knepley user->constants[1] = 2.0; 472557cf195SMatthew G. Knepley user->constants[2] = 3.0; 4735f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectGetComm((PetscObject) fdm, &comm)); 4745f80ce2aSJacob Faibussowitsch CHKERRQ(SetupFunctions(fdm, usePoly, order, dir, exactFuncs, exactFuncDers, user)); 4755f80ce2aSJacob Faibussowitsch CHKERRQ(DMComputeL2Diff(fdm, 0.0, exactFuncs, exactCtxs, fu, &error)); 4765f80ce2aSJacob Faibussowitsch CHKERRQ(DMComputeL2GradientDiff(fdm, 0.0, exactFuncDers, exactCtxs, fu, n, &errorDer)); 477557cf195SMatthew G. Knepley /* Report result */ 4785f80ce2aSJacob Faibussowitsch if (error > tol) CHKERRQ(PetscPrintf(comm, "%s tests FAIL for order %D at tolerance %g error %g\n", testname, order, (double)tol, (double)error)); 4795f80ce2aSJacob Faibussowitsch else CHKERRQ(PetscPrintf(comm, "%s tests pass for order %D at tolerance %g\n", testname, order, (double)tol)); 4805f80ce2aSJacob Faibussowitsch if (errorDer > tol) CHKERRQ(PetscPrintf(comm, "%s tests FAIL for order %D derivatives at tolerance %g error %g\n", testname, order, (double)tol, (double)errorDer)); 4815f80ce2aSJacob Faibussowitsch else CHKERRQ(PetscPrintf(comm, "%s tests pass for order %D derivatives at tolerance %g\n", testname, order, (double)tol)); 482557cf195SMatthew G. Knepley PetscFunctionReturn(0); 483557cf195SMatthew G. Knepley } 484557cf195SMatthew G. Knepley 485557cf195SMatthew G. Knepley static PetscErrorCode CheckTransfer(DM dm, InterpType inType, PetscInt order, AppCtx *user) 486557cf195SMatthew G. Knepley { 487557cf195SMatthew G. Knepley PetscErrorCode (*exactFuncs[1]) (PetscInt, PetscReal, const PetscReal x[], PetscInt, PetscScalar *u, void *ctx); 488557cf195SMatthew G. Knepley PetscErrorCode (*exactFuncDers[1]) (PetscInt, PetscReal, const PetscReal x[], const PetscReal n[], PetscInt, PetscScalar *u, void *ctx); 489d6837840SMatthew G. Knepley void *exactCtxs[3]; 490d6837840SMatthew G. Knepley DM rdm = NULL, idm = NULL, fdm = NULL; 491557cf195SMatthew G. Knepley Mat Interp, InterpAdapt = NULL; 492d6837840SMatthew G. Knepley Vec iu, fu, scaling = NULL; 493557cf195SMatthew G. Knepley MPI_Comm comm; 494d6837840SMatthew G. Knepley const char *testname = "Unknown"; 495557cf195SMatthew G. Knepley char checkname[PETSC_MAX_PATH_LEN]; 496557cf195SMatthew G. Knepley 497557cf195SMatthew G. Knepley PetscFunctionBeginUser; 498d6837840SMatthew G. Knepley exactCtxs[0] = exactCtxs[1] = exactCtxs[2] = user; 4995f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectGetComm((PetscObject)dm,&comm)); 5005f80ce2aSJacob Faibussowitsch CHKERRQ(DMRefine(dm, comm, &rdm)); 5015f80ce2aSJacob Faibussowitsch CHKERRQ(DMViewFromOptions(rdm, NULL, "-ref_dm_view")); 5025f80ce2aSJacob Faibussowitsch CHKERRQ(DMSetCoarseDM(rdm, dm)); 5035f80ce2aSJacob Faibussowitsch CHKERRQ(DMCopyDisc(dm, rdm)); 504557cf195SMatthew G. Knepley switch (inType) { 505557cf195SMatthew G. Knepley case INTERPOLATION: 506557cf195SMatthew G. Knepley testname = "Interpolation"; 507557cf195SMatthew G. Knepley idm = dm; 508557cf195SMatthew G. Knepley fdm = rdm; 509557cf195SMatthew G. Knepley break; 510557cf195SMatthew G. Knepley case RESTRICTION: 511557cf195SMatthew G. Knepley testname = "Restriction"; 512557cf195SMatthew G. Knepley idm = rdm; 513557cf195SMatthew G. Knepley fdm = dm; 514557cf195SMatthew G. Knepley break; 515557cf195SMatthew G. Knepley case INJECTION: 516557cf195SMatthew G. Knepley testname = "Injection"; 517557cf195SMatthew G. Knepley idm = rdm; 518557cf195SMatthew G. Knepley fdm = dm; 519557cf195SMatthew G. Knepley break; 520557cf195SMatthew G. Knepley } 5215f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetGlobalVector(idm, &iu)); 5225f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetGlobalVector(fdm, &fu)); 5235f80ce2aSJacob Faibussowitsch CHKERRQ(DMSetApplicationContext(dm, user)); 5245f80ce2aSJacob Faibussowitsch CHKERRQ(DMSetApplicationContext(rdm, user)); 525557cf195SMatthew G. Knepley /* Project function into initial FE function space */ 5265f80ce2aSJacob Faibussowitsch CHKERRQ(SetupFunctions(dm, PETSC_TRUE, order, 0, exactFuncs, exactFuncDers, user)); 5275f80ce2aSJacob Faibussowitsch CHKERRQ(DMProjectFunction(idm, 0.0, exactFuncs, exactCtxs, INSERT_ALL_VALUES, iu)); 528557cf195SMatthew G. Knepley /* Interpolate function into final FE function space */ 529557cf195SMatthew G. Knepley switch (inType) { 530557cf195SMatthew G. Knepley case INTERPOLATION: 5315f80ce2aSJacob Faibussowitsch CHKERRQ(DMCreateInterpolation(dm, rdm, &Interp, &scaling)); 5325f80ce2aSJacob Faibussowitsch CHKERRQ(MatInterpolate(Interp, iu, fu)); 533557cf195SMatthew G. Knepley break; 534557cf195SMatthew G. Knepley case RESTRICTION: 5355f80ce2aSJacob Faibussowitsch CHKERRQ(DMCreateInterpolation(dm, rdm, &Interp, &scaling)); 5365f80ce2aSJacob Faibussowitsch CHKERRQ(MatRestrict(Interp, iu, fu)); 5375f80ce2aSJacob Faibussowitsch CHKERRQ(VecPointwiseMult(fu, scaling, fu)); 538557cf195SMatthew G. Knepley break; 539557cf195SMatthew G. Knepley case INJECTION: 5405f80ce2aSJacob Faibussowitsch CHKERRQ(DMCreateInjection(dm, rdm, &Interp)); 5415f80ce2aSJacob Faibussowitsch CHKERRQ(MatRestrict(Interp, iu, fu)); 542557cf195SMatthew G. Knepley break; 543557cf195SMatthew G. Knepley } 5445f80ce2aSJacob Faibussowitsch CHKERRQ(CheckTransferError(fdm, PETSC_TRUE, order, 0, testname, fu, user)); 545557cf195SMatthew G. Knepley if (user->K && (inType == INTERPOLATION)) { 546557cf195SMatthew G. Knepley KSP smoother; 547557cf195SMatthew G. Knepley Mat A; 548557cf195SMatthew G. Knepley Vec *iV, *fV; 549557cf195SMatthew G. Knepley PetscInt k, dim, d; 550557cf195SMatthew G. Knepley 5515f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(comm, " Adapting interpolator using %s\n", user->usePoly ? "polynomials" : "harmonics")); 5525f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetDimension(dm, &dim)); 5535f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc2(user->K*dim, &iV, user->K*dim, &fV)); 554557cf195SMatthew G. Knepley /* Project coarse modes into initial and final FE function space */ 555557cf195SMatthew G. Knepley for (k = 0; k < user->K; ++k) { 556557cf195SMatthew G. Knepley for (d = 0; d < dim; ++d) { 5575f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetGlobalVector(idm, &iV[k*dim+d])); 5585f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetGlobalVector(fdm, &fV[k*dim+d])); 5595f80ce2aSJacob Faibussowitsch CHKERRQ(SetupFunctions(idm, user->usePoly, user->usePoly ? k : k+1, d, exactFuncs, exactFuncDers, user)); 5605f80ce2aSJacob Faibussowitsch CHKERRQ(DMProjectFunction(idm, 0.0, exactFuncs, exactCtxs, INSERT_ALL_VALUES, iV[k*dim+d])); 5615f80ce2aSJacob Faibussowitsch CHKERRQ(DMProjectFunction(fdm, 0.0, exactFuncs, exactCtxs, INSERT_ALL_VALUES, fV[k*dim+d])); 562557cf195SMatthew G. Knepley } 563557cf195SMatthew G. Knepley } 564557cf195SMatthew G. Knepley /* Adapt interpolator */ 5655f80ce2aSJacob Faibussowitsch CHKERRQ(DMCreateMatrix(rdm, &A)); 5665f80ce2aSJacob Faibussowitsch CHKERRQ(MatShift(A, 1.0)); 5675f80ce2aSJacob Faibussowitsch CHKERRQ(KSPCreate(comm, &smoother)); 5685f80ce2aSJacob Faibussowitsch CHKERRQ(KSPSetFromOptions(smoother)); 5695f80ce2aSJacob Faibussowitsch CHKERRQ(KSPSetOperators(smoother, A, A)); 5705f80ce2aSJacob Faibussowitsch CHKERRQ(DMAdaptInterpolator(dm, rdm, Interp, smoother, user->K*dim, fV, iV, &InterpAdapt, user)); 571557cf195SMatthew G. Knepley /* Interpolate function into final FE function space */ 5725f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSNPrintf(checkname, PETSC_MAX_PATH_LEN, " %s poly", testname)); 5735f80ce2aSJacob Faibussowitsch CHKERRQ(MatInterpolate(InterpAdapt, iu, fu)); 5745f80ce2aSJacob Faibussowitsch CHKERRQ(CheckTransferError(fdm, PETSC_TRUE, order, 0, checkname, fu, user)); 575557cf195SMatthew G. Knepley for (k = 0; k < user->K; ++k) { 576557cf195SMatthew G. Knepley for (d = 0; d < dim; ++d) { 5775f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSNPrintf(checkname, PETSC_MAX_PATH_LEN, " %s trig (%D, %D)", testname, k, d)); 5785f80ce2aSJacob Faibussowitsch CHKERRQ(MatInterpolate(InterpAdapt, iV[k*dim+d], fV[k*dim+d])); 5795f80ce2aSJacob Faibussowitsch CHKERRQ(CheckTransferError(fdm, PETSC_FALSE, k+1, d, checkname, fV[k*dim+d], user)); 580557cf195SMatthew G. Knepley } 581557cf195SMatthew G. Knepley } 582557cf195SMatthew G. Knepley /* Cleanup */ 5835f80ce2aSJacob Faibussowitsch CHKERRQ(KSPDestroy(&smoother)); 5845f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&A)); 585557cf195SMatthew G. Knepley for (k = 0; k < user->K; ++k) { 586557cf195SMatthew G. Knepley for (d = 0; d < dim; ++d) { 5875f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreGlobalVector(idm, &iV[k*dim+d])); 5885f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreGlobalVector(fdm, &fV[k*dim+d])); 589557cf195SMatthew G. Knepley } 590557cf195SMatthew G. Knepley } 5915f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree2(iV, fV)); 5925f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&InterpAdapt)); 593557cf195SMatthew G. Knepley } 5945f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreGlobalVector(idm, &iu)); 5955f80ce2aSJacob Faibussowitsch CHKERRQ(DMRestoreGlobalVector(fdm, &fu)); 5965f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&Interp)); 5975f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&scaling)); 5985f80ce2aSJacob Faibussowitsch CHKERRQ(DMDestroy(&rdm)); 599557cf195SMatthew G. Knepley PetscFunctionReturn(0); 600557cf195SMatthew G. Knepley } 601557cf195SMatthew G. Knepley 602557cf195SMatthew G. Knepley int main(int argc, char **argv) 603557cf195SMatthew G. Knepley { 604557cf195SMatthew G. Knepley DM dm; 60530602db0SMatthew G. Knepley PetscFE fe; 60630602db0SMatthew G. Knepley AppCtx user; 60730602db0SMatthew G. Knepley PetscInt dim; 60830602db0SMatthew G. Knepley PetscBool simplex; 609557cf195SMatthew G. Knepley 610*b122ec5aSJacob Faibussowitsch CHKERRQ(PetscInitialize(&argc, &argv, NULL, help)); 6115f80ce2aSJacob Faibussowitsch CHKERRQ(ProcessOptions(PETSC_COMM_WORLD, &user)); 6125f80ce2aSJacob Faibussowitsch CHKERRQ(CreateMesh(PETSC_COMM_WORLD, &user, &dm)); 61330602db0SMatthew G. Knepley 6145f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetDimension(dm, &dim)); 6155f80ce2aSJacob Faibussowitsch CHKERRQ(DMPlexIsSimplex(dm, &simplex)); 6165f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFECreateDefault(PETSC_COMM_WORLD, dim, user.Nc < 0 ? dim : user.Nc, simplex, NULL, user.qorder, &fe)); 6175f80ce2aSJacob Faibussowitsch CHKERRQ(DMSetField(dm, 0, NULL, (PetscObject) fe)); 6185f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEDestroy(&fe)); 6195f80ce2aSJacob Faibussowitsch CHKERRQ(DMCreateDS(dm)); 62030602db0SMatthew G. Knepley 6215f80ce2aSJacob Faibussowitsch CHKERRQ(CheckFunctions(dm, user.porder, &user)); 6225f80ce2aSJacob Faibussowitsch CHKERRQ(CheckTransfer(dm, INTERPOLATION, user.porder, &user)); 6235f80ce2aSJacob Faibussowitsch CHKERRQ(CheckTransfer(dm, INJECTION, user.porder, &user)); 6245f80ce2aSJacob Faibussowitsch CHKERRQ(DMDestroy(&dm)); 625*b122ec5aSJacob Faibussowitsch CHKERRQ(PetscFinalize()); 626*b122ec5aSJacob Faibussowitsch return 0; 627557cf195SMatthew G. Knepley } 628557cf195SMatthew G. Knepley 629557cf195SMatthew G. Knepley /*TEST 630557cf195SMatthew G. Knepley 631557cf195SMatthew G. Knepley # TODO dim 3 will not work until I get composite elements in 3D (see plexrefine.c:34) 632557cf195SMatthew G. Knepley # 2D/3D P_1 on a simplex 633557cf195SMatthew G. Knepley test: 634557cf195SMatthew G. Knepley suffix: p1 635557cf195SMatthew G. Knepley requires: triangle ctetgen 63630602db0SMatthew 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} 637557cf195SMatthew G. Knepley test: 638557cf195SMatthew G. Knepley suffix: p1_pragmatic 639557cf195SMatthew G. Knepley requires: triangle ctetgen pragmatic 64030602db0SMatthew 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} 641557cf195SMatthew G. Knepley test: 642557cf195SMatthew G. Knepley suffix: p1_adapt 643557cf195SMatthew G. Knepley requires: triangle ctetgen 64430602db0SMatthew 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} 645557cf195SMatthew G. Knepley 646557cf195SMatthew G. Knepley # TODO dim 3 will not work until I get composite elements in 3D (see plexrefine.c:34) 647557cf195SMatthew G. Knepley # 2D/3D P_2 on a simplex 648557cf195SMatthew G. Knepley test: 649557cf195SMatthew G. Knepley suffix: p2 650557cf195SMatthew G. Knepley requires: triangle ctetgen 65130602db0SMatthew 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} 652557cf195SMatthew G. Knepley test: 653557cf195SMatthew G. Knepley suffix: p2_pragmatic 654557cf195SMatthew G. Knepley requires: triangle ctetgen pragmatic 65530602db0SMatthew 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} 656557cf195SMatthew G. Knepley 657557cf195SMatthew G. Knepley # TODO dim 3 will not work until I get composite elements in 3D (see plexrefine.c:34) 658557cf195SMatthew G. Knepley # TODO This is broken. Check ex3 which worked 659557cf195SMatthew G. Knepley # 2D/3D P_3 on a simplex 660557cf195SMatthew G. Knepley test: 661d6837840SMatthew G. Knepley TODO: gll Lagrange nodes break this 662557cf195SMatthew G. Knepley suffix: p3 663557cf195SMatthew G. Knepley requires: triangle ctetgen !single 66430602db0SMatthew 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} 665557cf195SMatthew G. Knepley test: 666d6837840SMatthew G. Knepley TODO: gll Lagrange nodes break this 667557cf195SMatthew G. Knepley suffix: p3_pragmatic 668557cf195SMatthew G. Knepley requires: triangle ctetgen pragmatic !single 66930602db0SMatthew 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} 670557cf195SMatthew G. Knepley 671557cf195SMatthew G. Knepley # 2D/3D Q_1 on a tensor cell 672557cf195SMatthew G. Knepley test: 673557cf195SMatthew G. Knepley suffix: q1 67430602db0SMatthew 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} 675557cf195SMatthew G. Knepley 676557cf195SMatthew G. Knepley # 2D/3D Q_2 on a tensor cell 677557cf195SMatthew G. Knepley test: 678557cf195SMatthew G. Knepley suffix: q2 67999a192c5SJunchao Zhang requires: !single 68030602db0SMatthew 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} 681557cf195SMatthew G. Knepley 682557cf195SMatthew G. Knepley # 2D/3D Q_3 on a tensor cell 683557cf195SMatthew G. Knepley test: 684d6837840SMatthew G. Knepley TODO: gll Lagrange nodes break this 685557cf195SMatthew G. Knepley suffix: q3 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 3 -qorder 3 -porder {{1 2 3 4}separate output} 688557cf195SMatthew G. Knepley 689557cf195SMatthew G. Knepley # 2D/3D P_1disc on a triangle/quadrilateral 690557cf195SMatthew G. Knepley # TODO Missing injection functional for simplices 691557cf195SMatthew G. Knepley test: 692557cf195SMatthew G. Knepley suffix: p1d 693557cf195SMatthew G. Knepley requires: triangle ctetgen 69430602db0SMatthew 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} 695557cf195SMatthew G. Knepley 696557cf195SMatthew G. Knepley TEST*/ 697