PageRenderTime 46ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/airfoil/airfoil_op.cpp

https://github.com/tiziano88/airfoil_opencl
C++ | 409 lines | 239 code | 90 blank | 80 comment | 37 complexity | ac046ac2c423397fbe0f4be0d2def64f MD5 | raw file
  1. //
  2. // auto-generated by op2.m on 30-May-2011 22:03:11
  3. //
  4. /*
  5. Open source copyright declaration based on BSD open source template:
  6. http://www.opensource.org/licenses/bsd-license.php
  7. * Copyright (c) 2009-2011, Mike Giles
  8. * All rights reserved.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions are met:
  12. * * Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. * * Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. * * The name of Mike Giles may not be used to endorse or promote products
  18. * derived from this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY Mike Giles ''AS IS'' AND ANY
  21. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  22. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  23. * DISCLAIMED. IN NO EVENT SHALL Mike Giles BE LIABLE FOR ANY
  24. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  25. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  26. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  27. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  29. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. */
  31. //
  32. // Nonlinear airfoil lift calculation
  33. //
  34. // Written by Mike Giles, 2010-2011, based on FORTRAN code
  35. // by Devendra Ghate and Mike Giles, 2005
  36. //
  37. //
  38. // standard headers
  39. //
  40. #include <stdlib.h>
  41. #include <stdio.h>
  42. #include <string.h>
  43. #include <math.h>
  44. #include <assert.h>
  45. #include <utility>
  46. #define __NO_STD_VECTOR //use cl::vector
  47. #include <CL/cl.h>
  48. // global constants
  49. //float gam, gm1, cfl, eps, mach, alpha, qinf[4];
  50. struct global_constants {
  51. float gam;
  52. float gm1;
  53. float cfl;
  54. float eps;
  55. float mach;
  56. float alpha;
  57. float qinf[4];
  58. };
  59. struct global_constants g_const;
  60. cl_mem g_const_d;
  61. #include "op_lib.h"
  62. //#define DIAGNOSTIC 1
  63. //
  64. // OP header file
  65. //
  66. //
  67. // op_par_loop declarations
  68. //
  69. void op_par_loop_save_soln(char const *, op_set,
  70. op_arg,
  71. op_arg );
  72. void op_par_loop_adt_calc(char const *, op_set,
  73. op_arg,
  74. op_arg,
  75. op_arg,
  76. op_arg,
  77. op_arg,
  78. op_arg );
  79. void op_par_loop_res_calc(char const *, op_set,
  80. op_arg,
  81. op_arg,
  82. op_arg,
  83. op_arg,
  84. op_arg,
  85. op_arg,
  86. op_arg,
  87. op_arg );
  88. void op_par_loop_bres_calc(char const *, op_set,
  89. op_arg,
  90. op_arg,
  91. op_arg,
  92. op_arg,
  93. op_arg,
  94. op_arg );
  95. void op_par_loop_update(char const *, op_set,
  96. op_arg,
  97. op_arg,
  98. op_arg,
  99. op_arg,
  100. op_arg );
  101. // kernel routines for parallel loops
  102. //
  103. /*
  104. #include "save_soln.h"
  105. #include "adt_calc.h"
  106. #include "res_calc.h"
  107. #include "bres_calc.h"
  108. #include "update.h"
  109. */
  110. // main program
  111. void print_array( float *array, int len, const char *file ) {
  112. FILE *flog;
  113. flog = fopen( file, "w" );
  114. for( int i=0; i<len; ++i ) {
  115. fprintf( flog, "%f\n", array[i] );
  116. }
  117. fclose( flog );
  118. }
  119. void dump_array( op_dat dat, const char *file ) {
  120. op_fetch_data( dat );
  121. print_array( ( float *) dat->data, dat->set->size, file );
  122. }
  123. int main(int argc, char **argv){
  124. int *becell, *ecell, *bound, *bedge, *edge, *cell;
  125. float *x, *q, *qold, *adt, *res;
  126. int nnode,ncell,nedge,nbedge,niter;
  127. float rms;
  128. // read in grid
  129. printf("reading in grid \n");
  130. FILE *fp;
  131. if ( (fp = fopen("new_grid.dat","r")) == NULL) {
  132. printf("can't open file new_grid.dat\n"); exit(-1);
  133. }
  134. if (fscanf(fp,"%d %d %d %d \n",&nnode, &ncell, &nedge, &nbedge) != 4) {
  135. printf("error reading from new_grid.dat\n"); exit(-1);
  136. }
  137. cell = (int *) malloc(4*ncell*sizeof(int));
  138. edge = (int *) malloc(2*nedge*sizeof(int));
  139. ecell = (int *) malloc(2*nedge*sizeof(int));
  140. bedge = (int *) malloc(2*nbedge*sizeof(int));
  141. becell = (int *) malloc( nbedge*sizeof(int));
  142. bound = (int *) malloc( nbedge*sizeof(int));
  143. x = (float *) malloc(2*nnode*sizeof(float));
  144. q = (float *) malloc(4*ncell*sizeof(float));
  145. qold = (float *) malloc(4*ncell*sizeof(float));
  146. res = (float *) malloc(4*ncell*sizeof(float));
  147. adt = (float *) malloc( ncell*sizeof(float));
  148. for (int n=0; n<nnode; n++) {
  149. if (fscanf(fp,"%f %f \n",&x[2*n], &x[2*n+1]) != 2) {
  150. printf("error reading from new_grid.dat\n"); exit(-1);
  151. }
  152. }
  153. for (int n=0; n<ncell; n++) {
  154. if (fscanf(fp,"%d %d %d %d \n",&cell[4*n ], &cell[4*n+1],
  155. &cell[4*n+2], &cell[4*n+3]) != 4) {
  156. printf("error reading from new_grid.dat\n"); exit(-1);
  157. }
  158. }
  159. for (int n=0; n<nedge; n++) {
  160. if (fscanf(fp,"%d %d %d %d \n",&edge[2*n], &edge[2*n+1],
  161. &ecell[2*n],&ecell[2*n+1]) != 4) {
  162. printf("error reading from new_grid.dat\n"); exit(-1);
  163. }
  164. }
  165. for (int n=0; n<nbedge; n++) {
  166. if (fscanf(fp,"%d %d %d %d \n",&bedge[2*n],&bedge[2*n+1],
  167. &becell[n], &bound[n]) != 4) {
  168. printf("error reading from new_grid.dat\n"); exit(-1);
  169. }
  170. }
  171. fclose(fp);
  172. // set constants and initialise flow field and residual
  173. printf("initialising flow field \n");
  174. g_const.gam = 1.4f;
  175. g_const.gm1 = g_const.gam - 1.0f;
  176. g_const.cfl = 0.9f;
  177. g_const.eps = 0.05f;
  178. g_const.mach = 0.4f;
  179. g_const.alpha = 3.0f*atan(1.0f)/45.0f;
  180. float p = 1.0f;
  181. float r = 1.0f;
  182. float u = sqrt(g_const.gam*p/r)*g_const.mach;
  183. float e = p/(r*g_const.gm1) + 0.5f*u*u;
  184. g_const.qinf[0] = r;
  185. g_const.qinf[1] = r*u;
  186. g_const.qinf[2] = 0.0f;
  187. g_const.qinf[3] = r*e;
  188. for (int n=0; n<ncell; n++) {
  189. for (int m=0; m<4; m++) {
  190. q[4*n+m] = g_const.qinf[m];
  191. res[4*n+m] = 0.0f;
  192. }
  193. }
  194. // OP initialisation
  195. printf("OP initialisation\n");
  196. op_init(argc,argv,2);
  197. g_const_d = op_allocate_constant( &g_const, sizeof( struct global_constants ) );
  198. // declare sets, pointers, datasets and global constants
  199. op_set nodes = op_decl_set(nnode, "nodes");
  200. op_set edges = op_decl_set(nedge, "edges");
  201. op_set bedges = op_decl_set(nbedge, "bedges");
  202. op_set cells = op_decl_set(ncell, "cells");
  203. op_map pedge = op_decl_map(edges, nodes,2,edge, "pedge");
  204. op_map pecell = op_decl_map(edges, cells,2,ecell, "pecell");
  205. op_map pbedge = op_decl_map(bedges,nodes,2,bedge, "pbedge");
  206. op_map pbecell = op_decl_map(bedges,cells,1,becell,"pbecell");
  207. op_map pcell = op_decl_map(cells, nodes,4,cell, "pcell");
  208. op_dat p_bound = op_decl_dat(bedges,1,"int" ,bound,"p_bound");
  209. op_dat p_x = op_decl_dat(nodes ,2,"float",x ,"p_x");
  210. op_dat p_q = op_decl_dat(cells ,4,"float",q ,"p_q");
  211. op_dat p_qold = op_decl_dat(cells ,4,"float",qold ,"p_qold");
  212. op_dat p_adt = op_decl_dat(cells ,1,"float",adt ,"p_adt");
  213. op_dat p_res = op_decl_dat(cells ,4,"float",res ,"p_res");
  214. op_decl_const2("gam",1,"float",&g_const.gam );
  215. op_decl_const2("gm1",1,"float",&g_const.gm1 );
  216. op_decl_const2("cfl",1,"float",&g_const.cfl );
  217. op_decl_const2("eps",1,"float",&g_const.eps );
  218. op_decl_const2("mach",1,"float",&g_const.mach );
  219. op_decl_const2("alpha",1,"float",&g_const.alpha);
  220. op_decl_const2("qinf",4,"float",g_const.qinf );
  221. op_diagnostic_output();
  222. // main time-marching loop
  223. niter = 1000;
  224. for(int iter=1; iter<=niter; iter++) {
  225. // save old flow solution
  226. op_par_loop_save_soln("save_soln", cells,
  227. op_arg_dat(p_q, -1,OP_ID, 4,"float",OP_READ ),
  228. op_arg_dat(p_qold,-1,OP_ID, 4,"float",OP_WRITE));
  229. /* if ( iter == 1 ) {
  230. dump_array( p_qold, "p_qold" );
  231. }
  232. */
  233. #ifdef DIAGNOSTIC
  234. if (iter==1) {
  235. dump_array( p_qold, "p_qold" );
  236. }
  237. #endif
  238. //dump_array( p_qold, "p_qold" );
  239. //op_fetch_data( p_qold );
  240. //print_array( ( float *) p_qold->data, 4*p_qold->set->size, "p_qold" );
  241. // print_array( p_q, "p_qold2" );
  242. // print_array( p_qold, "p_qold" );
  243. //assert( p_q->data[0] != 0.0f );
  244. // predictor/corrector update loop
  245. for(int k=0; k<2; k++) {
  246. // calculate area/timstep
  247. op_par_loop_adt_calc("adt_calc",cells,
  248. op_arg_dat(p_x, 0,pcell, 2,"float",OP_READ ),
  249. op_arg_dat(p_x, 1,pcell, 2,"float",OP_READ ),
  250. op_arg_dat(p_x, 2,pcell, 2,"float",OP_READ ),
  251. op_arg_dat(p_x, 3,pcell, 2,"float",OP_READ ),
  252. op_arg_dat(p_q, -1,OP_ID, 4,"float",OP_READ ),
  253. op_arg_dat(p_adt,-1,OP_ID, 1,"float",OP_WRITE));
  254. #ifdef DIAGNOSTIC
  255. if (iter==1 && k==0) {
  256. dump_array( p_adt, "p_adt0" );
  257. }
  258. if (iter==1 && k==1) {
  259. dump_array( p_adt, "p_adt1" );
  260. }
  261. #endif
  262. // calculate flux residual
  263. op_par_loop_res_calc("res_calc",edges,
  264. op_arg_dat(p_x, 0,pedge, 2,"float",OP_READ),
  265. op_arg_dat(p_x, 1,pedge, 2,"float",OP_READ),
  266. op_arg_dat(p_q, 0,pecell,4,"float",OP_READ),
  267. op_arg_dat(p_q, 1,pecell,4,"float",OP_READ),
  268. op_arg_dat(p_adt, 0,pecell,1,"float",OP_READ),
  269. op_arg_dat(p_adt, 1,pecell,1,"float",OP_READ),
  270. op_arg_dat(p_res, 0,pecell,4,"float",OP_INC ),
  271. op_arg_dat(p_res, 1,pecell,4,"float",OP_INC ));
  272. #ifdef DIAGNOSTIC
  273. if (iter==1 && k==0) {
  274. dump_array( p_res, "p_res0" );
  275. }
  276. if (iter==1 && k==1) {
  277. dump_array( p_res, "p_res1" );
  278. }
  279. #endif
  280. op_par_loop_bres_calc("bres_calc",bedges,
  281. op_arg_dat(p_x, 0,pbedge, 2,"float",OP_READ),
  282. op_arg_dat(p_x, 1,pbedge, 2,"float",OP_READ),
  283. op_arg_dat(p_q, 0,pbecell,4,"float",OP_READ),
  284. op_arg_dat(p_adt, 0,pbecell,1,"float",OP_READ),
  285. op_arg_dat(p_res, 0,pbecell,4,"float",OP_INC ),
  286. op_arg_dat(p_bound,-1,OP_ID ,1,"int", OP_READ));
  287. #ifdef DIAGNOSTIC
  288. if (iter==1 && k==0) {
  289. dump_array( p_res, "p_res_a0" );
  290. }
  291. if (iter==1 && k==0) {
  292. dump_array( p_res, "p_res_a1" );
  293. }
  294. #endif
  295. // update flow field
  296. rms = 0.0;
  297. op_par_loop_update("update",cells,
  298. op_arg_dat(p_qold,-1,OP_ID, 4,"float",OP_READ ),
  299. op_arg_dat(p_q, -1,OP_ID, 4,"float",OP_WRITE),
  300. op_arg_dat(p_res, -1,OP_ID, 4,"float",OP_RW ),
  301. op_arg_dat(p_adt, -1,OP_ID, 1,"float",OP_READ ),
  302. op_arg_gbl(&rms,1,"float",OP_INC));
  303. }
  304. #ifdef DIAGNOSTIC
  305. if (iter==1) {
  306. dump_array( p_q, "p_q1" );
  307. }
  308. #endif
  309. // print iteration history
  310. rms = sqrt(rms/(float) ncell);
  311. if (iter%100 == 0)
  312. printf(" %d %10.5e \n",iter,rms);
  313. }
  314. op_timing_output();
  315. #ifdef DIAGNOSTIC
  316. dump_array( p_q, "p_q" );
  317. #endif
  318. }