PageRenderTime 25ms CodeModel.GetById 43ms RepoModel.GetById 0ms app.codeStats 0ms

/apps/c/airfoil/airfoil_tempdats/dp/airfoil.cpp

https://github.com/OP2/OP2-Common
C++ | 314 lines | 186 code | 61 blank | 67 comment | 30 complexity | 5b937ec33f1d5903501b024dea6bb85e MD5 | raw file
  1. /*
  2. * Open source copyright declaration based on BSD open source template:
  3. * http://www.opensource.org/licenses/bsd-license.php
  4. *
  5. * This file is part of the OP2 distribution.
  6. *
  7. * Copyright (c) 2011, Mike Giles and others. Please see the AUTHORS file in
  8. * the main source directory for a full list of copyright holders.
  9. * All rights reserved.
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions are met:
  13. * * Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. * * Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in the
  17. * documentation and/or other materials provided with the distribution.
  18. * * The name of Mike Giles may not be used to endorse or promote products
  19. * derived from this software without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY Mike Giles ''AS IS'' AND ANY
  22. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  23. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  24. * DISCLAIMED. IN NO EVENT SHALL Mike Giles BE LIABLE FOR ANY
  25. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  26. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  27. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  28. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. */
  32. //
  33. // Nonlinear airfoil lift calculation
  34. //
  35. // Written by Mike Giles, 2010-2011, based on FORTRAN code
  36. // by Devendra Ghate and Mike Giles, 2005
  37. //
  38. //
  39. // standard headers
  40. //
  41. #include <math.h>
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <string.h>
  45. // global constants
  46. double gam, gm1, cfl, eps, mach, alpha, qinf[4];
  47. //
  48. // OP header file
  49. //
  50. #include "op_seq.h"
  51. //
  52. // kernel routines for parallel loops
  53. //
  54. #include "adt_calc.h"
  55. #include "bres_calc.h"
  56. #include "res_calc.h"
  57. #include "save_soln.h"
  58. #include "update.h"
  59. // main program
  60. int main(int argc, char **argv) {
  61. // OP initialisation
  62. op_init(argc, argv, 2);
  63. int *becell, *ecell, *bound, *bedge, *edge, *cell;
  64. double *x, *q, *qold, *adt, *res;
  65. int nnode, ncell, nedge, nbedge, niter;
  66. double rms;
  67. // timer
  68. double cpu_t1, cpu_t2, wall_t1, wall_t2;
  69. // read in grid
  70. op_printf("reading in grid \n");
  71. FILE *fp;
  72. if ((fp = fopen("./new_grid.dat", "r")) == NULL) {
  73. op_printf("can't open file new_grid.dat\n");
  74. exit(-1);
  75. }
  76. if (fscanf(fp, "%d %d %d %d \n", &nnode, &ncell, &nedge, &nbedge) != 4) {
  77. op_printf("error reading from new_grid.dat\n");
  78. exit(-1);
  79. }
  80. cell = (int *)malloc(4 * ncell * sizeof(int));
  81. edge = (int *)malloc(2 * nedge * sizeof(int));
  82. ecell = (int *)malloc(2 * nedge * sizeof(int));
  83. bedge = (int *)malloc(2 * nbedge * sizeof(int));
  84. becell = (int *)malloc(nbedge * sizeof(int));
  85. bound = (int *)malloc(nbedge * sizeof(int));
  86. x = (double *)malloc(2 * nnode * sizeof(double));
  87. q = (double *)malloc(4 * ncell * sizeof(double));
  88. qold = (double *)malloc(4 * ncell * sizeof(double));
  89. res = (double *)malloc(4 * ncell * sizeof(double));
  90. adt = (double *)malloc(ncell * sizeof(double));
  91. for (int n = 0; n < nnode; n++) {
  92. if (fscanf(fp, "%lf %lf \n", &x[2 * n], &x[2 * n + 1]) != 2) {
  93. op_printf("error reading from new_grid.dat\n");
  94. exit(-1);
  95. }
  96. }
  97. for (int n = 0; n < ncell; n++) {
  98. if (fscanf(fp, "%d %d %d %d \n", &cell[4 * n], &cell[4 * n + 1],
  99. &cell[4 * n + 2], &cell[4 * n + 3]) != 4) {
  100. op_printf("error reading from new_grid.dat\n");
  101. exit(-1);
  102. }
  103. }
  104. for (int n = 0; n < nedge; n++) {
  105. if (fscanf(fp, "%d %d %d %d \n", &edge[2 * n], &edge[2 * n + 1],
  106. &ecell[2 * n], &ecell[2 * n + 1]) != 4) {
  107. op_printf("error reading from new_grid.dat\n");
  108. exit(-1);
  109. }
  110. }
  111. for (int n = 0; n < nbedge; n++) {
  112. if (fscanf(fp, "%d %d %d %d \n", &bedge[2 * n], &bedge[2 * n + 1],
  113. &becell[n], &bound[n]) != 4) {
  114. op_printf("error reading from new_grid.dat\n");
  115. exit(-1);
  116. }
  117. }
  118. fclose(fp);
  119. // set constants and initialise flow field and residual
  120. op_printf("initialising flow field \n");
  121. gam = 1.4f;
  122. gm1 = gam - 1.0f;
  123. cfl = 0.9f;
  124. eps = 0.05f;
  125. double mach = 0.4f;
  126. double alpha = 3.0f * atan(1.0f) / 45.0f;
  127. double p = 1.0f;
  128. double r = 1.0f;
  129. double u = sqrt(gam * p / r) * mach;
  130. double e = p / (r * gm1) + 0.5f * u * u;
  131. qinf[0] = r;
  132. qinf[1] = r * u;
  133. qinf[2] = 0.0f;
  134. qinf[3] = r * e;
  135. for (int n = 0; n < ncell; n++) {
  136. for (int m = 0; m < 4; m++) {
  137. q[4 * n + m] = qinf[m];
  138. res[4 * n + m] = 0.0f;
  139. }
  140. }
  141. // declare sets, pointers, datasets and global constants
  142. op_set nodes = op_decl_set(nnode, "nodes");
  143. op_set edges = op_decl_set(nedge, "edges");
  144. op_set bedges = op_decl_set(nbedge, "bedges");
  145. op_set cells = op_decl_set(ncell, "cells");
  146. op_map pedge = op_decl_map(edges, nodes, 2, edge, "pedge");
  147. free(edge);
  148. op_map pecell = op_decl_map(edges, cells, 2, ecell, "pecell");
  149. free(ecell);
  150. op_map pbedge = op_decl_map(bedges, nodes, 2, bedge, "pbedge");
  151. free(bedge);
  152. op_map pbecell = op_decl_map(bedges, cells, 1, becell, "pbecell");
  153. free(becell);
  154. op_map pcell = op_decl_map(cells, nodes, 4, cell, "pcell");
  155. free(cell);
  156. op_dat p_bound = op_decl_dat(bedges, 1, "int", bound, "p_bound");
  157. free(bound);
  158. op_dat p_x = op_decl_dat(nodes, 2, "double", x, "p_x");
  159. free(x);
  160. op_dat p_q = op_decl_dat(cells, 4, "double", q, "p_q");
  161. free(q);
  162. // op_dat p_qold = op_decl_dat(cells ,4,"double",qold ,"p_qold");
  163. // op_dat p_adt = op_decl_dat(cells ,1,"double",adt ,"p_adt");
  164. // op_dat p_res = op_decl_dat(cells ,4,"double",res ,"p_res");
  165. // p_res, p_adt and p_qold now declared as a temp op_dats during
  166. // the execution of the time-marching loop
  167. op_decl_const(1, "double", &gam);
  168. op_decl_const(1, "double", &gm1);
  169. op_decl_const(1, "double", &cfl);
  170. op_decl_const(1, "double", &eps);
  171. op_decl_const(1, "double", &mach);
  172. op_decl_const(1, "double", &alpha);
  173. op_decl_const(4, "double", qinf);
  174. op_diagnostic_output();
  175. double g_ncell = op_get_size(cells);
  176. // initialise timers for total execution wall time
  177. op_timers(&cpu_t1, &wall_t1);
  178. // main time-marching loop
  179. niter = 1000;
  180. for (int iter = 1; iter <= niter; iter++) {
  181. double *tmp_elem = NULL;
  182. op_dat p_res = op_decl_dat_temp(cells, 4, "double", tmp_elem, "p_res");
  183. op_dat p_adt = op_decl_dat_temp(cells, 1, "double", tmp_elem, "p_adt");
  184. op_dat p_qold = op_decl_dat_temp(cells, 4, "double", qold, "p_qold");
  185. // save old flow solution
  186. op_par_loop(save_soln, "save_soln", cells,
  187. op_arg_dat(p_q, -1, OP_ID, 4, "double", OP_READ),
  188. op_arg_dat(p_qold, -1, OP_ID, 4, "double", OP_WRITE));
  189. // predictor/corrector update loop
  190. for (int k = 0; k < 2; k++) {
  191. // calculate area/timstep
  192. op_par_loop(adt_calc, "adt_calc", cells,
  193. op_arg_dat(p_x, 0, pcell, 2, "double", OP_READ),
  194. op_arg_dat(p_x, 1, pcell, 2, "double", OP_READ),
  195. op_arg_dat(p_x, 2, pcell, 2, "double", OP_READ),
  196. op_arg_dat(p_x, 3, pcell, 2, "double", OP_READ),
  197. op_arg_dat(p_q, -1, OP_ID, 4, "double", OP_READ),
  198. op_arg_dat(p_adt, -1, OP_ID, 1, "double", OP_WRITE));
  199. // calculate flux residual
  200. op_par_loop(res_calc, "res_calc", edges,
  201. op_arg_dat(p_x, 0, pedge, 2, "double", OP_READ),
  202. op_arg_dat(p_x, 1, pedge, 2, "double", OP_READ),
  203. op_arg_dat(p_q, 0, pecell, 4, "double", OP_READ),
  204. op_arg_dat(p_q, 1, pecell, 4, "double", OP_READ),
  205. op_arg_dat(p_adt, 0, pecell, 1, "double", OP_READ),
  206. op_arg_dat(p_adt, 1, pecell, 1, "double", OP_READ),
  207. op_arg_dat(p_res, 0, pecell, 4, "double", OP_INC),
  208. op_arg_dat(p_res, 1, pecell, 4, "double", OP_INC));
  209. op_par_loop(bres_calc, "bres_calc", bedges,
  210. op_arg_dat(p_x, 0, pbedge, 2, "double", OP_READ),
  211. op_arg_dat(p_x, 1, pbedge, 2, "double", OP_READ),
  212. op_arg_dat(p_q, 0, pbecell, 4, "double", OP_READ),
  213. op_arg_dat(p_adt, 0, pbecell, 1, "double", OP_READ),
  214. op_arg_dat(p_res, 0, pbecell, 4, "double", OP_INC),
  215. op_arg_dat(p_bound, -1, OP_ID, 1, "int", OP_READ));
  216. // update flow field
  217. rms = 0.0;
  218. op_par_loop(update, "update", cells,
  219. op_arg_dat(p_qold, -1, OP_ID, 4, "double", OP_READ),
  220. op_arg_dat(p_q, -1, OP_ID, 4, "double", OP_WRITE),
  221. op_arg_dat(p_res, -1, OP_ID, 4, "double", OP_RW),
  222. op_arg_dat(p_adt, -1, OP_ID, 1, "double", OP_READ),
  223. op_arg_gbl(&rms, 1, "double", OP_INC));
  224. }
  225. // print iteration history
  226. rms = sqrt(rms / (double)g_ncell);
  227. if (iter % 100 == 0)
  228. op_printf(" %d %10.5e \n", iter, rms);
  229. if (iter % 1000 == 0 &&
  230. g_ncell == 720000) { // defailt mesh -- for validation testing
  231. // op_printf(" %d %3.16f \n",iter,rms);
  232. double diff = fabs((100.0 * (rms / 0.0001060114637578)) - 100.0);
  233. op_printf("\n\nTest problem with %d cells is within %3.15E %% of the "
  234. "expected solution\n",
  235. 720000, diff);
  236. if (diff < 0.00001) {
  237. op_printf("This test is considered PASSED\n");
  238. } else {
  239. op_printf("This test is considered FAILED\n");
  240. }
  241. }
  242. if (op_free_dat_temp(p_res) < 0)
  243. op_printf("Error: temporary op_dat %s cannot be removed\n", p_res->name);
  244. if (op_free_dat_temp(p_adt) < 0)
  245. op_printf("Error: temporary op_dat %s cannot be removed\n", p_adt->name);
  246. if (op_free_dat_temp(p_qold) < 0)
  247. op_printf("Error: temporary op_dat %s cannot be removed\n", p_qold->name);
  248. }
  249. op_timers(&cpu_t2, &wall_t2);
  250. op_timing_output();
  251. op_printf("Max total runtime = %f\n", wall_t2 - wall_t1);
  252. op_exit();
  253. }