convergence.jl 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043
  1. # using Revise
  2. using Flower
  3. # PDI
  4. localARGS = ARGS
  5. # @show localARGS
  6. # print("\n Arguments ", localARGS)
  7. # print("\n length(localARGS) ",length(localARGS))
  8. if length(localARGS)>0
  9. yamlfile = localARGS[1]
  10. printstyled(color=:magenta, @sprintf "\n YAML file ")
  11. print(yamlfile)
  12. print("\n")
  13. yamlpath = yamlfile
  14. yamlnamelist = split(yamlfile, "/")
  15. yamlname = yamlnamelist[end]
  16. end
  17. data = YAML.load_file(yamlpath)
  18. # Dictionaries
  19. prop_dict = PropertyDict(data)
  20. #region study parameters
  21. study = PropertyDict(prop_dict.study)
  22. #mesh connvergence
  23. nb_grid_points = study.meshes
  24. n_cases = length(nb_grid_points)
  25. print("\n number of points ", nb_grid_points, "\n")
  26. #timestep convergence
  27. timesteps = study.timesteps
  28. #endregion study parameters
  29. io = PropertyDict(prop_dict.plot)
  30. flower = PropertyDict(prop_dict.flower)
  31. mesh = PropertyDict(flower.mesh)
  32. sim = PropertyDict(flower.simulation)
  33. phys = PropertyDict(flower.physics)
  34. macros = PropertyDict(flower.macros) #to parse code from .yml
  35. # boundaries_dict = PropertyDict(macros.boundaries_list)
  36. study_name = ""
  37. #region change one parameter at a time
  38. # # print("\n changing parameters",Meta.parseall(study.macro))
  39. # change_one_parameter_at_a_time = PropertyDict(study.change_one_parameter_at_a_time)
  40. # # eval(Meta.parseall(study.change_one_parameter_at_a_time.macro))
  41. # # for
  42. # # study_name = change_one_parameter_at_a_time
  43. # for (key, value) in change_one_parameter_at_a_time
  44. # print("\n changing parameter")
  45. # print("\n key ",key)
  46. # print("\n value ",value)
  47. # # eval(value.macro)
  48. # print("\n mu ",phys.mu1,phys.mu2)
  49. # eval(value["macro"])
  50. # print("\n mu ",phys.mu1,phys.mu2)
  51. # end
  52. # # Step 2: Modify multiple parameters
  53. # # Define a dictionary with the parameters you want to change and their new values
  54. # # changes = Dict(
  55. # # "parameter1" => "new_value1",
  56. # # "parameter2" => "new_value2",
  57. # # "parameter3" => "new_value3"
  58. # # # Add more parameters as needed
  59. # # )
  60. # # changes = eval(study.change_one_parameter_at_a_time)
  61. # # Apply the changes to the original YAML data
  62. # # for (key, value) in study.change_one_parameter_at_a_time
  63. # # print("\n changing parameter")
  64. # # print(key)
  65. # # eval(value.macro)
  66. # # end
  67. #endregion change one parameter at a time
  68. # print parameters by evaluating Julia code stored in .yml
  69. eval(Meta.parseall(macros.print_parameters))
  70. #region attempt at precompiling Flower modules to librairies (.so)
  71. # print("\n test juliac")
  72. # # @ccall "simple.so".add_julia(2::Cint, 2::Cint)::Cint
  73. # # test_juliac = @ccall "simple.so".add_julia(2::Cint, 2::Cint)::Cint
  74. # # # Get the current working directory
  75. # # current_directory = pwd()
  76. # # # Print the current working directory
  77. # # println("Current working directory: ", current_directory)
  78. # # test_juliac = @ccall "./simple.so".add_julia(2::Cint, 2::Cint)::Cint
  79. # # test_juliac = @ccall "/local/home/pr277828/flower/juliac/simple.so".add_julia(2::Cint, 2::Cint)::Cint
  80. # test_juliac = @ccall add_julia(2::Cint, 2::Cint)::Cint
  81. # print("\n test ",test_juliac)
  82. # # juliac_status = @ccall "mylib".load_parameters()::Cint
  83. # # juliac_status = @ccall "libmylib.so".load_parameters()::Cint
  84. # print("\n test juliac")
  85. # # pdipath = "libpdi"
  86. # pdipath = "/usr/lib/x86_64-linux-gnu/libpdi.so"
  87. #endregion attempt at precompiling Flower modules to librairies (.so)
  88. if io.pdi>0
  89. @debug "Before PDI init"
  90. yml_file = yamlfile
  91. conf = @ccall "libparaconf".PC_parse_path(yml_file::Cstring)::PC_tree_t
  92. @debug "after conf"
  93. getsubyml = @ccall "libparaconf".PC_get(conf::PC_tree_t,".pdi"::Cstring)::PC_tree_t
  94. @debug "after getsubyml"
  95. local pdi_status = @ccall "libpdi".PDI_init(getsubyml::PC_tree_t)::Cint
  96. @debug "after PDI_init"
  97. # Send meta-data to PDI
  98. mpi_coords_x = 1
  99. mpi_coords_y = 1
  100. mpi_max_coords_x = 1
  101. mpi_max_coords_y = 1
  102. local nx = 32
  103. local ny = 32
  104. nstep = 0
  105. # nx=gp.nx
  106. # ny=gp.ny
  107. #TODO check Clonglong ...
  108. phys_time = 0.0 #Cdouble
  109. # nstep = num.current_iter
  110. local PDI_status = @ccall "libpdi".PDI_multi_expose("init_PDI"::Cstring,
  111. "mpi_coords_x"::Cstring, mpi_coords_x::Ref{Clonglong}, PDI_OUT::Cint,
  112. "mpi_coords_y"::Cstring, mpi_coords_x::Ref{Clonglong}, PDI_OUT::Cint,
  113. "mpi_max_coords_x"::Cstring, mpi_max_coords_x::Ref{Clonglong}, PDI_OUT::Cint,
  114. "mpi_max_coords_y"::Cstring, mpi_max_coords_y::Ref{Clonglong}, PDI_OUT::Cint,
  115. "nx"::Cstring, nx::Ref{Clonglong}, PDI_OUT::Cint,
  116. "ny"::Cstring, ny::Ref{Clonglong}, PDI_OUT::Cint,
  117. "nb_transported_scalars"::Cstring, phys.nb_transported_scalars::Ref{Clonglong}, PDI_OUT::Cint,
  118. "nb_levelsets"::Cstring, phys.nb_levelsets::Ref{Clonglong}, PDI_OUT::Cint,
  119. "nstep"::Cstring, nstep::Ref{Clonglong}, PDI_OUT::Cint,
  120. # "timestep"::Cstring, nstep::Ref{Clonglong}, PDI_OUT::Cint,
  121. # "nb_Navier_slip_BC"::Cstring, num.nNavier::Ref{Clonglong}, PDI_OUT::Cint,
  122. C_NULL::Ptr{Cvoid})::Cint
  123. print("\n PDI INIT status ",PDI_status)
  124. @debug "after PDI_multi_expose"
  125. @debug "After full PDI init"
  126. # nx_pdi = [nx]
  127. # nstep_pdi = [nstep]
  128. # local PDI_status = @ccall "libpdi".PDI_multi_expose("test_pycall_write_arr"::Cstring,
  129. # "nx_arr"::Cstring, nx_pdi::Ref{Clonglong}, PDI_OUT::Cint,
  130. # "nstep_arr"::Cstring, nstep_pdi::Ref{Clonglong}, PDI_OUT::Cint,
  131. # C_NULL::Ptr{Cvoid})::Cint
  132. # local PDI_status = @ccall "libpdi".PDI_multi_expose("test_pycall_write"::Cstring,
  133. # "nx"::Cstring, nx::Ref{Clonglong}, PDI_OUT::Cint,
  134. # "nstep"::Cstring, nstep::Ref{Clonglong}, PDI_OUT::Cint,
  135. # C_NULL::Ptr{Cvoid})::Cint
  136. # local PDI_status = @ccall "libpdi".PDI_multi_expose("test_pycall_write"::Cstring,
  137. # "nx"::Cstring, nx::Ref{Clonglong}, PDI_INOUT::Cint,
  138. # "nstep"::Cstring, nstep::Ref{Clonglong}, PDI_INOUT::Cint,
  139. # C_NULL::Ptr{Cvoid})::Cint
  140. # local PDI_status = @ccall "libpdi".PDI_multi_expose("write_pycall"::Cstring,
  141. # "nx"::Cstring, nx::Ref{Clonglong}, PDI_OUT::Cint,
  142. # "nstep"::Cstring, nstep::Ref{Clonglong}, PDI_OUT::Cint,
  143. # C_NULL::Ptr{Cvoid})::Cint
  144. end #if io.pdi>0
  145. # arrays to store errors
  146. error_list_l1 = zeros(n_cases)
  147. error_list_l2 = zeros(n_cases)
  148. error_list_linfty = zeros(n_cases)
  149. error_list_l1_mixed = zeros(n_cases)
  150. error_list_l2_mixed = zeros(n_cases)
  151. error_list_linfty_mixed = zeros(n_cases)
  152. error_list_l1_full = zeros(n_cases)
  153. error_list_l2_full = zeros(n_cases)
  154. error_list_linfty_full = zeros(n_cases)
  155. cell_volume_list = zeros(n_cases)
  156. base_directory = pwd()
  157. # print("\n base directory ",base_directory)
  158. #region timestep convergence
  159. for timestep in timesteps
  160. print("\n Timestep ",timestep)
  161. timestep_to_string = @sprintf "timestep_%.4e" timestep
  162. # print("\n timestep_to_string ",timestep_to_string)
  163. timestep_to_string = replace(timestep_to_string, "." => "_")
  164. # print("\n timestep_to_string ",timestep_to_string)
  165. mkpath(timestep_to_string)
  166. cd(timestep_to_string)
  167. # print("\n pwd() ",pwd())
  168. #region mesh convergence
  169. for (i,study_nb_grid_points) in enumerate(nb_grid_points)
  170. mesh_to_string = @sprintf "mesh_%.5i" study_nb_grid_points
  171. mesh_ratio = Int((mesh.ymax - mesh.ymin)/ (mesh.xmax - mesh.xmin) )
  172. print("\n mesh ratio ", mesh_ratio )
  173. study_nb_grid_points_x = study_nb_grid_points
  174. study_nb_grid_points_y = study_nb_grid_points * mesh_ratio
  175. print("\n nx ",study_nb_grid_points_x, " ny ",study_nb_grid_points_y)
  176. mkpath(mesh_to_string)
  177. cd(mesh_to_string)
  178. #delete output.txt:
  179. # local PDI_status = @ccall "libpdi".PDI_multi_expose("macro_delete_file"::Cstring,C_NULL::Ptr{Cvoid})::Cint
  180. #bug
  181. # if study_name !=""
  182. # # mkpath(study.change_one_parameter_at_a_time.name)
  183. # print("\nstudy ",study.change_one_parameter_at_a_time.name)
  184. # end
  185. # init regular grid
  186. scalar_mesh_x = collect(LinRange(mesh.xmin, mesh.xmax, study_nb_grid_points_x + 1))
  187. scalar_mesh_y = collect(LinRange(mesh.ymin, mesh.ymax, study_nb_grid_points_y + 1))
  188. # # print("\n test juliac")
  189. # # juliac_status = @ccall "mylib".load_parameters()::Cint
  190. # juliac_status = @ccall "libmylib".load_parameters()::Cint
  191. # # print("\n test juliac")
  192. # print("\n mu1 mu2 ",phys.mu1," ",typeof(phys.mu1)," ",phys.mu2," ",typeof(phys.mu2))
  193. @debug "Before Numerical"
  194. #region test fill struct
  195. #aliases from yml to Flower.jl
  196. aliases = Dict(
  197. :x => :scalar_mesh_x,
  198. :y => :scalar_mesh_y,
  199. :xcoord => :intfc_x,
  200. :ycoord => :intfc_y,
  201. :R => :radius,
  202. :max_iterations => :max_iter,
  203. :save_every => :max_iter,
  204. :ϵ => :epsilon,
  205. :ϵwall => :epsilon_wall,
  206. :nLS => :nb_levelsets,
  207. :θd => :temperature0,
  208. :β => :beta,
  209. :σ => :sigma,
  210. :δreinit => :delta_reinit,
  211. :n_ext_cl => :n_ext,
  212. :timestep_0 => :timestep,
  213. :timestep_n => :timestep,
  214. :io_pdi => :pdi,
  215. # :convection => :convection_mode, #debug
  216. )
  217. # fields defined locally, not in yml
  218. extra = Dict(
  219. :scalar_mesh_x => scalar_mesh_x,
  220. :scalar_mesh_y => scalar_mesh_y,
  221. # :electrolysis_reaction => Symbol(phys.electrolysis_reaction),
  222. # :intfc_x => intfc_x,
  223. # :intfc_y => intfc_y,
  224. )
  225. default = Numerical{Float64,Int}(
  226. x = scalar_mesh_x,
  227. y = scalar_mesh_y,
  228. timestep_n = timestep,
  229. timestep_0 = timestep,
  230. electrolysis_reaction_symb = Symbol(phys.electrolysis_reaction),
  231. bulk_velocity_symb = Symbol(phys.bulk_velocity),
  232. ) # construct default parametric instance with x otherwise L0 and ... not defined in the same way
  233. # global num_new = safefill_with_aliases(Numerical{Float64, Int}, sim, phys, io,aliases)
  234. # global num_new = safefill_with_aliases_and_extra(Numerical{Float64,Int},
  235. # sim, phys, io,
  236. # aliases,
  237. # extra)
  238. print("\n ns_advection ",(sim.ns_advection ==1))
  239. global num_new = safefill_with_aliases_and_extra_already_init(Numerical{Float64,Int},default,
  240. sim, phys, io,
  241. aliases,
  242. extra)
  243. #endregion test fill struct
  244. # # global num = Numerical(
  245. # # CFL = sim.CFL,
  246. # # Re = Re, #in Flower, not real Re
  247. # # end_time=phys.end_time,
  248. # # x = scalar_mesh_x,
  249. # # y = scalar_mesh_y,
  250. # # xcoord = phys.intfc_x,
  251. # # ycoord = phys.intfc_y,
  252. # # case = sim.case,
  253. # # R = phys.radius,
  254. # # max_iterations = sim.max_iter,
  255. # # save_every = sim.max_iter,
  256. # # ϵ = sim.epsilon,
  257. # # ϵwall = sim.epsilon_wall,
  258. # # epsilon_mode = sim.epsilon_mode,
  259. # # nLS = phys.nb_levelsets,
  260. # # nb_transported_scalars=phys.nb_transported_scalars,
  261. # # concentration0=phys.concentration0,
  262. # # epsilon_concentration=phys.epsilon_concentration,
  263. # # diffusion_coeff=phys.diffusion_coeff,
  264. # # temperature0=phys.temperature0,
  265. # # i0=phys.i0,
  266. # # phi_ele0=phys.phi_ele0,
  267. # # phi_ele1=phys.phi_ele1,
  268. # # alpha_c=phys.alpha_c,
  269. # # alpha_a=phys.alpha_a,
  270. # # Ru=phys.Ru,
  271. # # Faraday=phys.Faraday,
  272. # # MWH2=phys.MWH2,
  273. # # θd=phys.temperature0,
  274. # # eps=sim.eps,
  275. # # mu1=phys.mu1,
  276. # # mu2=phys.mu2,
  277. # # rho1=phys.rho1,
  278. # # rho2=phys.rho2,
  279. # # # u_inf = 0.0,
  280. # # # v_inf = 0.0,
  281. # # pres0=phys.pres0,
  282. # # g = phys.g,
  283. # # β = phys.beta,
  284. # # σ = phys.sigma,
  285. # # sigma = phys.sigma,
  286. # # reinit_every = sim.reinit_every,
  287. # # nb_reinit = sim.nb_reinit,
  288. # # δreinit = sim.delta_reinit,
  289. # # n_ext_cl = sim.n_ext,
  290. # # NB = sim.NB,
  291. # # # plot_xscale = io.scale_x,
  292. # # timestep_n = timestep, #timestep convergence #sim.timestep_0,
  293. # # timestep_0 = timestep, #timestep convergence #sim.timestep_0,
  294. # # concentration_check_factor = sim.concentration_check_factor,
  295. # # radial_vel_factor = phys.radial_vel_factor,
  296. # # debug = sim.debug,
  297. # # v_inlet = phys.v_inlet,
  298. # # prediction = sim.prediction,
  299. # # null_space = sim.null_space,
  300. # # io_pdi = io.pdi,
  301. # # bulk_conductivity = sim.bulk_conductivity,
  302. # # electrical_potential = sim.electrical_potential,
  303. # # contact_angle = sim.contact_angle,
  304. # # convection_Cdivu = sim.convection_Cdivu,
  305. # # convection_mode = sim.convection_mode,
  306. # # advection_LS_mode = sim.advection_LS_mode,
  307. # # scalar_bc = sim.scalar_bc,
  308. # # scalar_scheme = sim.scalar_scheme,
  309. # # solver = sim.solver,
  310. # # mass_transfer_rate = sim.mass_transfer_rate,
  311. # # average_liquid_solid = sim.average_liquid_solid,
  312. # # index_phase_change = sim.index_phase_change,
  313. # # index_electrolyte = sim.index_electrolyte,
  314. # # extend_field = sim.extend_field,
  315. # # average_velocity = sim.average_velocity,
  316. # # laplacian = sim.laplacian,
  317. # # electrical_potential_max_iter = sim.electrical_potential_max_iter,
  318. # # electrical_potential_relative_residual = sim.electrical_potential_relative_residual,
  319. # # electrical_potential_residual = sim.electrical_potential_residual,
  320. # # electrical_potential_nonlinear_solver = sim.electrical_potential_nonlinear_solver,
  321. # # electrolysis_reaction = phys.electrolysis_reaction,
  322. # # pressure_velocity_coupling = sim.pressure_velocity_coupling,
  323. # # pressure_velocity_solver = sim.pressure_velocity_solver,
  324. # # solve_solid = sim.solve_solid,
  325. # # phase_change_method = sim.phase_change_method,
  326. # # one_fluid_model = sim.one_fluid_model,
  327. # # smooth_VOF = sim.smooth_VOF,
  328. # # surface_tension = sim.surface_tension,
  329. # # non_dimensionalize=sim.non_dimensionalize,
  330. # # levelset_reinitialize=sim.levelset_reinitialize,
  331. # # mu_one_fluid_average = sim.mu_one_fluid_average,
  332. # # one_fluid_normal = sim.one_fluid_normal,
  333. # # marching_squares_epsilon = sim.marching_squares_epsilon,
  334. # # marching_squares_max_iter = sim.marching_squares_max_iter,
  335. # # convection = sim.convection_mode,
  336. # # nucleation_time = phys.nucleation_time,
  337. # # solve_potential = sim.solve_potential,
  338. # # solve_species = sim.solve_species,
  339. # # kill_dead_cells = sim.kill_dead_cells,
  340. # # epsilon_volume_fraction_phase_change = sim.epsilon_volume_fraction_phase_change,
  341. # # solve_Navier_Stokes_liquid_phase = sim.solve_Navier_Stokes_liquid_phase,
  342. # # mass_transfer_rate_imposed_value = sim.mass_transfer_rate_imposed_value,
  343. # # verbosity = sim.verbosity,
  344. # # mode_2d = sim.mode_2d,
  345. # # mu_cin1 = phys.mu_cin1,
  346. # # mu_cin2 = phys.mu_cin2,
  347. # # # u_inf = phys.u_inf,
  348. # # )
  349. # if (num == num_new)
  350. # print("\n New init of num OK")
  351. # else
  352. # @error("\n init num")
  353. # end
  354. # function diff_struct(a, b)
  355. # @assert typeof(a) == typeof(b) "Types differ"
  356. # for name in fieldnames(typeof(a))
  357. # va = getfield(a, name)
  358. # vb = getfield(b, name)
  359. # if va != vb
  360. # println("Field $name differs:")
  361. # println(" a.$name = $va")
  362. # println(" b.$name = $vb")
  363. # end
  364. # end
  365. # end
  366. # diff_struct(num, num_new)
  367. # print("\n num x ",num.x)
  368. # print("\n num x ",num_new.x)
  369. # print("\n num y ",num.y)
  370. # print("\n num y ",num_new.y)
  371. global num = num_new
  372. if num.verbosity >0
  373. print("\n Parameters num ",num)
  374. end
  375. Broadcast.broadcastable(num::Numerical) = Ref(num) #do not broadcast num
  376. @debug "After Numerical"
  377. # num.electrolysis_reaction = Symbol(num.electrolysis_reaction)
  378. global gp, gu, gv = init_meshes(num)
  379. #gp, gu, gv = init_meshes(num) does not work for eval(Meta.parseall(macros.boundaries))
  380. global op, phS, phL = init_fields(num, gp, gu, gv)
  381. gp.LS[1].u .= 1.0 #deactivate interface
  382. # Init fields
  383. eval(Meta.parseall(macros.init_fields))
  384. # Define boundary conditions
  385. eval(Meta.parseall(macros.boundaries))
  386. if num.io_pdi>0
  387. # Send meta-data to PDI
  388. nx=gp.nx
  389. ny=gp.ny
  390. try
  391. local PDI_status = @ccall "libpdi".PDI_multi_expose("init_PDI"::Cstring,
  392. "mpi_coords_x"::Cstring, mpi_coords_x::Ref{Clonglong}, PDI_OUT::Cint,
  393. "mpi_coords_y"::Cstring, mpi_coords_x::Ref{Clonglong}, PDI_OUT::Cint,
  394. "mpi_max_coords_x"::Cstring, mpi_max_coords_x::Ref{Clonglong}, PDI_OUT::Cint,
  395. "mpi_max_coords_y"::Cstring, mpi_max_coords_y::Ref{Clonglong}, PDI_OUT::Cint,
  396. "nx"::Cstring, nx::Ref{Clonglong}, PDI_OUT::Cint,
  397. "ny"::Cstring, ny::Ref{Clonglong}, PDI_OUT::Cint,
  398. "nb_transported_scalars"::Cstring, phys.nb_transported_scalars::Ref{Clonglong}, PDI_OUT::Cint,
  399. "nb_levelsets"::Cstring, phys.nb_levelsets::Ref{Clonglong}, PDI_OUT::Cint,
  400. "nstep"::Cstring, num.current_iter::Ref{Clonglong}, PDI_OUT::Cint,
  401. "nb_Navier_slip_BC"::Cstring, num.nNavier::Ref{Clonglong}, PDI_OUT::Cint,
  402. "timestep"::Cstring, timestep::Ref{Cdouble}, PDI_OUT::Cint,
  403. C_NULL::Ptr{Cvoid})::Cint
  404. catch error
  405. print("\n Bug init_PDI \n")
  406. print("\n PDI_status ",PDI_status, "\n")
  407. print("\n error",error)
  408. end
  409. @debug "after PDI_multi_expose"
  410. @debug "After full PDI init"
  411. end #if num.io_pdi>0
  412. # Define interfaces (for bubbles, drops...)
  413. eval(Meta.parseall(macros.interface))
  414. # if sim.activate_interface == 1
  415. # gp.LS[1].u .= sqrt.((gp.x .- phys.intfc_x).^2 + (gp.y .- phys.intfc_y).^2) - phys.radius * ones(gp)
  416. # #modify velocity field near interface
  417. # su = sqrt.((gv.x .- phys.intfc_x).^2 .+ (gv.y .- phys.intfc_y).^2)
  418. # R1 = phys.radius + 3.0*num.Δ
  419. # bl = 4.0
  420. # for II in gv.ind.all_indices
  421. # if su[II] <= R1
  422. # phL.v[II] = 0.0
  423. # # elseif su[II] > R1
  424. # # uL[II] = tanh(bl*(su[II]-R1))
  425. # end
  426. # end
  427. # elseif sim.activate_interface == -1
  428. # gp.LS[1].u .= sqrt.((gp.x .- phys.intfc_x).^2 + (gp.y .- phys.intfc_y).^2) - phys.radius * ones(gp)
  429. # gp.LS[1].u .*= -1.0
  430. # else
  431. # gp.LS[1].u .= 1.0
  432. # end
  433. # test_LS(gp)
  434. # Create segments from interface
  435. # x,y,field,connectivities,num_vtx = convert_interfacial_D_to_segments(num,gp,phL.T,1)
  436. # print("\n number of interface points ", num_vtx)
  437. # # print("\n x",x)
  438. # # print("\n x",y)
  439. # # print("\n x",field)
  440. # print("\n x",connectivities)
  441. # print("\n x",num_vtx)
  442. # printstyled(color=:green, @sprintf "\n Initialisation0 \n")
  443. # print_electrolysis_statistics(num,gp,phL)
  444. if sim.time_scheme == "FE"
  445. time_scheme = FE
  446. else
  447. time_scheme = CN
  448. end
  449. if num.io_pdi>0
  450. try
  451. # printstyled(color=:red, @sprintf "\n before pdi \n")
  452. # printstyled(color=:red, @sprintf "\n PDI test \n" )
  453. # if num.solve_electrical_potential>0
  454. # phi_array=phL.phi_ele #do not transpose since python row major
  455. # compute_grad_phi_ele!(num, grid, grid_u, grid_v, phL, phS, op.opC_pL, op.opC_pS) #TODO current
  456. # Eus,Evs = interpolate_grid_liquid(grid,grid_u,grid_v,phL.Eu, phL.Ev)
  457. # us,vs = interpolate_grid_liquid(grid,grid_u,grid_v,phL.u,phL.v)
  458. # print("\n before write \n ")
  459. #TODO "levelset_p_tot"::Cstring, gp.LS[2].u::Ptr{Cdouble}, PDI_OUT::Cint,
  460. iLSpdi = 1 # all LS iLS = 1 # or all LS ?
  461. # Exposing data to PDI for IO
  462. # if writing "D" array (bulk, interface, border), add "_1D" to the name
  463. # printstyled(color=:magenta, @sprintf "\n PDI write_data_start_linftyp %.5i \n" num.current_iter)
  464. #print("\n size LS wall ", size( gp.LS[2].u))
  465. LStable = zeros(gp)
  466. if phys.nb_levelsets>1
  467. LStable = gp.LS[2].u
  468. end
  469. # Compute electrical current, interpolate velocity on scalar grid
  470. # compute_grad_phi_ele!(num, gp, gu, gv, phL, phS, op.opC_pL, op.opC_pS) #TODO current
  471. # compute_grad_phi_ele!(num, grid, grid_u, grid_v, phL, phS, op.opC_pL, op.opC_pS, elec_cond,tmp_vec_u,tmp_vec_v,tmp_vec_p,tmp_vec_p0,tmp_vec_p1) #TODO current
  472. us=zeros(gp) #TODO allocate only once
  473. vs=zeros(gp)
  474. # #store in us, vs instead of Eus, Evs
  475. # interpolate_grid_liquid!(gp,gu,gv,phL.Eu, phL.Ev,us,vs)
  476. # #TODO i_current_mag need cond
  477. # @ccall "libpdi".PDI_multi_expose("write_data_elec"::Cstring,
  478. # "i_current_x"::Cstring, us::Ptr{Cdouble}, PDI_OUT::Cint,
  479. # "i_current_y"::Cstring, vs::Ptr{Cdouble}, PDI_OUT::Cint,
  480. # "i_current_mag"::Cstring, phL.i_current_mag::Ptr{Cdouble}, PDI_OUT::Cint,
  481. # "phi_ele_1D"::Cstring, phL.phi_eleD::Ptr{Cdouble}, PDI_OUT::Cint,
  482. # C_NULL::Ptr{Cvoid})::Cint
  483. interpolate_grid_liquid!(gp,gu,gv,phL.u,phL.v,us,vs)
  484. current_radius = phys.radius
  485. PDI_status = @ccall "libpdi".PDI_multi_expose("write_initialization"::Cstring,
  486. "nstep"::Cstring, num.current_iter::Ref{Clonglong}, PDI_OUT::Cint,
  487. "time"::Cstring, phys_time::Ref{Cdouble}, PDI_OUT::Cint,
  488. "u_1D"::Cstring, phL.uD::Ptr{Cdouble}, PDI_OUT::Cint,
  489. "v_1D"::Cstring, phL.vD::Ptr{Cdouble}, PDI_OUT::Cint,
  490. "p_1D"::Cstring, phL.pD::Ptr{Cdouble}, PDI_OUT::Cint,
  491. "levelset_p"::Cstring, gp.LS[iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  492. "levelset_u"::Cstring, gu.LS[iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  493. "levelset_v"::Cstring, gv.LS[iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  494. "levelset_p_wall"::Cstring, LStable::Ptr{Cdouble}, PDI_OUT::Cint,
  495. # "trans_scal_1DT"::Cstring, phL.trans_scalD'::Ptr{Cdouble}, PDI_OUT::Cint,
  496. "phi_ele_1D"::Cstring, phL.phi_eleD::Ptr{Cdouble}, PDI_OUT::Cint,
  497. # "i_current_x"::Cstring, Eus::Ptr{Cdouble}, PDI_OUT::Cint,
  498. # "i_current_y"::Cstring, Evs::Ptr{Cdouble}, PDI_OUT::Cint,
  499. "velocity_x"::Cstring, us::Ptr{Cdouble}, PDI_OUT::Cint,
  500. "velocity_y"::Cstring, vs::Ptr{Cdouble}, PDI_OUT::Cint,
  501. "radius"::Cstring, current_radius::Ref{Cdouble}, PDI_OUT::Cint,
  502. # "intfc_vtx_num"::Cstring, intfc_vtx_num::Ref{Clonglong}, PDI_OUT::Cint,
  503. # "intfc_seg_num"::Cstring, intfc_seg_num::Ref{Clonglong}, PDI_OUT::Cint,
  504. # "intfc_vtx_x"::Cstring, intfc_vtx_x::Ptr{Cdouble}, PDI_OUT::Cint,
  505. # "intfc_vtx_y"::Cstring, intfc_vtx_y::Ptr{Cdouble}, PDI_OUT::Cint,
  506. # "intfc_vtx_field"::Cstring, intfc_vtx_field::Ptr{Cdouble}, PDI_OUT::Cint,
  507. # "intfc_vtx_connectivities"::Cstring, intfc_vtx_connectivities::Ptr{Clonglong}, PDI_OUT::Cint,
  508. C_NULL::Ptr{Cvoid})::Cint
  509. catch error
  510. printstyled(color=:red, @sprintf "\n PDI error \n")
  511. print(error)
  512. printstyled(color=:red, @sprintf "\n PDI error \n")
  513. end
  514. end #if io_pdi
  515. velocity_y_bubble = 0.0 .* gp.LS[end].geoS.dcap[:,:,5]
  516. volume_fraction = gp.LS[end].geoS.dcap[:,:,5]
  517. center_of_mass_x = 0.0
  518. center_of_mass_y = 0.0
  519. circularity = 1.0
  520. rise_velocity_y = 0.0
  521. iLSpdi = 1
  522. velocity_y = velocity_y_bubble
  523. area_liq = 0.0
  524. area_gaz = 0.0
  525. # PDI_status = @ccall "libpdi".PDI_multi_expose("write_postprocessing_rising_bubble"::Cstring,
  526. # "nstep"::Cstring, num.current_iter ::Ref{Clonglong}, PDI_OUT::Cint,
  527. # "center_of_mass_x"::Cstring, center_of_mass_x::Ref{Cdouble}, PDI_OUT::Cint,
  528. # "center_of_mass_y"::Cstring, center_of_mass_y::Ref{Cdouble}, PDI_OUT::Cint,
  529. # "rise_velocity_y"::Cstring, rise_velocity_y::Ref{Cdouble}, PDI_OUT::Cint,
  530. # "circularity"::Cstring, circularity::Ref{Cdouble}, PDI_OUT::Cint,
  531. # "velocity_y_bubble"::Cstring, velocity_y_bubble::Ptr{Cdouble}, PDI_OUT::Cint,
  532. # "area_gaz"::Cstring, area_gaz::Ref{Cdouble}, PDI_OUT::Cint,
  533. # "area_liq"::Cstring, area_liq::Ref{Cdouble}, PDI_OUT::Cint,
  534. # C_NULL::Ptr{Cvoid})::Cint
  535. # PDI_status = @ccall "libpdi".PDI_multi_expose("post_processing_rising_bubble_new"::Cstring,
  536. # "nstep"::Cstring, num.current_iter ::Ref{Clonglong}, PDI_OUT::Cint,
  537. # "velocity_y"::Cstring, velocity_y_bubble::Ptr{Cdouble}, PDI_OUT::Cint,
  538. # "volume_fraction"::Cstring, volume_fraction::Ptr{Cdouble}, PDI_OUT::Cint,
  539. # # "volume_liq_cell"::Cstring, grid_p.LS[end].geoL.dcap[:,:,5]::Ptr{Cdouble}, PDI_OUT::Cint, #geoS for bubble phase
  540. # # "volume_cell"::Cstring, grid_p.LS[end].geoS.dcap[:,:,5]::Ptr{Cdouble}, PDI_OUT::Cint, #geoS for bubble phase
  541. # "mesh_p_x"::Cstring, gp.x::Ptr{Cdouble}, PDI_OUT::Cint,
  542. # "mesh_p_y"::Cstring, gp.y::Ptr{Cdouble}, PDI_OUT::Cint,
  543. # "dcap_1"::Cstring, gp.LS[iLSpdi].geoS.dcap[:,:,1]::Ptr{Cdouble}, PDI_OUT::Cint, #geoS for bubble phase
  544. # "dcap_2"::Cstring, gp.LS[iLSpdi].geoS.dcap[:,:,2]::Ptr{Cdouble}, PDI_OUT::Cint, #geoS for bubble phase
  545. # "dcap_3"::Cstring, gp.LS[iLSpdi].geoS.dcap[:,:,3]::Ptr{Cdouble}, PDI_OUT::Cint, #geoS for bubble phase
  546. # "dcap_4"::Cstring, gp.LS[iLSpdi].geoS.dcap[:,:,4]::Ptr{Cdouble}, PDI_OUT::Cint, #geoS for bubble phase
  547. # C_NULL::Ptr{Cvoid})::Cint
  548. PDI_status = @ccall "libpdi".PDI_multi_expose("post_processing_rising_bubble"::Cstring,
  549. "nstep"::Cstring, num.current_iter ::Ref{Clonglong}, PDI_OUT::Cint,
  550. "velocity_y"::Cstring, velocity_y::Ptr{Cdouble}, PDI_OUT::Cint,
  551. "volume_fraction"::Cstring, volume_fraction::Ptr{Cdouble}, PDI_OUT::Cint,
  552. "volume_liq_cell"::Cstring, gp.LS[iLSpdi].geoL.dcap[:,:,5]::Ptr{Cdouble}, PDI_OUT::Cint, #geoS for bubble phase
  553. "volume_cell"::Cstring, gp.LS[iLSpdi].geoS.dcap[:,:,5]::Ptr{Cdouble}, PDI_OUT::Cint, #geoS for bubble phase
  554. "mesh_p_x"::Cstring, gp.x::Ptr{Cdouble}, PDI_OUT::Cint,
  555. "mesh_p_y"::Cstring, gp.y::Ptr{Cdouble}, PDI_OUT::Cint,
  556. "dcap_1"::Cstring, gp.LS[iLSpdi].geoS.dcap[:,:,1]::Ptr{Cdouble}, PDI_OUT::Cint, #geoS for bubble phase
  557. "dcap_2"::Cstring, gp.LS[iLSpdi].geoS.dcap[:,:,2]::Ptr{Cdouble}, PDI_OUT::Cint, #geoS for bubble phase
  558. "dcap_3"::Cstring, gp.LS[iLSpdi].geoS.dcap[:,:,3]::Ptr{Cdouble}, PDI_OUT::Cint, #geoS for bubble phase
  559. "dcap_4"::Cstring, gp.LS[iLSpdi].geoS.dcap[:,:,4]::Ptr{Cdouble}, PDI_OUT::Cint, #geoS for bubble phase
  560. C_NULL::Ptr{Cvoid})::Cint
  561. # if num.io_pdi>0
  562. # iLSpdi = 1 # TODO all grid.LS
  563. # PDI_status = @ccall "libpdi".PDI_multi_expose("write_capacities"::Cstring,
  564. # "dcap"::Cstring, permutedims(gp.LS[iLSpdi].geoL.dcap, (3, 1, 2))::Ptr{Cdouble}, PDI_OUT::Cint,
  565. # C_NULL::Ptr{Cvoid})::Cint
  566. # # try
  567. # # iLSpdi = 1 # TODO all grid.LS
  568. # # PDI_status = @ccall "libpdi".PDI_multi_expose("write_capacities"::Cstring,
  569. # # "dcap"::Cstring, gp.LS[iLSpdi].geoL.dcap'::Ptr{Cdouble}, PDI_OUT::Cint,
  570. # # C_NULL::Ptr{Cvoid})::Cint
  571. # # catch error
  572. # # printstyled(color=:red, @sprintf "\n PDI error \n")
  573. # # print(error)
  574. # # printstyled(color=:red, @sprintf "\n PDI error \n")
  575. # # end
  576. # end #if io_pdi
  577. # printstyled(color=:red, @sprintf "\n after pdi \n")
  578. # printstyled(color=:red, @sprintf "\n before run_forward \n")
  579. # print("\n BC_uL ",BC_uL)
  580. run_forward!(
  581. num, gp, gu, gv, op, phS, phL;
  582. periodic_x = (sim.periodic_x == 1),
  583. periodic_y = (sim.periodic_y == 1),
  584. BC_uL = BC_uL,
  585. BC_uS=BC_uS,
  586. BC_vL = BC_vL,
  587. BC_vS=BC_vS,
  588. BC_pL = BC_pL,
  589. BC_pS=BC_pS,
  590. BC_u = BC_u,
  591. BC_int = BC_int,
  592. BC_trans_scal=BC_trans_scal,
  593. BC_phi_ele = BC_phi_ele,
  594. auto_reinit = sim.auto_reinit,
  595. time_scheme = time_scheme,
  596. electrolysis = true,
  597. navier_stokes = true,
  598. ns_advection = (sim.ns_advection ==1),
  599. ns_liquid_phase = (sim.solve_Navier_Stokes_liquid_phase == 1),
  600. verbose = true,
  601. show_every = sim.show_every,
  602. electrolysis_convection = (sim.electrolysis_convection ==1),
  603. electrolysis_liquid_phase = true,
  604. electrolysis_phase_change_case = sim.electrolysis_phase_change_case,
  605. imposed_velocity = sim.imposed_velocity,
  606. adapt_timestep_mode = sim.adapt_timestep_mode,#1,
  607. non_dimensionalize=sim.non_dimensionalize,
  608. mode_2d = sim.mode_2d,
  609. breakup = sim.breakup,
  610. )
  611. @debug "After run"
  612. # #cut small cells for error
  613. # number_small_cells_for_error = 0
  614. # cutoff_for_error_volume = 1e-12 #TODO
  615. # for II in gp.ind.all_indices
  616. # if gp.LS[1].geoL.cap[II,5] < cutoff_for_error_volume
  617. # number_small_cells_for_error += 1
  618. # Tana[II] = 0.0
  619. # T[II] = 0.0
  620. # end
  621. # end
  622. # printstyled(color=:green, @sprintf "\n number_small_cells_for_error %.3i \n" number_small_cells_for_error)
  623. if study.compute_errors != "None" #"Poiseuille"
  624. LIQUID = gp.ind.all_indices[gp.LS[1].geoL.cap[:,:,5] .> (1-1e-16)]
  625. MIXED = gp.ind.all_indices[gp.LS[1].geoL.cap[:,:,5] .<= (1-1e-16) .&& gp.LS[1].geoL.cap[:,:,5] .> 1e-16]
  626. if study.compute_errors == "Poiseuille"
  627. norm_all = relative_errors(phL.v, vPoiseuille, vcat(LIQUID, MIXED), gp.LS[1].geoL.cap[:,:,5], num.Δ)
  628. norm_mixed = relative_errors(phL.v, vPoiseuille, MIXED, gp.LS[1].geoL.cap[:,:,5], num.Δ)
  629. norm_full = relative_errors(phL.v, vPoiseuille, LIQUID, gp.LS[1].geoL.cap[:,:,5], num.Δ)
  630. elseif study.compute_errors == "diffusion_full_cell"
  631. # Parameters
  632. L = mesh.xmax-mesh.xmin
  633. D = num.diffusion_coeff[2] #3.2e-9 # diffusivity
  634. analytical_nx = 1000 #accumulating error if n too small so if N big, accumulating too much if nx=100 and N=1000
  635. diffusion_time_scale = L^2 / D
  636. println("diffusion time scale", diffusion_time_scale)
  637. # ele_current_i = minimum(i_current_mag from gradient)
  638. # print("i mag min ", ele_current_i)
  639. ele_current_i = -1.59e4
  640. F1 = ele_current_i / (2 * num.Faraday * D) #BC
  641. t_max = diffusion_time_scale
  642. println("diffusion_time_scale", diffusion_time_scale)
  643. analytical_dx = L / analytical_nx # Spatial step size
  644. analytical_x = collect(0:analytical_dx:L) # Spatial domain
  645. c0 = num.concentration0[2]
  646. println("max c without convection", c0 - F1 * L / 2, c0 + F1 * L / 2)
  647. max_nb_Fourier_series = 1000
  648. # Special function u1
  649. function full_cell_u1(x, t)
  650. return F1 * x
  651. # return (F2-F1)/(2*L) + F1 * x + D*(F2-F1)/L*t #if different left right
  652. end
  653. # Initial condition f(x)
  654. function full_cell_f(x)
  655. return c0 - full_cell_u1(x, 0) # Example initial condition c0-u1?
  656. end
  657. # Coefficients A_n
  658. function full_cell_A_n(n, L, F1, dx,c0)
  659. # integral = sum(full_cell_f(xi) * cos(n * π * xi / L) for xi in x) * dx
  660. # return (2 / L) * integral #* cos(n * π * x / L)
  661. if n == 0
  662. return -F1*L +2*c0 #-c0*L*2/L #analytical if just F1 * x
  663. else
  664. return (-2*F1*L)/(n*π)^2*((-1)^n-1) #analytical if just F1 * x
  665. end
  666. end
  667. # Solution u2
  668. function full_cell_u2(x, t, L, D, max_nb_Fourier_series,c0,analytical_dx)
  669. result = sum(full_cell_A_n(n, L, F1, analytical_dx,c0) * cos(n * π * x / L) * exp(-D * (n * π / L)^2 * t) for n in 1:max_nb_Fourier_series)
  670. result += full_cell_A_n(0, L, F1, analytical_dx,c0) * cos(0 * π * x / L) * exp(-D * (0 * π / L)^2 * t) / 2
  671. #case 0 special int cos(0) cos(0)dx = L
  672. return result
  673. end
  674. # Total solution u
  675. function full_cell_u(x, t, L, D, max_nb_Fourier_series,c0,analytical_dx)
  676. return full_cell_u1(x, t) + full_cell_u2(x, t, L, D, max_nb_Fourier_series,c0,analytical_dx)
  677. end
  678. # print("\n param ",gp.x[2,:]," | ",num.time," | ",L," | ",num.diffusion_coeff[2]," | ",max_nb_Fourier_series," | ",c0," | ",analytical_dx)
  679. #TODO NX vs n ... need to interpolate
  680. # concentration_profile = full_cell_u.(analytical_x,num.time,L,num.diffusion_coeff[2],max_nb_Fourier_series,c0,analytical_dx)
  681. concentration_profile = full_cell_u.(gp.x[2,:],num.time,L,num.diffusion_coeff[2],max_nb_Fourier_series,c0,analytical_dx)
  682. print("\n concentration profile ",phL.trans_scal[2,:,2])
  683. print("\n concentration profile ",concentration_profile)
  684. # norm_all = relative_errors(phL.trans_scal[:,:,2], concentration_profile, vcat(LIQUID, MIXED), gp.LS[1].geoL.cap[:,:,5], num.Δ)
  685. # norm_mixed = relative_errors(phL.trans_scal[:,:,2], concentration_profile, MIXED, gp.LS[1].geoL.cap[:,:,5], num.Δ)
  686. # norm_full = relative_errors(phL.trans_scal[:,:,2], concentration_profile, LIQUID, gp.LS[1].geoL.cap[:,:,5], num.Δ)
  687. l1,l2,linfty = relative_errors(phL.trans_scal[:,:,2], concentration_profile, vcat(LIQUID, MIXED), gp.LS[1].geoL.cap[:,:,5], num.Δ)
  688. l1_mixed,l2_mixed,linfty_mixed = relative_errors(phL.trans_scal[:,:,2], concentration_profile, MIXED, gp.LS[1].geoL.cap[:,:,5], num.Δ)
  689. l1_full,l2_full,linfty_full = relative_errors(phL.trans_scal[:,:,2], concentration_profile, LIQUID, gp.LS[1].geoL.cap[:,:,5], num.Δ)
  690. end
  691. # error_list_l1[i] = norm_all[1]
  692. # error_list_l2[i] = norm_all[2]
  693. # error_list_linfty[i] = norm_all[3]
  694. # error_list_l1_mixed[i] = norm_mixed[1]
  695. # error_list_l2_mixed[i] = norm_mixed[2]
  696. # error_list_linfty_mixed[i] = norm_mixed[3]
  697. # error_list_l1_full[i] = norm_full[1]
  698. # error_list_l2_full[i] = norm_full[2]
  699. # error_list_linfty_full[i] = norm_full[3]
  700. error_list_l1[i] = l1
  701. error_list_l2[i] = l2
  702. error_list_linfty[i] = linfty
  703. error_list_l1_mixed[i] = l1_mixed
  704. error_list_l2_mixed[i] = l2_mixed
  705. error_list_linfty_mixed[i] = linfty_mixed
  706. error_list_l1_full[i] = l1_full
  707. error_list_l2_full[i] = l2_full
  708. error_list_linfty_full[i] = linfty_full
  709. cell_volume_list[i] = minimum(gp.LS[1].geoL.dcap[:,:,5])
  710. min_cell_volume = minimum(gp.LS[1].geoL.dcap[:,:,5])
  711. if study.compute_errors != "None" #"Poiseuille"
  712. local PDI_status = @ccall "libpdi".PDI_multi_expose("convergence_study_iter"::Cstring,
  713. "study_nb_grid_points"::Cstring, study_nb_grid_points::Ref{Clong}, PDI_OUT::Cint,
  714. "study_timestep"::Cstring, timestep::Ref{Cdouble}, PDI_OUT::Cint,
  715. # "cell_volume"::Cstring, cell_volume_list::Ptr{Cdouble}, PDI_OUT::Cint,
  716. "study_l1_rel_error"::Cstring, l1::Ref{Cdouble}, PDI_OUT::Cint,
  717. "study_l2_rel_error"::Cstring, l2::Ref{Cdouble}, PDI_OUT::Cint,
  718. "study_linfty_rel_error"::Cstring, linfty::Ref{Cdouble}, PDI_OUT::Cint,
  719. "study_l1_rel_error_full_cells"::Cstring, l1_full::Ref{Cdouble}, PDI_OUT::Cint,
  720. "study_l2_rel_error_full_cells"::Cstring, l2_full::Ref{Cdouble}, PDI_OUT::Cint,
  721. "study_linfty_rel_error_full_cells"::Cstring, linfty_full::Ref{Cdouble}, PDI_OUT::Cint,
  722. "study_l1_rel_error_partial_cells"::Cstring, l1_mixed::Ref{Cdouble}, PDI_OUT::Cint,
  723. "study_l2_rel_error_partial_cells"::Cstring, l2_mixed::Ref{Cdouble}, PDI_OUT::Cint,
  724. "study_linfty_rel_error_partial_cells"::Cstring, linfty_mixed::Ref{Cdouble}, PDI_OUT::Cint,
  725. "domain_length"::Cstring, L0::Ref{Cdouble}, PDI_OUT::Cint,
  726. "min_cell_volume"::Cstring, min_cell_volume::Ref{Cdouble}, PDI_OUT::Cint,
  727. C_NULL::Ptr{Cvoid})::Cint
  728. end
  729. end
  730. current_directory = pwd()
  731. if current_directory == base_directory*"/"*timestep_to_string*"/"*mesh_to_string
  732. cd("..")
  733. else
  734. print("\n Error in mesh subdirectory",current_directory," not ",base_directory*"/"*timestep_to_string*"/"*mesh_to_string)
  735. exit()
  736. end
  737. end
  738. #endregion mesh convergence
  739. current_directory = pwd()
  740. if current_directory == base_directory*"/"*timestep_to_string
  741. cd("..")
  742. else
  743. print("\n Error in timestep subdirectory",current_directory," not ",base_directory*"/"*timestep_to_string)
  744. exit()
  745. end
  746. end
  747. #endregion timestep convergence
  748. min_cell_volume = minimum(gp.LS[1].geoL.cap[:,:,5])
  749. print("\n min_cell_volume ",min_cell_volume," type ",typeof(min_cell_volume))
  750. if study.compute_errors != "None" #"Poiseuille"
  751. local PDI_status = @ccall "libpdi".PDI_multi_expose("convergence_study"::Cstring,
  752. "n_tests"::Cstring, n_cases::Ref{Clonglong}, PDI_OUT::Cint,
  753. "nx_list"::Cstring, nb_grid_points::Ptr{Clonglong}, PDI_OUT::Cint,
  754. "cell_volume_list"::Cstring, cell_volume_list::Ptr{Cdouble}, PDI_OUT::Cint,
  755. "l1_rel_error"::Cstring, error_list_l1::Ptr{Cdouble}, PDI_OUT::Cint,
  756. "l2_rel_error"::Cstring, error_list_l2::Ptr{Cdouble}, PDI_OUT::Cint,
  757. "linfty_rel_error"::Cstring, error_list_linfty::Ptr{Cdouble}, PDI_OUT::Cint,
  758. "l1_rel_error_full_cells"::Cstring, error_list_l1_full::Ptr{Cdouble}, PDI_OUT::Cint,
  759. "l2_rel_error_full_cells"::Cstring, error_list_l2_full::Ptr{Cdouble}, PDI_OUT::Cint,
  760. "linfty_rel_error_full_cells"::Cstring, error_list_linfty_full::Ptr{Cdouble}, PDI_OUT::Cint,
  761. "l1_rel_error_partial_cells"::Cstring, error_list_l1_mixed::Ptr{Cdouble}, PDI_OUT::Cint,
  762. "l2_rel_error_partial_cells"::Cstring, error_list_l2_mixed::Ptr{Cdouble}, PDI_OUT::Cint,
  763. "linfty_rel_error_partial_cells"::Cstring, error_list_linfty_mixed::Ptr{Cdouble}, PDI_OUT::Cint,
  764. "domain_length"::Cstring, L0::Ref{Cdouble}, PDI_OUT::Cint,
  765. "min_cell_volume"::Cstring, min_cell_volume::Ref{Cdouble}, PDI_OUT::Cint,
  766. C_NULL::Ptr{Cvoid})::Cint
  767. end
  768. if io.pdi>0
  769. try
  770. # local PDI_status = @ccall "libpdi".PDI_event("close_pycall"::Cstring)::Cint
  771. # PDI_event("finalization");
  772. # local PDI_status = @ccall "libpdi".PDI_event("finalization"::Cstring)::Cint
  773. local PDI_status = @ccall "libpdi".PDI_finalize()::Cint
  774. # printstyled(color=:red, @sprintf "\n PDI end\n" )
  775. catch error
  776. printstyled(color=:red, @sprintf "\n PDI error \n")
  777. print(error)
  778. end
  779. end #if io.pdi>0
  780. printstyled(color=:red, @sprintf "\n After PDI \n")
  781. #Tests
  782. if haskey(macros,"test_end")
  783. eval(Meta.parseall(macros.test_end))
  784. end