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); 350557cf195SMatthew G. Knepley ierr = PetscOptionsInt("-qorder", "The quadrature order", "ex8.c", options->qorder, &options->qorder, NULL);CHKERRQ(ierr); 351557cf195SMatthew G. Knepley ierr = PetscOptionsInt("-num_comp", "The number of field components", "ex8.c", options->Nc, &options->Nc, NULL);CHKERRQ(ierr); 352557cf195SMatthew G. Knepley ierr = PetscOptionsInt("-porder", "The order of polynomials to test", "ex8.c", options->porder, &options->porder, NULL);CHKERRQ(ierr); 353557cf195SMatthew G. Knepley ierr = PetscOptionsInt("-K", "The number of coarse modes used in optimization", "ex8.c", options->K, &options->K, NULL);CHKERRQ(ierr); 354557cf195SMatthew G. Knepley ierr = PetscOptionsBool("-use_poly", "Use polynomials (or harmonics) to adapt interpolator", "ex8.c", options->usePoly, &options->usePoly, NULL);CHKERRQ(ierr); 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 PetscErrorCode ierr; 362557cf195SMatthew G. Knepley 363557cf195SMatthew G. Knepley PetscFunctionBeginUser; 36430602db0SMatthew G. Knepley ierr = DMCreate(comm, dm);CHKERRQ(ierr); 36530602db0SMatthew G. Knepley ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 366557cf195SMatthew G. Knepley ierr = DMSetFromOptions(*dm);CHKERRQ(ierr); 367557cf195SMatthew G. Knepley ierr = DMViewFromOptions(*dm, NULL, "-dm_view");CHKERRQ(ierr); 368557cf195SMatthew G. Knepley PetscFunctionReturn(0); 369557cf195SMatthew G. Knepley } 370557cf195SMatthew G. Knepley 371557cf195SMatthew G. Knepley /* Setup functions to approximate */ 372557cf195SMatthew G. Knepley static PetscErrorCode SetupFunctions(DM dm, PetscBool usePoly, PetscInt order, PetscInt dir, PetscErrorCode (**exactFuncs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), 373557cf195SMatthew G. Knepley PetscErrorCode (**exactFuncDers)(PetscInt, PetscReal, const PetscReal[], const PetscReal[], PetscInt, PetscScalar *, void *), AppCtx *user) 374557cf195SMatthew G. Knepley { 375557cf195SMatthew G. Knepley PetscInt dim; 376557cf195SMatthew G. Knepley PetscErrorCode ierr; 377557cf195SMatthew G. Knepley 378557cf195SMatthew G. Knepley PetscFunctionBeginUser; 379557cf195SMatthew G. Knepley user->dir = dir; 380557cf195SMatthew G. Knepley if (usePoly) { 381557cf195SMatthew G. Knepley switch (order) { 382557cf195SMatthew G. Knepley case 0: 383557cf195SMatthew G. Knepley exactFuncs[0] = constant; 384557cf195SMatthew G. Knepley exactFuncDers[0] = constantDer; 385557cf195SMatthew G. Knepley break; 386557cf195SMatthew G. Knepley case 1: 387557cf195SMatthew G. Knepley exactFuncs[0] = linear; 388557cf195SMatthew G. Knepley exactFuncDers[0] = linearDer; 389557cf195SMatthew G. Knepley break; 390557cf195SMatthew G. Knepley case 2: 391557cf195SMatthew G. Knepley exactFuncs[0] = quadratic; 392557cf195SMatthew G. Knepley exactFuncDers[0] = quadraticDer; 393557cf195SMatthew G. Knepley break; 394557cf195SMatthew G. Knepley case 3: 395557cf195SMatthew G. Knepley exactFuncs[0] = cubic; 396557cf195SMatthew G. Knepley exactFuncDers[0] = cubicDer; 397557cf195SMatthew G. Knepley break; 398557cf195SMatthew G. Knepley case 4: 399557cf195SMatthew G. Knepley exactFuncs[0] = quartic; 400557cf195SMatthew G. Knepley exactFuncDers[0] = quarticDer; 401557cf195SMatthew G. Knepley break; 402557cf195SMatthew G. Knepley default: 403557cf195SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 404*98921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Could not determine functions to test for dimension %d order %d", dim, order); 405557cf195SMatthew G. Knepley } 406557cf195SMatthew G. Knepley } else { 407557cf195SMatthew G. Knepley user->m = order; 408557cf195SMatthew G. Knepley exactFuncs[0] = trig; 409557cf195SMatthew G. Knepley exactFuncDers[0] = trigDer; 410557cf195SMatthew G. Knepley } 411557cf195SMatthew G. Knepley PetscFunctionReturn(0); 412557cf195SMatthew G. Knepley } 413557cf195SMatthew G. Knepley 414557cf195SMatthew G. Knepley static PetscErrorCode ComputeError(DM dm, PetscErrorCode (**exactFuncs)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *), 415557cf195SMatthew G. Knepley PetscErrorCode (**exactFuncDers)(PetscInt, PetscReal, const PetscReal[], const PetscReal[], PetscInt, PetscScalar *, void *), 416557cf195SMatthew G. Knepley void **exactCtxs, PetscReal *error, PetscReal *errorDer, AppCtx *user) 417557cf195SMatthew G. Knepley { 418557cf195SMatthew G. Knepley Vec u; 419557cf195SMatthew G. Knepley PetscReal n[3] = {1.0, 1.0, 1.0}; 420557cf195SMatthew G. Knepley PetscErrorCode ierr; 421557cf195SMatthew G. Knepley 422557cf195SMatthew G. Knepley PetscFunctionBeginUser; 423557cf195SMatthew G. Knepley ierr = DMGetGlobalVector(dm, &u);CHKERRQ(ierr); 424557cf195SMatthew G. Knepley /* Project function into FE function space */ 425557cf195SMatthew G. Knepley ierr = DMProjectFunction(dm, 0.0, exactFuncs, exactCtxs, INSERT_ALL_VALUES, u);CHKERRQ(ierr); 426557cf195SMatthew G. Knepley ierr = VecViewFromOptions(u, NULL, "-projection_view");CHKERRQ(ierr); 427557cf195SMatthew G. Knepley /* Compare approximation to exact in L_2 */ 428557cf195SMatthew G. Knepley ierr = DMComputeL2Diff(dm, 0.0, exactFuncs, exactCtxs, u, error);CHKERRQ(ierr); 429557cf195SMatthew G. Knepley ierr = DMComputeL2GradientDiff(dm, 0.0, exactFuncDers, exactCtxs, u, n, errorDer);CHKERRQ(ierr); 430557cf195SMatthew G. Knepley ierr = DMRestoreGlobalVector(dm, &u);CHKERRQ(ierr); 431557cf195SMatthew G. Knepley PetscFunctionReturn(0); 432557cf195SMatthew G. Knepley } 433557cf195SMatthew G. Knepley 434557cf195SMatthew G. Knepley static PetscErrorCode CheckFunctions(DM dm, PetscInt order, AppCtx *user) 435557cf195SMatthew G. Knepley { 436557cf195SMatthew G. Knepley PetscErrorCode (*exactFuncs[1]) (PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar *u, void *ctx); 437557cf195SMatthew G. Knepley PetscErrorCode (*exactFuncDers[1]) (PetscInt dim, PetscReal time, const PetscReal x[], const PetscReal n[], PetscInt Nf, PetscScalar *u, void *ctx); 438557cf195SMatthew G. Knepley void *exactCtxs[3]; 439557cf195SMatthew G. Knepley MPI_Comm comm; 440557cf195SMatthew G. Knepley PetscReal error, errorDer, tol = PETSC_SMALL; 441557cf195SMatthew G. Knepley PetscErrorCode ierr; 442557cf195SMatthew G. Knepley 443557cf195SMatthew G. Knepley PetscFunctionBeginUser; 444557cf195SMatthew G. Knepley exactCtxs[0] = user; 445557cf195SMatthew G. Knepley exactCtxs[1] = user; 446557cf195SMatthew G. Knepley exactCtxs[2] = user; 447557cf195SMatthew G. Knepley user->constants[0] = 1.0; 448557cf195SMatthew G. Knepley user->constants[1] = 2.0; 449557cf195SMatthew G. Knepley user->constants[2] = 3.0; 450557cf195SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)dm, &comm);CHKERRQ(ierr); 451557cf195SMatthew G. Knepley ierr = SetupFunctions(dm, PETSC_TRUE, order, 0, exactFuncs, exactFuncDers, user);CHKERRQ(ierr); 452557cf195SMatthew G. Knepley ierr = ComputeError(dm, exactFuncs, exactFuncDers, exactCtxs, &error, &errorDer, user);CHKERRQ(ierr); 453557cf195SMatthew G. Knepley /* Report result */ 454557cf195SMatthew G. Knepley if (error > tol) {ierr = PetscPrintf(comm, "Function tests FAIL for order %D at tolerance %g error %g\n", order, (double)tol,(double) error);CHKERRQ(ierr);} 455557cf195SMatthew G. Knepley else {ierr = PetscPrintf(comm, "Function tests pass for order %D at tolerance %g\n", order, (double)tol);CHKERRQ(ierr);} 456557cf195SMatthew G. Knepley if (errorDer > tol) {ierr = PetscPrintf(comm, "Function tests FAIL for order %D derivatives at tolerance %g error %g\n", order, (double)tol, (double)errorDer);CHKERRQ(ierr);} 457557cf195SMatthew G. Knepley else {ierr = PetscPrintf(comm, "Function tests pass for order %D derivatives at tolerance %g\n", order, (double)tol);CHKERRQ(ierr);} 458557cf195SMatthew G. Knepley PetscFunctionReturn(0); 459557cf195SMatthew G. Knepley } 460557cf195SMatthew G. Knepley 461557cf195SMatthew G. Knepley /* Compare approximation to exact in L_2 */ 462557cf195SMatthew G. Knepley static PetscErrorCode CheckTransferError(DM fdm, PetscBool usePoly, PetscInt order, PetscInt dir, const char *testname, Vec fu, AppCtx *user) 463557cf195SMatthew G. Knepley { 464557cf195SMatthew G. Knepley PetscErrorCode (*exactFuncs[1]) (PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nf, PetscScalar *u, void *ctx); 465557cf195SMatthew G. Knepley PetscErrorCode (*exactFuncDers[1]) (PetscInt dim, PetscReal time, const PetscReal x[], const PetscReal n[], PetscInt Nf, PetscScalar *u, void *ctx); 466557cf195SMatthew G. Knepley PetscReal n[3] = {1.0, 1.0, 1.0}; 467557cf195SMatthew G. Knepley void *exactCtxs[3]; 468557cf195SMatthew G. Knepley MPI_Comm comm; 469557cf195SMatthew G. Knepley PetscReal error, errorDer, tol = PETSC_SMALL; 470557cf195SMatthew G. Knepley PetscErrorCode ierr; 471557cf195SMatthew G. Knepley 472557cf195SMatthew G. Knepley PetscFunctionBeginUser; 473557cf195SMatthew G. Knepley exactCtxs[0] = user; 474557cf195SMatthew G. Knepley exactCtxs[1] = user; 475557cf195SMatthew G. Knepley exactCtxs[2] = user; 476557cf195SMatthew G. Knepley user->constants[0] = 1.0; 477557cf195SMatthew G. Knepley user->constants[1] = 2.0; 478557cf195SMatthew G. Knepley user->constants[2] = 3.0; 479557cf195SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) fdm, &comm);CHKERRQ(ierr); 480557cf195SMatthew G. Knepley ierr = SetupFunctions(fdm, usePoly, order, dir, exactFuncs, exactFuncDers, user);CHKERRQ(ierr); 481557cf195SMatthew G. Knepley ierr = DMComputeL2Diff(fdm, 0.0, exactFuncs, exactCtxs, fu, &error);CHKERRQ(ierr); 482557cf195SMatthew G. Knepley ierr = DMComputeL2GradientDiff(fdm, 0.0, exactFuncDers, exactCtxs, fu, n, &errorDer);CHKERRQ(ierr); 483557cf195SMatthew G. Knepley /* Report result */ 484557cf195SMatthew G. Knepley if (error > tol) {ierr = PetscPrintf(comm, "%s tests FAIL for order %D at tolerance %g error %g\n", testname, order, (double)tol, (double)error);CHKERRQ(ierr);} 485557cf195SMatthew G. Knepley else {ierr = PetscPrintf(comm, "%s tests pass for order %D at tolerance %g\n", testname, order, (double)tol);CHKERRQ(ierr);} 486557cf195SMatthew G. Knepley if (errorDer > tol) {ierr = PetscPrintf(comm, "%s tests FAIL for order %D derivatives at tolerance %g error %g\n", testname, order, (double)tol, (double)errorDer);CHKERRQ(ierr);} 487557cf195SMatthew G. Knepley else {ierr = PetscPrintf(comm, "%s tests pass for order %D derivatives at tolerance %g\n", testname, order, (double)tol);CHKERRQ(ierr);} 488557cf195SMatthew G. Knepley PetscFunctionReturn(0); 489557cf195SMatthew G. Knepley } 490557cf195SMatthew G. Knepley 491557cf195SMatthew G. Knepley static PetscErrorCode CheckTransfer(DM dm, InterpType inType, PetscInt order, AppCtx *user) 492557cf195SMatthew G. Knepley { 493557cf195SMatthew G. Knepley PetscErrorCode (*exactFuncs[1]) (PetscInt, PetscReal, const PetscReal x[], PetscInt, PetscScalar *u, void *ctx); 494557cf195SMatthew G. Knepley PetscErrorCode (*exactFuncDers[1]) (PetscInt, PetscReal, const PetscReal x[], const PetscReal n[], PetscInt, PetscScalar *u, void *ctx); 495d6837840SMatthew G. Knepley void *exactCtxs[3]; 496d6837840SMatthew G. Knepley DM rdm = NULL, idm = NULL, fdm = NULL; 497557cf195SMatthew G. Knepley Mat Interp, InterpAdapt = NULL; 498d6837840SMatthew G. Knepley Vec iu, fu, scaling = NULL; 499557cf195SMatthew G. Knepley MPI_Comm comm; 500d6837840SMatthew G. Knepley const char *testname = "Unknown"; 501557cf195SMatthew G. Knepley char checkname[PETSC_MAX_PATH_LEN]; 502557cf195SMatthew G. Knepley PetscErrorCode ierr; 503557cf195SMatthew G. Knepley 504557cf195SMatthew G. Knepley PetscFunctionBeginUser; 505d6837840SMatthew G. Knepley exactCtxs[0] = exactCtxs[1] = exactCtxs[2] = user; 506557cf195SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 507557cf195SMatthew G. Knepley ierr = DMRefine(dm, comm, &rdm);CHKERRQ(ierr); 50830602db0SMatthew G. Knepley ierr = DMViewFromOptions(rdm, NULL, "-ref_dm_view");CHKERRQ(ierr); 509557cf195SMatthew G. Knepley ierr = DMSetCoarseDM(rdm, dm);CHKERRQ(ierr); 510557cf195SMatthew G. Knepley ierr = DMCopyDisc(dm, rdm);CHKERRQ(ierr); 511557cf195SMatthew G. Knepley switch (inType) { 512557cf195SMatthew G. Knepley case INTERPOLATION: 513557cf195SMatthew G. Knepley testname = "Interpolation"; 514557cf195SMatthew G. Knepley idm = dm; 515557cf195SMatthew G. Knepley fdm = rdm; 516557cf195SMatthew G. Knepley break; 517557cf195SMatthew G. Knepley case RESTRICTION: 518557cf195SMatthew G. Knepley testname = "Restriction"; 519557cf195SMatthew G. Knepley idm = rdm; 520557cf195SMatthew G. Knepley fdm = dm; 521557cf195SMatthew G. Knepley break; 522557cf195SMatthew G. Knepley case INJECTION: 523557cf195SMatthew G. Knepley testname = "Injection"; 524557cf195SMatthew G. Knepley idm = rdm; 525557cf195SMatthew G. Knepley fdm = dm; 526557cf195SMatthew G. Knepley break; 527557cf195SMatthew G. Knepley } 528557cf195SMatthew G. Knepley ierr = DMGetGlobalVector(idm, &iu);CHKERRQ(ierr); 529557cf195SMatthew G. Knepley ierr = DMGetGlobalVector(fdm, &fu);CHKERRQ(ierr); 530557cf195SMatthew G. Knepley ierr = DMSetApplicationContext(dm, user);CHKERRQ(ierr); 531557cf195SMatthew G. Knepley ierr = DMSetApplicationContext(rdm, user);CHKERRQ(ierr); 532557cf195SMatthew G. Knepley /* Project function into initial FE function space */ 533557cf195SMatthew G. Knepley ierr = SetupFunctions(dm, PETSC_TRUE, order, 0, exactFuncs, exactFuncDers, user);CHKERRQ(ierr); 534557cf195SMatthew G. Knepley ierr = DMProjectFunction(idm, 0.0, exactFuncs, exactCtxs, INSERT_ALL_VALUES, iu);CHKERRQ(ierr); 535557cf195SMatthew G. Knepley /* Interpolate function into final FE function space */ 536557cf195SMatthew G. Knepley switch (inType) { 537557cf195SMatthew G. Knepley case INTERPOLATION: 538557cf195SMatthew G. Knepley ierr = DMCreateInterpolation(dm, rdm, &Interp, &scaling);CHKERRQ(ierr); 539557cf195SMatthew G. Knepley ierr = MatInterpolate(Interp, iu, fu);CHKERRQ(ierr); 540557cf195SMatthew G. Knepley break; 541557cf195SMatthew G. Knepley case RESTRICTION: 542557cf195SMatthew G. Knepley ierr = DMCreateInterpolation(dm, rdm, &Interp, &scaling);CHKERRQ(ierr); 543557cf195SMatthew G. Knepley ierr = MatRestrict(Interp, iu, fu);CHKERRQ(ierr); 544557cf195SMatthew G. Knepley ierr = VecPointwiseMult(fu, scaling, fu);CHKERRQ(ierr); 545557cf195SMatthew G. Knepley break; 546557cf195SMatthew G. Knepley case INJECTION: 547557cf195SMatthew G. Knepley ierr = DMCreateInjection(dm, rdm, &Interp);CHKERRQ(ierr); 548557cf195SMatthew G. Knepley ierr = MatRestrict(Interp, iu, fu);CHKERRQ(ierr); 549557cf195SMatthew G. Knepley break; 550557cf195SMatthew G. Knepley } 551557cf195SMatthew G. Knepley ierr = CheckTransferError(fdm, PETSC_TRUE, order, 0, testname, fu, user);CHKERRQ(ierr); 552557cf195SMatthew G. Knepley if (user->K && (inType == INTERPOLATION)) { 553557cf195SMatthew G. Knepley KSP smoother; 554557cf195SMatthew G. Knepley Mat A; 555557cf195SMatthew G. Knepley Vec *iV, *fV; 556557cf195SMatthew G. Knepley PetscInt k, dim, d; 557557cf195SMatthew G. Knepley 558557cf195SMatthew G. Knepley ierr = PetscPrintf(comm, " Adapting interpolator using %s\n", user->usePoly ? "polynomials" : "harmonics");CHKERRQ(ierr); 559557cf195SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 560557cf195SMatthew G. Knepley ierr = PetscMalloc2(user->K*dim, &iV, user->K*dim, &fV);CHKERRQ(ierr); 561557cf195SMatthew G. Knepley /* Project coarse modes into initial and final FE function space */ 562557cf195SMatthew G. Knepley for (k = 0; k < user->K; ++k) { 563557cf195SMatthew G. Knepley for (d = 0; d < dim; ++d) { 564557cf195SMatthew G. Knepley ierr = DMGetGlobalVector(idm, &iV[k*dim+d]);CHKERRQ(ierr); 565557cf195SMatthew G. Knepley ierr = DMGetGlobalVector(fdm, &fV[k*dim+d]);CHKERRQ(ierr); 566557cf195SMatthew G. Knepley ierr = SetupFunctions(idm, user->usePoly, user->usePoly ? k : k+1, d, exactFuncs, exactFuncDers, user);CHKERRQ(ierr); 567557cf195SMatthew G. Knepley ierr = DMProjectFunction(idm, 0.0, exactFuncs, exactCtxs, INSERT_ALL_VALUES, iV[k*dim+d]);CHKERRQ(ierr); 568557cf195SMatthew G. Knepley ierr = DMProjectFunction(fdm, 0.0, exactFuncs, exactCtxs, INSERT_ALL_VALUES, fV[k*dim+d]);CHKERRQ(ierr); 569557cf195SMatthew G. Knepley } 570557cf195SMatthew G. Knepley } 571557cf195SMatthew G. Knepley /* Adapt interpolator */ 572557cf195SMatthew G. Knepley ierr = DMCreateMatrix(rdm, &A);CHKERRQ(ierr); 573557cf195SMatthew G. Knepley ierr = MatShift(A, 1.0);CHKERRQ(ierr); 574557cf195SMatthew G. Knepley ierr = KSPCreate(comm, &smoother);CHKERRQ(ierr); 575557cf195SMatthew G. Knepley ierr = KSPSetFromOptions(smoother);CHKERRQ(ierr); 576557cf195SMatthew G. Knepley ierr = KSPSetOperators(smoother, A, A);CHKERRQ(ierr); 577557cf195SMatthew G. Knepley ierr = DMAdaptInterpolator(dm, rdm, Interp, smoother, user->K*dim, fV, iV, &InterpAdapt, user);CHKERRQ(ierr); 578557cf195SMatthew G. Knepley /* Interpolate function into final FE function space */ 579557cf195SMatthew G. Knepley ierr = PetscSNPrintf(checkname, PETSC_MAX_PATH_LEN, " %s poly", testname);CHKERRQ(ierr); 580557cf195SMatthew G. Knepley ierr = MatInterpolate(InterpAdapt, iu, fu);CHKERRQ(ierr); 581557cf195SMatthew G. Knepley ierr = CheckTransferError(fdm, PETSC_TRUE, order, 0, checkname, fu, user);CHKERRQ(ierr); 582557cf195SMatthew G. Knepley for (k = 0; k < user->K; ++k) { 583557cf195SMatthew G. Knepley for (d = 0; d < dim; ++d) { 584557cf195SMatthew G. Knepley ierr = PetscSNPrintf(checkname, PETSC_MAX_PATH_LEN, " %s trig (%D, %D)", testname, k, d);CHKERRQ(ierr); 585557cf195SMatthew G. Knepley ierr = MatInterpolate(InterpAdapt, iV[k*dim+d], fV[k*dim+d]);CHKERRQ(ierr); 586557cf195SMatthew G. Knepley ierr = CheckTransferError(fdm, PETSC_FALSE, k+1, d, checkname, fV[k*dim+d], user);CHKERRQ(ierr); 587557cf195SMatthew G. Knepley } 588557cf195SMatthew G. Knepley } 589557cf195SMatthew G. Knepley /* Cleanup */ 590557cf195SMatthew G. Knepley ierr = KSPDestroy(&smoother);CHKERRQ(ierr); 591557cf195SMatthew G. Knepley ierr = MatDestroy(&A);CHKERRQ(ierr); 592557cf195SMatthew G. Knepley for (k = 0; k < user->K; ++k) { 593557cf195SMatthew G. Knepley for (d = 0; d < dim; ++d) { 594557cf195SMatthew G. Knepley ierr = DMRestoreGlobalVector(idm, &iV[k*dim+d]);CHKERRQ(ierr); 595557cf195SMatthew G. Knepley ierr = DMRestoreGlobalVector(fdm, &fV[k*dim+d]);CHKERRQ(ierr); 596557cf195SMatthew G. Knepley } 597557cf195SMatthew G. Knepley } 598557cf195SMatthew G. Knepley ierr = PetscFree2(iV, fV);CHKERRQ(ierr); 599557cf195SMatthew G. Knepley ierr = MatDestroy(&InterpAdapt);CHKERRQ(ierr); 600557cf195SMatthew G. Knepley } 601557cf195SMatthew G. Knepley ierr = DMRestoreGlobalVector(idm, &iu);CHKERRQ(ierr); 602557cf195SMatthew G. Knepley ierr = DMRestoreGlobalVector(fdm, &fu);CHKERRQ(ierr); 603557cf195SMatthew G. Knepley ierr = MatDestroy(&Interp);CHKERRQ(ierr); 604557cf195SMatthew G. Knepley ierr = VecDestroy(&scaling);CHKERRQ(ierr); 605557cf195SMatthew G. Knepley ierr = DMDestroy(&rdm);CHKERRQ(ierr); 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 PetscErrorCode ierr; 617557cf195SMatthew G. Knepley 618557cf195SMatthew G. Knepley ierr = PetscInitialize(&argc, &argv, NULL, help);if (ierr) return ierr; 619557cf195SMatthew G. Knepley ierr = ProcessOptions(PETSC_COMM_WORLD, &user);CHKERRQ(ierr); 620557cf195SMatthew G. Knepley ierr = CreateMesh(PETSC_COMM_WORLD, &user, &dm);CHKERRQ(ierr); 62130602db0SMatthew G. Knepley 62230602db0SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 62330602db0SMatthew G. Knepley ierr = DMPlexIsSimplex(dm, &simplex);CHKERRQ(ierr); 62430602db0SMatthew G. Knepley ierr = PetscFECreateDefault(PETSC_COMM_WORLD, dim, user.Nc < 0 ? dim : user.Nc, simplex, NULL, user.qorder, &fe);CHKERRQ(ierr); 62530602db0SMatthew G. Knepley ierr = DMSetField(dm, 0, NULL, (PetscObject) fe);CHKERRQ(ierr); 62630602db0SMatthew G. Knepley ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); 627557cf195SMatthew G. Knepley ierr = DMCreateDS(dm);CHKERRQ(ierr); 62830602db0SMatthew G. Knepley 629557cf195SMatthew G. Knepley ierr = CheckFunctions(dm, user.porder, &user);CHKERRQ(ierr); 630557cf195SMatthew G. Knepley ierr = CheckTransfer(dm, INTERPOLATION, user.porder, &user);CHKERRQ(ierr); 631557cf195SMatthew G. Knepley ierr = CheckTransfer(dm, INJECTION, user.porder, &user);CHKERRQ(ierr); 632557cf195SMatthew G. Knepley ierr = DMDestroy(&dm);CHKERRQ(ierr); 633557cf195SMatthew G. Knepley ierr = PetscFinalize(); 634557cf195SMatthew G. Knepley return ierr; 635557cf195SMatthew G. Knepley } 636557cf195SMatthew G. Knepley 637557cf195SMatthew G. Knepley /*TEST 638557cf195SMatthew G. Knepley 639557cf195SMatthew G. Knepley # TODO dim 3 will not work until I get composite elements in 3D (see plexrefine.c:34) 640557cf195SMatthew G. Knepley # 2D/3D P_1 on a simplex 641557cf195SMatthew G. Knepley test: 642557cf195SMatthew G. Knepley suffix: p1 643557cf195SMatthew G. Knepley requires: triangle ctetgen 64430602db0SMatthew 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} 645557cf195SMatthew G. Knepley test: 646557cf195SMatthew G. Knepley suffix: p1_pragmatic 647557cf195SMatthew G. Knepley requires: triangle ctetgen pragmatic 64830602db0SMatthew 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} 649557cf195SMatthew G. Knepley test: 650557cf195SMatthew G. Knepley suffix: p1_adapt 651557cf195SMatthew G. Knepley requires: triangle ctetgen 65230602db0SMatthew 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} 653557cf195SMatthew G. Knepley 654557cf195SMatthew G. Knepley # TODO dim 3 will not work until I get composite elements in 3D (see plexrefine.c:34) 655557cf195SMatthew G. Knepley # 2D/3D P_2 on a simplex 656557cf195SMatthew G. Knepley test: 657557cf195SMatthew G. Knepley suffix: p2 658557cf195SMatthew G. Knepley requires: triangle ctetgen 65930602db0SMatthew 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} 660557cf195SMatthew G. Knepley test: 661557cf195SMatthew G. Knepley suffix: p2_pragmatic 662557cf195SMatthew G. Knepley requires: triangle ctetgen pragmatic 66330602db0SMatthew 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} 664557cf195SMatthew G. Knepley 665557cf195SMatthew G. Knepley # TODO dim 3 will not work until I get composite elements in 3D (see plexrefine.c:34) 666557cf195SMatthew G. Knepley # TODO This is broken. Check ex3 which worked 667557cf195SMatthew G. Knepley # 2D/3D P_3 on a simplex 668557cf195SMatthew G. Knepley test: 669d6837840SMatthew G. Knepley TODO: gll Lagrange nodes break this 670557cf195SMatthew G. Knepley suffix: p3 671557cf195SMatthew G. Knepley requires: triangle ctetgen !single 67230602db0SMatthew 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} 673557cf195SMatthew G. Knepley test: 674d6837840SMatthew G. Knepley TODO: gll Lagrange nodes break this 675557cf195SMatthew G. Knepley suffix: p3_pragmatic 676557cf195SMatthew G. Knepley requires: triangle ctetgen pragmatic !single 67730602db0SMatthew 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} 678557cf195SMatthew G. Knepley 679557cf195SMatthew G. Knepley # 2D/3D Q_1 on a tensor cell 680557cf195SMatthew G. Knepley test: 681557cf195SMatthew G. Knepley suffix: q1 682557cf195SMatthew G. Knepley requires: mpi_type_get_envelope 68330602db0SMatthew 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} 684557cf195SMatthew G. Knepley 685557cf195SMatthew G. Knepley # 2D/3D Q_2 on a tensor cell 686557cf195SMatthew G. Knepley test: 687557cf195SMatthew G. Knepley suffix: q2 688d6837840SMatthew G. Knepley requires: mpi_type_get_envelope !single 68930602db0SMatthew 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} 690557cf195SMatthew G. Knepley 691557cf195SMatthew G. Knepley # 2D/3D Q_3 on a tensor cell 692557cf195SMatthew G. Knepley test: 693d6837840SMatthew G. Knepley TODO: gll Lagrange nodes break this 694557cf195SMatthew G. Knepley suffix: q3 695557cf195SMatthew G. Knepley requires: mpi_type_get_envelope !single 69630602db0SMatthew 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} 697557cf195SMatthew G. Knepley 698557cf195SMatthew G. Knepley # 2D/3D P_1disc on a triangle/quadrilateral 699557cf195SMatthew G. Knepley # TODO Missing injection functional for simplices 700557cf195SMatthew G. Knepley test: 701557cf195SMatthew G. Knepley suffix: p1d 702557cf195SMatthew G. Knepley requires: triangle ctetgen 70330602db0SMatthew 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} 704557cf195SMatthew G. Knepley 705557cf195SMatthew G. Knepley TEST*/ 706