run.jl 153 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292
  1. """
  2. Main function of Flower.jl code to run a simulation
  3. """
  4. function run_forward!(
  5. num::Numerical{Float64, Int64},
  6. grid_p::Mesh{Flower.GridCC, Float64, Int64},
  7. grid_u::Mesh{Flower.GridFCx, Float64, Int64},
  8. grid_v::Mesh{Flower.GridFCy, Float64, Int64},
  9. op::DiscreteOperators{Float64, Int64},
  10. phS::Union{Phase{Float64},Nothing},
  11. phL::Phase{Float64};
  12. periodic_x::Bool = false,
  13. periodic_y::Bool = false,
  14. BC_TS = Boundaries(),
  15. BC_TL = Boundaries(),
  16. BC_pS = Boundaries(),
  17. BC_pL = Boundaries(),
  18. BC_uS = BoundariesInt(),
  19. BC_uL = BoundariesInt(),
  20. BC_vS = BoundariesInt(),
  21. BC_vL = BoundariesInt(),
  22. BC_u = Boundaries(),
  23. BC_trans_scal = Vector{BoundariesInt}(),
  24. BC_phi_ele = BoundariesInt(),
  25. BC_int::Vector{<:BoundaryCondition} = [WallNoSlip()],
  26. time_scheme::TemporalIntegration = CN,
  27. ls_scheme::LevelsetDiscretization = weno5,
  28. auto_reinit::Int64 = 0,
  29. heat::Bool = false,
  30. heat_convection::Bool = false,
  31. heat_liquid_phase::Bool = false,
  32. heat_solid_phase::Bool = false,
  33. navier_stokes ::Bool= false,
  34. ns_advection::Bool = false,
  35. ns_liquid_phase::Bool = false,
  36. ns_solid_phase::Bool = false,
  37. hill::Bool = false,
  38. Vmean::Bool = false,
  39. levelset::Bool = true,
  40. analytical::Bool = false,
  41. verbose::Bool = false,
  42. show_every::Int64 = 100,
  43. save_radius::Bool = false,
  44. adaptative_t::Bool = false,
  45. breakup::Int64 = 0,
  46. Ra::Float64 = 0.0,
  47. electrolysis::Bool = false,
  48. electrolysis_convection::Bool = false,
  49. electrolysis_liquid_phase::Bool = false,
  50. electrolysis_solid_phase::Bool = false,
  51. electrolysis_phase_change_case::String = "Khalighi",
  52. imposed_velocity::String = "none",
  53. adapt_timestep_mode::Int64 = 0,
  54. non_dimensionalize::Int64=1,
  55. mode_2d::Int64=0,
  56. test_laplacian::Bool = false,
  57. )
  58. #region Initialize simulation parameters
  59. λ = 1 #for Stefan velocity
  60. speed = 0.0
  61. radius_pdi = [0.0] #radius for pdi, list so that value is mutable
  62. if num.time > num.nucleation_time && num.phase_change_method >0 #TODO more precisely no mass transfer but velocity
  63. num.phase_change_currently_activated = 1
  64. end
  65. if num.mu1 == 0.0 && num.mu2 == 0.0 && num.mu_one_fluid_average !=0
  66. @error ("Resetting num.mu_one_fluid_average to 0")
  67. num.mu_one_fluid_average = 0
  68. end
  69. # if (num.one_fluid_model == 1 && num.solve_Navier_Stokes_liquid_phase == 1)
  70. # if CL BC
  71. # # grid_u.LS[1].cl
  72. # @error("BC CL with one fluid")
  73. # end
  74. # end
  75. #TODO Re
  76. #TODO homogenize set_poisson... functions which use -b - in the original implementation and not +b + for the Robin BC
  77. # Defining epsilon length and volume to handle special cells
  78. if num.epsilon_mode == 1 || num.epsilon_mode ==2
  79. num.epsilon_dist = eps(0.01) * num.Δ
  80. num.epsilon_vol = (eps(0.01)*num.Δ)^2
  81. num.epsilon_dist_mass_transfer_rate = num.Δ / 10 #TODO improve ex crit vol cf num.epsilon_volume_fraction_phase_change
  82. #TODO kill dead cells
  83. #TODO 1e-...
  84. end
  85. electrode_definition_function = (num.electrolysis_reaction_symb === :Butler_no_concentration) ? vecb_L : vecb_B
  86. # Temp = heat ? T : num.temperature0
  87. # if monophasic
  88. # if length(BC_int) != num.nLS
  89. # @error ("You have to specify $(num.nLS) boundary conditions.")
  90. # return nothing
  91. # end
  92. num.status = 0 # used to stop the simulation
  93. num.current_iter = 0 #1
  94. num.time = 0.
  95. free_surface = false
  96. stefan = false
  97. navier = false
  98. ls_advection = true
  99. if any(is_fs, BC_int)
  100. free_surface = true
  101. end
  102. if any(is_stefan, BC_int)
  103. stefan = true
  104. end
  105. if any(is_navier_cl, BC_int) || any(is_navier, BC_int)
  106. navier = true
  107. end
  108. if num.nNavier > 1
  109. @warn ("When using more than 1 Navier BC, the interfaces shouldn't cross")
  110. end
  111. if free_surface && stefan
  112. @error ("Cannot advect the levelset using both free-surface and stefan condition.")
  113. return nothing
  114. elseif free_surface || stefan || (num.one_fluid_model == 1 && num.solve_Navier_Stokes_liquid_phase == 1) && (num.activate_interface != 0) #|| electrolysis_phase_change_case !="none"
  115. # num.activate_interface != 0 : no interface, do not advect (monophasic)
  116. advection = true
  117. else
  118. advection = false
  119. end
  120. if num.solve_Navier_Stokes_liquid_phase == 0
  121. advection = false
  122. electrolysis_advection = false
  123. else
  124. if electrolysis
  125. electrolysis_advection = true
  126. end
  127. end
  128. if num.advection_LS_mode == 16 || num.advection_LS_mode == 16 #test Cipriano 2024 's method
  129. extend_liquid_velocity = true
  130. else
  131. extend_liquid_velocity = false
  132. end
  133. # The count threshold shouldn't be smaller than 2
  134. count_limit_breakup = 6
  135. if num.verbosity > 0
  136. printstyled(color=:green, @sprintf "\n num.CFL : %.2e dt : %.2e\n" num.CFL num.timestep_n)
  137. end
  138. #compute initial curvature (TODO other interfaces than circle)
  139. num.mean_curvature = 1.0/num.R
  140. num.current_radius = num.R
  141. # if num.surface_tension == 0
  142. # compute_surface_tension_VOF!(num,grid_p, grid_u, grid_v, opC_p, opC_u, opC_v,
  143. # volume_fraction,levelset_one_fluid,volumic_surface_tension_u,volumic_surface_tension_v,tmp_vec_p,tmp_vec_p0)
  144. # elseif num.surface_tension == 1
  145. # compute_surface_tension_LS!(num,grid_p, grid_u, grid_v, opC_p, opC_u, opC_v,
  146. # volume_fraction,levelset_one_fluid,volumic_surface_tension_u,volumic_surface_tension_v,tmp_vec_p,tmp_vec_p0,
  147. # levelset_1D, levelset_heavyside_2D, normal_and_dirac_u, normal_and_dirac_v,
  148. # normal_u, normal_v, curvature_u, curvature_v)
  149. # end
  150. num.timestep_n = adapt_timestep!(num, phL, phS, grid_u, grid_v,adapt_timestep_mode)
  151. pres_free_surfaceS = 0.0
  152. # pres_free_surfaceL = 0.0
  153. pres_free_surfaceL = num.pres0
  154. if occursin("levelset",electrolysis_phase_change_case)
  155. jump_mass_transfer_rateS = false
  156. jump_mass_transfer_rateL = true
  157. else
  158. jump_mass_transfer_rateS = false
  159. jump_mass_transfer_rateL = false
  160. end
  161. mass_transfer_rateS = 0.0
  162. iRe = 1.0 / num.Re
  163. # CFL_sc is not a CFL, it is supposed to be the timestep divided by the cell volume
  164. CFL_sc = num.timestep_n / num.Δ^2
  165. irho = 1.0
  166. num.mu_cin1 = num.mu1 / num.rho1
  167. num.mu_cin2 = num.mu2 / num.rho2
  168. if non_dimensionalize==0
  169. #force L=1 u=1
  170. Re=num.rho1/num.mu1
  171. iRe = 1.0/Re
  172. irho=1.0/num.rho1
  173. num.visc_coeff=iRe
  174. else
  175. num.visc_coeff=iRe
  176. Re = num.Re
  177. end
  178. if num.verbosity > 0 && num.solve_Navier_Stokes>0
  179. printstyled(color=:green, @sprintf "\n Re : %.2e %.2e\n" Re num.visc_coeff)
  180. printstyled(color=:magenta, @sprintf "\n CFL_sc : %.2e\n" CFL_sc)
  181. end
  182. # Electrolysis
  183. num.current_radius = 0.0
  184. # TODO kill_dead_cells! for [:,:,iscal]
  185. #region init number of moles
  186. if electrolysis
  187. if electrolysis_phase_change_case != "none"
  188. num.current_radius = num.R
  189. printstyled(color=:green, @sprintf "\n radius: %.2e \n" num.current_radius)
  190. p_liq= num.pres0 + mean(veci(phL.pD,grid_p,2)) #TODO here one bubble
  191. p_g=p_liq + 2 * num.σ / num.current_radius
  192. #TODO using num.temperature0
  193. if mode_2d==0
  194. num.nH2 = p_g * 4.0 / 3.0 * pi * num.current_radius ^ 3 / (num.temperature0 * num.Ru)
  195. elseif mode_2d == 1 #reference thickness for a cylinder
  196. num.nH2 = p_g * pi * num.current_radius ^ 2 * num.ref_thickness_2d / (num.temperature0 * num.Ru)
  197. elseif mode_2d==2 #mol/meter
  198. num.nH2=num.concentration0[num.index_phase_change]* pi * num.current_radius ^ 2
  199. elseif mode_2d==3 #mol/meter half circle
  200. num.nH2=1.0/2.0*num.concentration0[num.index_phase_change]* pi * num.current_radius ^ 2
  201. end
  202. # num.nH2 = 4.0/3.0 * pi * num.current_radius^3 * num.rho2 / num.MWH2
  203. printstyled(color=:green, @sprintf "\n Mole: %.2e \n" num.nH2)
  204. printstyled(color=:green, @sprintf "\n Mole test: %.2e %.2e\n" num.concentration0[num.index_phase_change]*4.0/3.0*pi*num.current_radius^3 p_g*4.0/3.0*pi*num.current_radius^3/(num.temperature0*num.Ru))
  205. end
  206. end # if electrolysis
  207. #endregion init number of moles
  208. #endregion Initialize simulation parameters
  209. local NB_indices;
  210. #region Allocations
  211. if num.solve_solid == 1
  212. local Cum1S = fzeros(grid_u)
  213. local Cvm1S = fzeros(grid_v)
  214. local Mm1_S
  215. local Mum1_S
  216. local Mvm1_S
  217. end
  218. local Cum1L = fzeros(grid_u)
  219. local Cvm1L = fzeros(grid_v)
  220. local Mm1_L
  221. local Mum1_L
  222. local Mvm1_L
  223. if extend_liquid_velocity #num.advection_LS_mode == 16
  224. # *_ext_vel : variables for the second system of Navier-Stokes equations
  225. local Cum1L_ext_vel = fzeros(grid_u)
  226. local Cvm1L_ext_vel = fzeros(grid_v)
  227. # local Mm1_L_ext_vel
  228. # local Mum1_L_ext_vel
  229. # local Mvm1_L_ext_vel
  230. p_ext_vel = zeros(grid_p)
  231. pD_ext_vel = fzeros(grid_p)
  232. phi_ext_vel = zeros(grid_p)
  233. u_ext_vel = zeros(grid_u)
  234. v_ext_vel= zeros(grid_v)
  235. u_predictionD_ext_vel= fzeros(grid_u)
  236. v_predictionD_ext_vel= fzeros(grid_v)
  237. uD_ext_vel= fzeros(grid_u)
  238. vD_ext_vel= fzeros(grid_v)
  239. u_prediction_ext_vel= zeros(grid_u)
  240. v_prediction_ext_vel= zeros(grid_v)
  241. uT_ext_vel = zeros(grid_p)
  242. pres_grad_x = fzeros(grid_u)
  243. pres_grad_y = fzeros(grid_v)
  244. else
  245. u_ext_vel = nothing
  246. v_ext_vel= nothing
  247. end
  248. θ_out = zeros(grid_p, 4)
  249. utmp = copy(grid_p.LS[1].u)
  250. rhs_LS = fzeros(grid_p)
  251. #vectors used reset at start of functions to limit allocations
  252. tmp_vec_u = zeros(grid_u)
  253. tmp_vec_v = zeros(grid_v)
  254. tmp_vec_u0 = zeros(grid_u)
  255. tmp_vec_v0 = zeros(grid_v)
  256. tmp_vec_u1 = zeros(grid_u)
  257. tmp_vec_v1 = zeros(grid_v)
  258. tmp_vec_p = zeros(grid_p)
  259. tmp_vec_p0 = zeros(grid_p)
  260. tmp_vec_p1 = zeros(grid_p)
  261. tmp_vec_1D = fnzeros(grid_p,num)
  262. tmp_vec_1D_2 = fnzeros(grid_p,num)
  263. # tmp_vec_1D_u = fnzeros(grid_p,num)
  264. tmp_vec_1D_v = fnzeros(grid_v,num)
  265. tmp_vec_1D_v0 = fnzeros(grid_v,num)
  266. tmp_vec_1D_p = fnzeros(grid_p,num)
  267. tmp_vec_1D_p0 = fnzeros(grid_p,num)
  268. # nb_gaz_acceptors = zeros(grid_p)
  269. #region electrolysis
  270. #TODO harmonic conductivity
  271. if electrolysis
  272. if num.nb_transported_scalars>1
  273. elec_cond = zeros(grid_p)
  274. elec_condD = fnzeros(grid_p,num)
  275. if heat
  276. elec_condD .= compute_ele_cond.(num.Faraday,num.diffusion_coeff[num.index_electrolyte],num.Ru, phL.TD, phL.trans_scalD[:,num.index_electrolyte])
  277. elec_cond .= reshape(vec1(elec_condD,grid_p),grid_p)
  278. # elec_cond .= compute_ele_cond.(num.Faraday,num.diffusion_coeff[num.index_electrolyte],num.Ru, phL.T, phL.trans_scal)
  279. # elec_cond = 2*num.Faraday^2 .*phL.trans_scal[:,:,2].*num.diffusion_coeff[2]./(num.Ru.*phL.T) #phL.T
  280. else
  281. elec_condD .= compute_ele_cond.(num.Faraday,num.diffusion_coeff[num.index_electrolyte],num.Ru, num.temperature0, phL.trans_scalD[:,num.index_electrolyte])
  282. elec_cond .= reshape(vec1(elec_condD,grid_p),grid_p)
  283. # elec_cond .= compute_ele_cond.(num.Faraday,num.diffusion_coeff[num.index_electrolyte],num.Ru, num.temperature0, phL.trans_scal)
  284. # elec_cond = 2*num.Faraday^2 .*phL.trans_scal[:,:,2].*num.diffusion_coeff[2]./(num.Ru*num.temperature0)
  285. end
  286. else
  287. elec_cond = ones(grid_p)
  288. elec_condD = fnones(grid_p,num)
  289. printstyled(color=:green, @sprintf "\n conductivity one")
  290. end
  291. # update_electrical_conductivity!(num,grid,elec_cond,elec_condD,heat;phL)
  292. # if num.electrolysis_reaction == "Butler_no_concentration"
  293. # i_butler = zeros(grid_p.ny) #left wall
  294. # elseif num.electrolysis_reaction == "fixed_current"
  295. # i_butler = zeros(grid_p.nx) #bottom wall
  296. # end
  297. printstyled(color=:red, @sprintf "\n Reaction")
  298. i_butler = Float64[] # empty vector, defined in scope
  299. print("\n electrolysis_reaction_symb ",num.electrolysis_reaction_symb)
  300. if num.electrolysis_reaction_symb === :none
  301. else
  302. size_BC_reaction = if num.electrolysis_reaction_symb === :Butler_no_concentration
  303. grid_p.ny
  304. elseif num.electrolysis_reaction_symb === :fixed_current
  305. grid_p.nx
  306. else
  307. error("Unknown electrolysis_reaction")
  308. end
  309. resize!(i_butler, size_BC_reaction)
  310. fill!(i_butler, 0.0)
  311. end
  312. end #electrolysis
  313. #endregion electrolysis
  314. if levelset
  315. # At every iteration, update_all_ls_data is called twice,
  316. # once inside run.jl and another one (if there's advection of the levelset) inside set_heat!.
  317. # The difference between both is a flag as last argument, inside run.jl is
  318. # implicitly defined as true and inside set_heat is false.
  319. # If you're calling your version of set_heat several times, then you're calling the version with the flag set to false, but for the convective term it has to be set to true, so that's why
  320. # The flag=true, the capacities are set for the convection, the flag=false they are set for the other operators
  321. NB_indices = update_all_ls_data(num, grid_p, grid_u, grid_v, BC_int, periodic_x, periodic_y)
  322. # printstyled(color=:red, @sprintf "\n levelset:\n")
  323. # println(grid_p.LS[1].geoL.dcap[1,1,:])
  324. if save_radius
  325. n_snaps = iszero(num.max_iterations%num.save_every) ? num.max_iterations÷num.save_every+1 : num.max_iterations÷num.save_every+2
  326. local radius = zeros(n_snaps)
  327. radius[1] = find_radius(grid_p, grid_p.LS[1])
  328. end
  329. if hill
  330. local radius = zeros(num.max_iterations+1)
  331. a = zeros(length(grid_p.LS[1].MIXED))
  332. for i in eachindex(grid_p.LS[1].MIXED)
  333. a[i] = grid_p.LS[1].geoL.projection[grid_p.LS[1].MIXED[i]].pos.y
  334. end
  335. radius[1] = mean(a)
  336. end
  337. elseif !levelset
  338. grid_p.LS[1].MIXED = [CartesianIndex(-1,-1)]
  339. grid_u.LS[1].MIXED = [CartesianIndex(-1,-1)]
  340. grid_v.LS[1].MIXED = [CartesianIndex(-1,-1)]
  341. end
  342. # if save_length
  343. # fwd.length[1] = arc_length2(grid_p.LS[1].geoS.projection, grid_p.LS[1].MIXED)
  344. # end
  345. #endregion
  346. #region Initialisation of bulk and interfacial values
  347. # Initialisation of bulk and interfacial values
  348. #TODO which grid_p.LS
  349. #TODO perio, intfc, ... check init_fields_2!
  350. #No scalar in "solid" phase
  351. # @views init_fields_multiple_levelsets!(num,phS.trans_scalD[:,iscal],phS.trans_scal[:,:,iscal],HS,BC_trans_scal[iscal],grid_p,num.concentration0[iscal])
  352. # @views phS.trans_scal[:,:,iscal] .= num.concentration0[iscal]
  353. # TODO reset zero
  354. tmp_vec_u .= 0.0
  355. if num.solve_solid == 1
  356. #from LS 1 to centroid grid_u.LS[end].geoS
  357. get_height!(grid_u.LS[1],grid_u.ind,grid_u.dx,grid_u.dy,grid_u.LS[end].geoS,tmp_vec_u) #here tmp_vec_u solid
  358. init_fields_multiple_levelsets!(num,phS.uD,phS.u,tmp_vec_u,BC_uS,grid_u,num.uD,"uS")
  359. # init_fields_multiple_levelsets!(num,phS.u_predictionD,phS.u,HSu,BC_uS,grid_u,num.uD)
  360. end
  361. get_height!(grid_u.LS[1],grid_u.ind,grid_u.dx,grid_u.dy,grid_u.LS[end].geoL,tmp_vec_u) #here tmp_vec_u liquid
  362. init_fields_multiple_levelsets!(num,phL.uD,phL.u,tmp_vec_u,BC_uL,grid_u,num.uD,"uL")
  363. # init_fields_multiple_levelsets!(num,phL.u_predictionD,phL.u,HLu,BC_uL,grid_u,num.uD)
  364. # TODO reset zero
  365. tmp_vec_v .= 0.0
  366. if num.solve_solid == 1
  367. get_height!(grid_v.LS[1],grid_v.ind,grid_v.dx,grid_v.dy,grid_v.LS[end].geoS,tmp_vec_v)
  368. init_fields_multiple_levelsets!(num,phS.vD,phS.v,tmp_vec_v,BC_vS,grid_v,num.vD,"vS")
  369. # init_fields_multiple_levelsets!(num,phS.v_predictionD,phS.v,HSv,BC_vS,grid_v,num.vD)
  370. end
  371. get_height!(grid_v.LS[1],grid_v.ind,grid_v.dx,grid_v.dy,grid_v.LS[end].geoL,tmp_vec_v)
  372. init_fields_multiple_levelsets!(num,phL.vD,phL.v,tmp_vec_v,BC_vL,grid_v,num.vD,"vL")
  373. # init_fields_multiple_levelsets!(num,phL.v_predictionD,phL.v,HLv,BC_vL,grid_v,num.vD)
  374. # TODO reset zero
  375. tmp_vec_p .= 0.0
  376. if num.solve_solid == 1
  377. get_height!(grid_p.LS[1],grid_p.ind,grid_p.dx,grid_p.dy,grid_p.LS[end].geoS,tmp_vec_p) #here tmp_vec_p solid
  378. init_fields_multiple_levelsets!(num,phS.pD,phS.p,tmp_vec_p,BC_pS,grid_p,num.pres_intfc,"pS")
  379. if heat
  380. init_fields_multiple_levelsets!(num,phS.TD,phS.T,tmp_vec_p,BC_TS,grid_p,num.θd,"TS")
  381. end
  382. #Electrolysis
  383. if electrolysis && num.electrical_potential > 0
  384. init_fields_multiple_levelsets!(num,phS.phi_eleD,phS.phi_ele,tmp_vec_p,BC_phi_ele,grid_p,num.phi_ele0,"phiS")
  385. end
  386. end
  387. get_height!(grid_p.LS[1],grid_p.ind,grid_p.dx,grid_p.dy,grid_p.LS[end].geoL,tmp_vec_p) #here tmp_vec_p liquid
  388. init_fields_multiple_levelsets!(num,phL.pD,phL.p,tmp_vec_p,BC_pL,grid_p,num.pres_intfc,"pL")
  389. if heat
  390. init_fields_multiple_levelsets!(num,phL.TD,phL.T,tmp_vec_p,BC_TL,grid_p,num.θd,"TL")
  391. end
  392. # Electrolysis
  393. if electrolysis
  394. printstyled(color=:green, @sprintf "\n Check %s %s %s %s %.2e %.2e %2i\n" heat heat_convection electrolysis electrolysis_convection num.timestep_n num.θd num.nb_transported_scalars)
  395. for iscal=1:num.nb_transported_scalars
  396. @views phL.trans_scal[:,:,iscal] .= num.concentration0[iscal]
  397. @views init_fields_multiple_levelsets!(num,phL.trans_scalD[:,iscal],phL.trans_scal[:,:,iscal],
  398. tmp_vec_p,BC_trans_scal[iscal],grid_p,num.concentration0[iscal],"scalL")
  399. # tmp_vec_p,BC_trans_scal[iscal],grid_p,num.concentration0[iscal],"testscalL")
  400. end
  401. if num.electrical_potential > 0 #TODO init phi =0 or with Neumann for BC of concentration? for now not done since "phiL" given in arg
  402. init_fields_multiple_levelsets!(num,phL.phi_eleD,phL.phi_ele,tmp_vec_p,BC_phi_ele,grid_p,num.phi_ele0,"phiL")
  403. if num.electrical_potential == 3
  404. vecb(phL.phi_eleD,grid_p) .= 0.0
  405. end
  406. end
  407. end
  408. if electrolysis
  409. printstyled(color=:green, @sprintf "\n Check init_fields_2!\n")
  410. # print_electrolysis_statistics(num,grid_p,phL)
  411. PDI_status = @ccall "libpdi".PDI_multi_expose("print_variables"::Cstring,
  412. "nstep"::Cstring, num.current_iter ::Ref{Clonglong}, PDI_OUT::Cint,
  413. "time"::Cstring, num.time::Ref{Cdouble}, PDI_OUT::Cint,
  414. "u_1D"::Cstring, phL.uD::Ptr{Cdouble}, PDI_OUT::Cint,
  415. "v_1D"::Cstring, phL.vD::Ptr{Cdouble}, PDI_OUT::Cint,
  416. "p_1D"::Cstring, phL.pD::Ptr{Cdouble}, PDI_OUT::Cint,
  417. "levelset_p"::Cstring, grid_p.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  418. "levelset_u"::Cstring, grid_u.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  419. "levelset_v"::Cstring, grid_v.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  420. # "levelset_p_wall"::Cstring, LStable::Ptr{Cdouble}, PDI_OUT::Cint,
  421. "trans_scal_1DT"::Cstring, phL.trans_scalD'::Ptr{Cdouble}, PDI_OUT::Cint,
  422. "phi_ele_1D"::Cstring, phL.phi_eleD::Ptr{Cdouble}, PDI_OUT::Cint,
  423. # "i_current_x"::Cstring, Eus::Ptr{Cdouble}, PDI_OUT::Cint,
  424. # "i_current_y"::Cstring, Evs::Ptr{Cdouble}, PDI_OUT::Cint,
  425. # "velocity_x"::Cstring, us::Ptr{Cdouble}, PDI_OUT::Cint,
  426. # "velocity_y"::Cstring, vs::Ptr{Cdouble}, PDI_OUT::Cint,
  427. # "radius"::Cstring, current_radius::Ref{Cdouble}, PDI_OUT::Cint,
  428. # "intfc_vtx_num"::Cstring, intfc_vtx_num::Ref{Clonglong}, PDI_OUT::Cint,
  429. # "intfc_seg_num"::Cstring, intfc_seg_num::Ref{Clonglong}, PDI_OUT::Cint,
  430. # "intfc_vtx_x"::Cstring, intfc_vtx_x::Ptr{Cdouble}, PDI_OUT::Cint,
  431. # "intfc_vtx_y"::Cstring, intfc_vtx_y::Ptr{Cdouble}, PDI_OUT::Cint,
  432. # "intfc_vtx_field"::Cstring, intfc_vtx_field::Ptr{Cdouble}, PDI_OUT::Cint,
  433. # "intfc_vtx_connectivities"::Cstring, intfc_vtx_connectivities::Ptr{Clonglong}, PDI_OUT::Cint,
  434. C_NULL::Ptr{Cvoid})::Cint
  435. if num.solve_solid == 1
  436. if (any(isnan, phL.uD) || any(isnan, phL.vD) || any(isnan, phL.TD) ||
  437. any(isnan, phS.uD) || any(isnan, phS.vD) || any(isnan, phS.TD) ||
  438. any(isnan, phL.trans_scalD) || any(isnan, phL.phi_eleD) ||
  439. norm(phL.u) > 1e8 || norm(phL.T) > 1e8 ||
  440. norm(phS.u) > 1e8 || norm(phS.T) > 1e8
  441. # norm(phL.trans_scal) > 1e8
  442. || norm(phL.phi_ele) > 1e8
  443. # ||
  444. # any(phL.trans_scal .<0)
  445. )
  446. println(@sprintf "\n CRASHED start \n")
  447. print("\n phL.uD: ",any(isnan, phL.uD) , "\n phL.vD: ",any(isnan, phL.vD) , "\n phL.TD: ",any(isnan, phL.TD) ,
  448. "\n phS.uD: ",any(isnan, phS.uD) , "\n phS.vD: ",any(isnan, phS.vD) , "\n phS.TD: ",any(isnan, phS.TD) ,
  449. "\n phL.trans_scalD: ",any(isnan, phL.trans_scalD) , "\n phL.phi_eleD: ",any(isnan, phL.phi_eleD) ,
  450. "\n phL.u: ",norm(phL.u) > 1e8 , "\n phS.u: ",norm(phS.u) > 1e8 , "\n phL.T: ",norm(phL.T) > 1e8 ,
  451. "\n phS.T: ",norm(phS.T) > 1e8 , "\n phL.trans_scal: ",norm(phL.trans_scal) > 1e8 ,
  452. "\n phL.phi_ele: ",norm(phL.phi_ele) > 1e8,"\n any(phL.trans_scal .<0): ", any(phL.trans_scal .<0))
  453. num.status = 1
  454. return num.current_iter
  455. end
  456. else
  457. if (any(isnan, phL.uD) || any(isnan, phL.vD) || any(isnan, phL.TD) ||
  458. any(isnan, phL.trans_scalD) || any(isnan, phL.phi_eleD) ||
  459. norm(phL.u) > 1e8 || norm(phL.T) > 1e8 ||
  460. # norm(phL.trans_scal) > 1e8 ||
  461. norm(phL.phi_ele) > 1e8
  462. # || any(phL.trans_scal .<0)
  463. )
  464. println(@sprintf "\n CRASHED start \n")
  465. # println(@sprintf "\n CRASHED after %d iterations \n" num.current_iter)
  466. print("\n phL.uD: ",any(isnan, phL.uD) , "\n phL.vD: ",any(isnan, phL.vD) , "\n phL.TD: ",any(isnan, phL.TD) ,
  467. "\n phL.trans_scalD: ",any(isnan, phL.trans_scalD) , "\n phL.phi_eleD: ",any(isnan, phL.phi_eleD) ,
  468. "\n phL.u: ",norm(phL.u) > 1e8, "\n phL.T: ",norm(phL.T) > 1e8 ,
  469. "\n phL.trans_scal: ",norm(phL.trans_scal) > 1e8 ,
  470. "\n phL.phi_ele: ",norm(phL.phi_ele) > 1e8,"\n any(phL.trans_scal .<0): ", any(phL.trans_scal .<0))
  471. num.status = 1
  472. return num.current_iter
  473. end
  474. end
  475. interpolate_staggered_u_v_to_scalar_grid_one_fluid_or_one_phase!(num,grid_p,grid_u,grid_v,phL.u,phL.v,tmp_vec_p,tmp_vec_p0)
  476. PDI_status = @ccall "libpdi".PDI_multi_expose("write_data"::Cstring,
  477. "nstep"::Cstring, num.current_iter::Ref{Clonglong}, PDI_OUT::Cint,
  478. "time"::Cstring, num.time::Ref{Cdouble}, PDI_OUT::Cint,
  479. "timestep"::Cstring, num.timestep_n::Ref{Cdouble}, PDI_OUT::Cint,
  480. "nx"::Cstring, grid_p.nx::Ref{Clonglong}, PDI_OUT::Cint,
  481. "ny"::Cstring, grid_p.ny::Ref{Clonglong}, PDI_OUT::Cint,
  482. "u_1D"::Cstring, phL.uD::Ptr{Cdouble}, PDI_OUT::Cint,
  483. "v_1D"::Cstring, phL.vD::Ptr{Cdouble}, PDI_OUT::Cint,
  484. "p_1D"::Cstring, phL.pD::Ptr{Cdouble}, PDI_OUT::Cint,
  485. "levelset_p"::Cstring, grid_p.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  486. "levelset_u"::Cstring, grid_u.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  487. "levelset_v"::Cstring, grid_v.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  488. "trans_scal_1DT"::Cstring, phL.trans_scalD'::Ptr{Cdouble}, PDI_OUT::Cint,
  489. "phi_ele_1D"::Cstring, phL.phi_eleD::Ptr{Cdouble}, PDI_OUT::Cint,
  490. # "i_current_x"::Cstring, tmp_vec_p::Ptr{Cdouble}, PDI_OUT::Cint,
  491. # "i_current_y"::Cstring, tmp_vec_p0::Ptr{Cdouble}, PDI_OUT::Cint,
  492. # "normal_x"::Cstring, normal_x::Ptr{Cdouble}, PDI_OUT::Cint,
  493. # "normal_y"::Cstring, normal_y::Ptr{Cdouble}, PDI_OUT::Cint,
  494. # grid_u.LS[iLS].α
  495. # "normal_angle"::Cstring, grid_p.LS[num.iLSpdi].α::Ptr{Cdouble}, PDI_OUT::Cint,
  496. "velocity_x"::Cstring, tmp_vec_p::Ptr{Cdouble}, PDI_OUT::Cint,
  497. "velocity_y"::Cstring, tmp_vec_p0::Ptr{Cdouble}, PDI_OUT::Cint,
  498. "radius"::Cstring, num.current_radius::Ref{Cdouble}, PDI_OUT::Cint,
  499. # "intfc_vtx_num"::Cstring, intfc_vtx_num::Ref{Clonglong}, PDI_OUT::Cint,
  500. # "intfc_seg_num"::Cstring, intfc_seg_num::Ref{Clonglong}, PDI_OUT::Cint,
  501. # "intfc_vtx_x"::Cstring, intfc_vtx_x::Ptr{Cdouble}, PDI_OUT::Cint,
  502. # "intfc_vtx_y"::Cstring, intfc_vtx_y::Ptr{Cdouble}, PDI_OUT::Cint,
  503. # "intfc_vtx_field"::Cstring, intfc_vtx_field::Ptr{Cdouble}, PDI_OUT::Cint,
  504. # "intfc_vtx_connectivities"::Cstring, intfc_vtx_connectivities::Ptr{Clonglong}, PDI_OUT::Cint,
  505. C_NULL::Ptr{Cvoid})::Cint
  506. end
  507. if num.solve_solid == 1
  508. kill_dead_cells!(phS.T, grid_p, grid_p.LS[end].geoS)
  509. end
  510. kill_dead_cells!(phL.T, grid_p, grid_p.LS[end].geoL)
  511. #TODO check timestep coefficients num.n-1
  512. #Electrolysis
  513. # TODO kill_dead_cells! for [:,:,iscal]
  514. if electrolysis
  515. for iscal=1:num.nb_transported_scalars
  516. # @views kill_dead_cells!(phS.trans_scal[:,:,iscal], grid_p, grid_p.LS[end].geoS) #TODO
  517. # @views kill_dead_cells!(phL.trans_scal[:,:,iscal], grid_p, grid_p.LS[end].geoL)
  518. # @views kill_dead_cells_val!(phS.trans_scal[:,:,iscal], grid_p, grid_p.LS[end].geoS) #TODO
  519. # @views kill_dead_cells_val!(phL.trans_scal[:,:,iscal], grid_p, grid_p.LS[end].geoL,num.concentration0[iscal])
  520. # @views kill_dead_cells_val!(phL.trans_scal[:,:,iscal], grid_p, grid_p.LS[end].geoL,0.0)
  521. if num.kill_dead_cells == 0
  522. @views kill_dead_cells_val!(phL.trans_scal[:,:,iscal], grid_p, grid_p.LS[end].geoL,0.0)
  523. else
  524. @views kill_dead_cells_val!(phL.trans_scal[:,:,iscal], grid_p, grid_p.LS[end].geoL,num.concentration0[iscal])
  525. end
  526. @views veci(phL.trans_scalD[:,iscal],grid_p,1) .= vec(phL.trans_scal[:,:,iscal])
  527. end
  528. end #if electrolysis
  529. #endregion
  530. # print("\n vecb_L(elec_condD, grid_p) after kill \n ", vecb_L(phL.trans_scalD[:,2], grid_p) )
  531. # if num.nb_transported_scalars>0
  532. # printstyled(color=:green, @sprintf "\n after kill \n")
  533. # print_electrolysis_statistics(num,phL)
  534. # printstyled(color=:green, @sprintf "\n average T %s\n" average!(phL.T, grid_p, grid_p.LS[1].geoL, num))
  535. # end
  536. #region Allocations
  537. # Set matrices/operators
  538. if is_Forward_Euler(time_scheme) || is_Crank_Nicolson(time_scheme)
  539. NB_indices = update_all_ls_data(num, grid_p, grid_u, grid_v, BC_int, periodic_x, periodic_y, false)
  540. # printstyled(color=:red, @sprintf "\n levelset 2:\n")
  541. # println(grid_p.LS[1].geoL.dcap[1,1,:])
  542. if navier_stokes || heat || electrolysis
  543. if num.solve_solid == 1
  544. geoS = [grid_p.LS[iLS].geoS for iLS in 1:num._nLS]
  545. geo_uS = [grid_u.LS[iLS].geoS for iLS in 1:num._nLS]
  546. geo_vS = [grid_v.LS[iLS].geoS for iLS in 1:num._nLS]
  547. Lpm1_S, bc_Lpm1_S, bc_Lpm1_b_S, Lum1_S, bc_Lum1_S, bc_Lum1_b_S, Lvm1_S, bc_Lvm1_S, bc_Lvm1_b_S = set_matrices!(
  548. num, grid_p, geoS, grid_u, geo_uS, grid_v, geo_vS,
  549. op.opC_pS, op.opC_uS, op.opC_vS, periodic_x, periodic_y
  550. )
  551. end
  552. geoL = [grid_p.LS[iLS].geoL for iLS in 1:num._nLS]
  553. geo_uL = [grid_u.LS[iLS].geoL for iLS in 1:num._nLS]
  554. geo_vL = [grid_v.LS[iLS].geoL for iLS in 1:num._nLS]
  555. Lpm1_L, bc_Lpm1_L, bc_Lpm1_b_L, Lum1_L, bc_Lum1_L, bc_Lum1_b_L, Lvm1_L, bc_Lvm1_L, bc_Lvm1_b_L = set_matrices!(
  556. num, grid_p, geoL, grid_u, geo_uL, grid_v, geo_vL,
  557. op.opC_pL, op.opC_uL, op.opC_vL, periodic_x, periodic_y
  558. )
  559. end
  560. # Contains volumes
  561. if num.solve_solid == 1
  562. Mm1_S = copy(op.opC_pS.M)
  563. Mum1_S = copy(op.opC_uS.M)
  564. Mvm1_S = copy(op.opC_vS.M)
  565. end
  566. # M defined in set_cutcell_matrices!
  567. Mm1_L = copy(op.opC_pL.M)
  568. Mum1_L = copy(op.opC_uL.M)
  569. Mvm1_L = copy(op.opC_vL.M)
  570. if num.one_fluid_model == 1
  571. @error("\n Mum1L needs to be redefined for one-fluid ")
  572. end
  573. if navier_stokes || heat || electrolysis
  574. #Allocations
  575. #TODO pre-allocate at start to save up allocations
  576. #TODO optimize allocations
  577. # #Preallocate for mass flux computations
  578. # if electrolysis_phase_change_case != "None"
  579. # mass_transfer_rate_vec1 = fzeros(grid_p)
  580. # mass_transfer_rate_vecb = fzeros(grid_p)
  581. # mass_transfer_rate_veci = fzeros(grid_p)
  582. # mass_transfer_rate = zeros(grid_p)
  583. # else
  584. # mass_transfer_rate = 0.0
  585. # end
  586. mass_transfer_rate_vec1 = fzeros(grid_p)
  587. mass_transfer_rate_vecb = fzeros(grid_p)
  588. mass_transfer_rate_veci = fzeros(grid_p)
  589. mass_transfer_rate = zeros(grid_p)
  590. mass_transfer_rate_redistributed = zeros(grid_p)
  591. nb_gaz_acceptors = zeros(Int64,grid_p.ny,grid_p.nx)
  592. # nb_gaz_acceptors = zeros(grid_p)
  593. #Allocations for scalar grid_p
  594. ni = grid_p.nx * grid_p.ny
  595. nb = 2 * grid_p.nx + 2 * grid_p.ny
  596. nt = (num.nLS + 1) * ni + nb
  597. a1_p = spdiagm(ni,ni,zeros(ni))
  598. Ascal = spzeros(nt, nt)
  599. Bscal = spzeros(nt, nt)
  600. rhs_scal = fnzeros(grid_p, num)
  601. F_residual = fnzeros(grid_p, num)
  602. all_CUTCT = zeros(grid_p.ny * grid_p.nx, num.nb_transported_scalars)
  603. if num.one_fluid_model == 0
  604. if num.solve_solid == 1
  605. AϕS = spzeros(nt, nt)
  606. end
  607. AϕL = spzeros(nt, nt)
  608. else
  609. nt_pressure = ni + nb
  610. AϕL = spzeros(nt_pressure, nt_pressure)
  611. rhs_phi = zeros(nt_pressure)
  612. end
  613. if electrolysis
  614. # Aphi_eleL = spzeros(nt, nt)
  615. # coeffDu = zeros(grid_u)
  616. # coeffDv = zeros(grid_v)
  617. coeffDx_interface = zeros(grid_u)
  618. coeffDy_interface = zeros(grid_v)
  619. end
  620. if num.solve_solid == 1
  621. ATS = spzeros(nt, nt)
  622. BTS = spzeros(nt, nt)
  623. end
  624. ATL = spzeros(nt, nt)
  625. BTL = spzeros(nt, nt)
  626. ni = grid_u.nx * grid_u.ny
  627. nb = 2 * grid_u.nx + 2 * grid_u.ny
  628. nt = (num.nLS + 1) * ni + nb
  629. if num.solve_solid == 1
  630. AuS = spzeros(nt, nt)
  631. BuS = spzeros(nt, nt)
  632. end
  633. AuL = spzeros(nt, nt)
  634. BuL = spzeros(nt, nt)
  635. ni = grid_v.nx * grid_v.ny
  636. nb = 2 * grid_v.nx + 2 * grid_v.ny
  637. nt = (num.nLS + 1) * ni + nb
  638. if ns_solid_phase
  639. AvS = spzeros(nt, nt)
  640. BvS = spzeros(nt, nt)
  641. end
  642. AvL = spzeros(nt, nt)
  643. BvL = spzeros(nt, nt)
  644. #region Allocate for Navier case
  645. ni = grid_u.nx * grid_u.ny + grid_v.nx * grid_v.ny
  646. nb = 2 * grid_u.nx + 2 * grid_u.ny + 2 * grid_v.nx + 2 * grid_v.ny
  647. nt = (num.nLS - num.nNavier + 1) * ni + num.nNavier * grid_p.nx * grid_p.ny + nb
  648. #dev was done with nNavier == ?
  649. #when no Navier: nt = (num.nLS + 1) * ni + nb
  650. # if ((num.one_fluid_model == 1 && num.solve_Navier_Stokes_liquid_phase == 1) && num.pressure_velocity_coupling != 0)
  651. # @error("\nCoupled pressure velocity + one-fluid model error")
  652. # return
  653. # end
  654. if (num.one_fluid_model == 1 && num.solve_Navier_Stokes_liquid_phase == 1)
  655. rho_one_fluid = zeros(grid_p)
  656. mu_one_fluid = zeros(grid_p)
  657. volume_fraction = zeros(grid_p)
  658. interface_length = zeros(grid_p)
  659. levelset_one_fluid = zeros(grid_p)
  660. rho_one_fluid_u = zeros(grid_u)
  661. # mu_one_fluid_u = zeros(grid_u)
  662. rho_one_fluid_v = zeros(grid_v)
  663. # mu_one_fluid_v = zeros(grid_v)
  664. volumic_surface_tension_u = zeros(grid_u)
  665. volumic_surface_tension_v = zeros(grid_v)
  666. # Pre-allocate arrays
  667. levelset_1D = fnzeros(grid_p, num)
  668. levelset_heavyside_2D = zeros(grid_p)
  669. convection_u = fzeros(grid_u)
  670. convection_v = fzeros(grid_v)
  671. viscosity_coeff_for_du_dx = zeros(grid_u.ny, grid_u.nx+1)
  672. viscosity_coeff_for_du_dy = zeros(grid_u.ny+1, grid_u.nx)
  673. viscosity_coeff_for_dv_dx = zeros(grid_v.ny, grid_v.nx+1)
  674. viscosity_coeff_for_dv_dy = zeros(grid_v.ny+1, grid_v.nx)
  675. velocity_and_BC_convection_u_x = zeros(grid_u) #Du_x
  676. velocity_and_BC_convection_u_y = zeros(grid_u)
  677. velocity_and_BC_convection_v_x = zeros(grid_v)
  678. velocity_and_BC_convection_v_y = zeros(grid_v)
  679. else
  680. volume_fraction = nothing
  681. interface_length = nothing
  682. end
  683. if (num.pressure_velocity_coupling == 0 && num.one_fluid_model == 0)
  684. if ns_solid_phase
  685. AuvS = spzeros(nt, nt)
  686. BuvS = spzeros(nt, nt)
  687. end
  688. AuvL = spzeros(nt, nt)
  689. BuvL = spzeros(nt, nt)
  690. else
  691. # We solve for u, v with borders
  692. # dev was done with nNavier == ?
  693. ni_p = grid_p.nx * grid_p.ny
  694. nb_p = 2 * grid_p.nx + 2 * grid_p.ny
  695. ni_u = grid_u.nx * grid_u.ny
  696. nb_u = 2 * grid_u.nx + 2 * grid_u.ny
  697. ni_v = grid_v.nx * grid_v.ny
  698. nb_v = 2 * grid_v.nx + 2 * grid_v.ny
  699. ni_uv = ni_u + ni_v
  700. nb_uv = nb_u + nb_v
  701. if num.pressure_velocity_coupling == 0
  702. if (num.one_fluid_model == 1 && num.solve_Navier_Stokes_liquid_phase == 1)
  703. nt = ni_uv + nb_uv
  704. ncol_A = ni_uv + nb_uv
  705. else
  706. nt = (num.nLS - num.nNavier + 1) * ni_uv + num.nNavier * ni_p + nb_uv
  707. ncol_A = (num.nLS - num.nNavier + 1) * ni_uv + num.nNavier * ni_p + nb_uv
  708. end
  709. AuvL = spzeros(ncol_A, nt)
  710. BuvL = spzeros(ncol_A, nt)
  711. rhs_uv = zeros(ncol_A)
  712. # AϕL = spzeros(nt, nt)
  713. elseif num.pressure_velocity_coupling == 1
  714. nt = (num.nLS - num.nNavier + 1) * ni_uv + num.nNavier * ni_p + nb_uv + (num.nLS + 1) * ni_p + nb_p
  715. ncol_A = (num.nLS - num.nNavier + 1) * ni_uv + num.nNavier * ni_p + nb_uv + ni_p
  716. # so 1 * ni + 1 * ni_p +nb + ni_p + nb
  717. # u v Navier, pression
  718. # AuvL = spzeros(nt, nt)
  719. # BuvL = spzeros(nt, nt)
  720. AuvL = spzeros(ncol_A, nt)
  721. BuvL = spzeros(ncol_A, nt)
  722. rhs_uv = zeros(ncol_A)
  723. elseif num.pressure_velocity_coupling == 2
  724. nt = (num.nLS - num.nNavier + 1) * ni_uv + num.nNavier * ni_p + nb_uv + (num.nLS + 1) * ni_p + nb_p
  725. ncol_A = nt
  726. # so 1 * ni + 1 * ni_p +nb + ni_p + nb
  727. # u v Navier, pression
  728. # AuvL = spzeros(nt, nt)
  729. # BuvL = spzeros(nt, nt)
  730. AuvL = spzeros(ncol_A, nt)
  731. BuvL = spzeros(ncol_A, nt)
  732. rhs_uv = zeros(ncol_A)
  733. elseif num.pressure_velocity_coupling == 3 #no BC for pressure
  734. if (num.one_fluid_model == 1 && num.solve_Navier_Stokes_liquid_phase == 1)
  735. nt = ni_uv + nb_uv + ni_p
  736. ncol_A = ni_uv + nb_uv + ni_p
  737. else
  738. nt = (num.nLS - num.nNavier + 1) * ni_uv + num.nNavier * ni_p + nb_uv + ni_p
  739. ncol_A = nt
  740. end
  741. AuvL = spzeros(ncol_A, nt)
  742. BuvL = spzeros(ncol_A, nt)
  743. rhs_uv = zeros(ncol_A)
  744. # AϕL = spzeros(nt, nt)
  745. elseif num.pressure_velocity_coupling == 4 # BC for pressure on interfaces (bubble)
  746. n_phase = 2
  747. nt = n_phase * ((num.nLS - num.nNavier + 1) * ni_uv + num.nNavier * ni_p + (num.nLS + 1) * ni_p ) + nb_uv
  748. ncol_A = nt
  749. # so 1 * ni + 1 * ni_p +nb + ni_p + nb
  750. # u v Navier, pression
  751. # AuvL = spzeros(nt, nt)
  752. # BuvL = spzeros(nt, nt)
  753. AuvL = spzeros(ncol_A, nt)
  754. BuvL = spzeros(ncol_A, nt)
  755. rhs_uv = zeros(ncol_A)
  756. # elseif num.pressure
  757. end
  758. end
  759. #endregion Allocate for Navier case
  760. #endregion Allocations
  761. #TODO remove allocations
  762. # Adapt cell volume W for gradients
  763. # cf 4/3 factor for Laplacian
  764. if num.laplacian == 1
  765. AvLcopy = copy(AvL)
  766. Lvm1_L,bc_Lvm1_L,bc_Lvm1_b_L=compute_divergence!(num,
  767. # grid_p,
  768. # grid_u,
  769. grid_v,
  770. op.opC_vL,
  771. AvLcopy,
  772. # rhs_scal,
  773. # tmp_vec_p, #a0
  774. tmp_vec_1D_v0,
  775. tmp_vec_1D_v,
  776. Lvm1_L,
  777. bc_Lvm1_L,
  778. bc_Lvm1_b_L
  779. # tmp_vec_u0,
  780. # tmp_vec_v0,
  781. # tmp_vec_1D,
  782. # ls_advection
  783. )
  784. ApLcopy = copy(Ascal)
  785. Lpm1_L,bc_Lpm1_L,bc_Lpm1_b_L=compute_divergence!(num,
  786. # grid_p,
  787. # grid_u,
  788. grid_p,
  789. op.opC_pL,
  790. ApLcopy,
  791. # rhs_scal,
  792. # tmp_vec_p, #a0
  793. tmp_vec_1D_p0,
  794. tmp_vec_1D_p,
  795. Lpm1_L,
  796. bc_Lpm1_L,
  797. bc_Lpm1_b_L
  798. # tmp_vec_u0,
  799. # tmp_vec_v0,
  800. # tmp_vec_1D,
  801. # ls_advection
  802. )
  803. end
  804. if num.pressure_velocity_coupling == 0
  805. #TODO why this call without interface initialization ?
  806. if !navier
  807. if (num.solve_solid == 1) && ns_solid_phase
  808. _ = FE_set_momentum(
  809. num, grid_u, op.opC_uS,
  810. AuS, BuS,
  811. iRe.*Lum1_S, iRe.*bc_Lum1_S, iRe.*bc_Lum1_b_S, Mum1_S, BC_uS,
  812. true
  813. )
  814. _ = FE_set_momentum(
  815. num, grid_v, op.opC_vS,
  816. AvS, BvS,
  817. iRe.*Lvm1_S, iRe.*bc_Lvm1_S, iRe.*bc_Lvm1_b_S, Mvm1_S, BC_vS,
  818. true
  819. )
  820. end
  821. else
  822. _ = FE_set_momentum_coupled(
  823. BC_int, num, grid_p, grid_u, grid_v,
  824. op.opC_pS, op.opC_uS, op.opC_vS,
  825. AuvS, BuvS,
  826. iRe.*Lum1_S, iRe.*bc_Lum1_S, iRe.*bc_Lum1_b_S, Mum1_S, BC_uS,
  827. iRe.*Lvm1_S, iRe.*bc_Lvm1_S, iRe.*bc_Lvm1_b_S, Mvm1_S, BC_vS,
  828. true
  829. )
  830. end
  831. elseif num.pressure_velocity_coupling > 1
  832. if num.pressure_velocity_coupling == 4
  833. # Coupled resolution of u and v, going to two-phases for pressure
  834. _ = FE_set_momentum_coupled_two_phases(
  835. BC_int, num, grid_p, grid_u, grid_v,
  836. op,
  837. AuvL, BuvL,rhs_uv,
  838. iRe.*Lum1_L, iRe.*bc_Lum1_L, iRe.*bc_Lum1_b_L, Mum1_L, BC_uL,
  839. iRe.*Lvm1_L, iRe.*bc_Lvm1_L, iRe.*bc_Lvm1_b_L, Mvm1_L, BC_vL,
  840. iRe.*Lum1_S, iRe.*bc_Lum1_S, iRe.*bc_Lum1_b_S, Mum1_S, BC_uS,
  841. iRe.*Lvm1_S, iRe.*bc_Lvm1_S, iRe.*bc_Lvm1_b_S, Mvm1_S, BC_vS,
  842. true,BC_pL,phL,phS
  843. )
  844. else
  845. if (num.one_fluid_model == 1 && num.solve_Navier_Stokes_liquid_phase == 1)
  846. # _ = FE_set_momentum_coupled2_one_fluid(
  847. # BC_int, num, grid_p, grid_u, grid_v,
  848. # op.opC_pL, op.opC_uL, op.opC_vL,
  849. # AuvL, BuvL,rhs_uv,
  850. # diffusion_bulk_u, diffusion_LS_u, diffusion_border_u, Mum1, BC_uL,
  851. # diffusion_bulk_v, diffusion_LS_v, diffusion_border_v, Mvm1, BC_vL,
  852. # cross_term_diffusion_bulk_d_dv_dx_dy,cross_term_diffusion_bulk_d_du_dy_dx,
  853. # cross_term_diffusion_bulk_d_dv_dx_dy_border,cross_term_diffusion_bulk_d_du_dy_dx_border,
  854. # rho_one_fluid_u,rho_one_fluid_v,
  855. # true,
  856. # BC_pL,phL
  857. # )
  858. else
  859. # Coupled resolution of u and v
  860. _ = FE_set_momentum_coupled2(
  861. BC_int, num, grid_p, grid_u, grid_v,
  862. op.opC_pL, op.opC_uL, op.opC_vL,
  863. AuvL, BuvL,rhs_uv,
  864. iRe.*Lum1_L, iRe.*bc_Lum1_L, iRe.*bc_Lum1_b_L, Mum1_L, BC_uL,
  865. iRe.*Lvm1_L, iRe.*bc_Lvm1_L, iRe.*bc_Lvm1_b_L, Mvm1_L, BC_vL,
  866. true,BC_pL,phL
  867. )
  868. end
  869. end
  870. end
  871. #TODO remove alloc a0_p
  872. a0_p = []
  873. for i in 1:num.nLS
  874. push!(a0_p, zeros(grid_p))
  875. end
  876. if !advection && (num.solve_solid == 1)
  877. #call to set_heat! is there to set up the matrices for the heat equation.
  878. #If the level-set is not advected, then after this call there is no need to update these matrices anymore
  879. _ = set_poisson(
  880. BC_int, num, grid_p, a0_p, op.opC_pS, op.opC_uS, op.opC_vS,
  881. AϕS, Lpm1_S, bc_Lpm1_S, bc_Lpm1_b_S, BC_pS,
  882. true
  883. )
  884. set_heat!(
  885. BC_int[1], num, grid_p, op.opC_TS, grid_p.LS[1].geoS, phS, num.θd, BC_TS, grid_p.LS[1].MIXED, grid_p.LS[1].geoS.projection,
  886. ATS, BTS,rhs_scal,
  887. op.opS, grid_u, grid_u.LS[1].geoS, grid_v, grid_v.LS[1].geoS,
  888. periodic_x, periodic_y, heat_convection, true, BC_int
  889. )
  890. end
  891. if test_laplacian
  892. num.exact_laplacian = test_laplacian_pressure(num,grid_v,phL.vD,op.opC_pL, Lvm1_L, bc_Lvm1_L, bc_Lvm1_b_L)
  893. return
  894. end
  895. # Segregated resolution for u and v since the viscosity is assumed to be constant in a phase
  896. if num.pressure_velocity_coupling == 0
  897. if !navier
  898. _ = FE_set_momentum(
  899. num, grid_u, op.opC_uL,
  900. AuL, BuL,
  901. iRe.*Lum1_L, iRe.*bc_Lum1_L, iRe.*bc_Lum1_b_L, Mum1_L, BC_uL,
  902. true
  903. )
  904. _ = FE_set_momentum(
  905. num, grid_v, op.opC_vL,
  906. AvL, BvL,
  907. iRe.*Lvm1_L, iRe.*bc_Lvm1_L, iRe.*bc_Lvm1_b_L, Mvm1_L, BC_vL,
  908. true
  909. )
  910. else
  911. # Coupled resolution of u and v if navier BC is activated
  912. _ = FE_set_momentum_coupled(
  913. BC_int, num, grid_p, grid_u, grid_v,
  914. op.opC_pL, op.opC_uL, op.opC_vL,
  915. AuvL, BuvL,
  916. iRe.*Lum1_L, iRe.*bc_Lum1_L, iRe.*bc_Lum1_b_L, Mum1_L, BC_uL,
  917. iRe.*Lvm1_L, iRe.*bc_Lvm1_L, iRe.*bc_Lvm1_b_L, Mvm1_L, BC_vL,
  918. true
  919. )
  920. end
  921. elseif num.pressure_velocity_coupling > 1
  922. if (num.one_fluid_model == 1 && num.solve_Navier_Stokes_liquid_phase == 1)
  923. # _ = FE_set_momentum_coupled2_one_fluid(
  924. # BC_int, num, grid_p, grid_u, grid_v,
  925. # op.opC_pL, op.opC_uL, op.opC_vL,
  926. # AuvL, BuvL,rhs_uv,
  927. # diffusion_bulk_u, diffusion_LS_u, diffusion_border_u, Mum1, BC_uL,
  928. # diffusion_bulk_v, diffusion_LS_v, diffusion_border_v, Mvm1, BC_vL,
  929. # cross_term_diffusion_bulk_d_dv_dx_dy,cross_term_diffusion_bulk_d_du_dy_dx,
  930. # cross_term_diffusion_bulk_d_dv_dx_dy_border,cross_term_diffusion_bulk_d_du_dy_dx_border,
  931. # rho_one_fluid_u,rho_one_fluid_v,
  932. # true,
  933. # BC_pL,phL
  934. # )
  935. else
  936. # Coupled resolution of u and v
  937. _ = FE_set_momentum_coupled2(
  938. BC_int, num, grid_p, grid_u, grid_v,
  939. op.opC_pL, op.opC_uL, op.opC_vL,
  940. AuvL, BuvL,rhs_uv,
  941. iRe.*Lum1_L, iRe.*bc_Lum1_L, iRe.*bc_Lum1_b_L, Mum1_L, BC_uL,
  942. iRe.*Lvm1_L, iRe.*bc_Lvm1_L, iRe.*bc_Lvm1_b_L, Mvm1_L, BC_vL,
  943. true,BC_pL,phL
  944. )
  945. end #one-fluid
  946. end
  947. a0_p = []
  948. for i in 1:num.nLS
  949. push!(a0_p, zeros(grid_p))
  950. end
  951. if num.one_fluid_model == 0
  952. _ = set_poisson(
  953. BC_int, num, grid_p, a0_p, op.opC_pL, op.opC_uL, op.opC_vL,
  954. AϕL, Lpm1_L, bc_Lpm1_L, bc_Lpm1_b_L, BC_pL,
  955. true
  956. )
  957. else
  958. _ = set_poisson_one_fluid(
  959. BC_int, num, grid_p, a0_p, op.opC_pL, op.opC_uL, op.opC_vL,
  960. AϕL, Lpm1_L, bc_Lpm1_L, bc_Lpm1_b_L, BC_pL,
  961. true
  962. )
  963. end
  964. if num.nLS>1 #monophasic
  965. #call to set_heat! is there to set up the matrices for the heat equation.
  966. #If the level-set is not advected, then after this call there is no need to update these matrices anymore
  967. set_heat!(
  968. BC_int[1], num, grid_p, op.opC_TL, grid_p.LS[1].geoL, phL, num.θd, BC_TL, grid_p.LS[1].MIXED, grid_p.LS[1].geoL.projection,
  969. ATL, BTL,rhs_scal,
  970. op.opL, grid_u, grid_u.LS[1].geoL, grid_v, grid_v.LS[1].geoL,
  971. periodic_x, periodic_y, heat_convection, true, BC_int
  972. )
  973. end
  974. end
  975. else
  976. error("Unknown time scheme. Available options are ForwardEuler and CrankNicolson")
  977. end
  978. if heat_convection || electrolysis_convection
  979. NB_indices = update_all_ls_data(num, grid_p, grid_u, grid_v, BC_int, periodic_x, periodic_y)
  980. # println(grid_p.LS[1].geoL.dcap[1,1,:])
  981. end
  982. # V0S = volume(grid_p.LS[end].geoS)
  983. # V0L = volume(grid_p.LS[end].geoL)
  984. if num.debug == "allocations_start"
  985. print("\n STOP allocations")
  986. return
  987. end
  988. #region restart
  989. # - file: decl_hdf5_test_02_r${rank}.h5
  990. # when: $input=1
  991. # read: [ reals, values ]
  992. PDI_status = @ccall "libpdi".PDI_multi_expose("restart"::Cstring,
  993. "nstep"::Cstring, num.current_iter::Ref{Clonglong}, PDI_OUT::Cint,
  994. "time"::Cstring, num.time::Ref{Cdouble}, PDI_OUT::Cint,
  995. "timestep"::Cstring, num.timestep_n::Ref{Cdouble}, PDI_OUT::Cint,
  996. "nx"::Cstring, grid_p.nx::Ref{Clonglong}, PDI_OUT::Cint,
  997. "ny"::Cstring, grid_p.ny::Ref{Clonglong}, PDI_OUT::Cint,
  998. "u_1D"::Cstring, phL.uD::Ptr{Cdouble}, PDI_OUT::Cint,
  999. "v_1D"::Cstring, phL.vD::Ptr{Cdouble}, PDI_OUT::Cint,
  1000. "p_1D"::Cstring, phL.pD::Ptr{Cdouble}, PDI_OUT::Cint,
  1001. "levelset_p"::Cstring, grid_p.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  1002. "levelset_u"::Cstring, grid_u.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  1003. "levelset_v"::Cstring, grid_v.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  1004. "trans_scal_1DT"::Cstring, phL.trans_scalD'::Ptr{Cdouble}, PDI_OUT::Cint,
  1005. "phi_ele_1D"::Cstring, phL.phi_eleD::Ptr{Cdouble}, PDI_OUT::Cint,
  1006. "velocity_x"::Cstring, tmp_vec_p::Ptr{Cdouble}, PDI_OUT::Cint,
  1007. "velocity_y"::Cstring, tmp_vec_p0::Ptr{Cdouble}, PDI_OUT::Cint,
  1008. "radius"::Cstring, num.current_radius::Ref{Cdouble}, PDI_OUT::Cint,
  1009. C_NULL::Ptr{Cvoid})::Cint
  1010. #endregion restart
  1011. interpolate_staggered_u_v_to_scalar_grid_one_fluid_or_one_phase!(num,grid_p,grid_u,grid_v,phL.u,phL.v,tmp_vec_p,tmp_vec_p0)
  1012. PDI_status = @ccall "libpdi".PDI_multi_expose("write_data"::Cstring,
  1013. "nstep"::Cstring, num.current_iter::Ref{Clonglong}, PDI_OUT::Cint,
  1014. "time"::Cstring, num.time::Ref{Cdouble}, PDI_OUT::Cint,
  1015. "timestep"::Cstring, num.timestep_n::Ref{Cdouble}, PDI_OUT::Cint,
  1016. "nx"::Cstring, grid_p.nx::Ref{Clonglong}, PDI_OUT::Cint,
  1017. "ny"::Cstring, grid_p.ny::Ref{Clonglong}, PDI_OUT::Cint,
  1018. "u_1D"::Cstring, phL.uD::Ptr{Cdouble}, PDI_OUT::Cint,
  1019. "v_1D"::Cstring, phL.vD::Ptr{Cdouble}, PDI_OUT::Cint,
  1020. "p_1D"::Cstring, phL.pD::Ptr{Cdouble}, PDI_OUT::Cint,
  1021. "levelset_p"::Cstring, grid_p.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  1022. "levelset_u"::Cstring, grid_u.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  1023. "levelset_v"::Cstring, grid_v.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  1024. "trans_scal_1DT"::Cstring, phL.trans_scalD'::Ptr{Cdouble}, PDI_OUT::Cint,
  1025. "phi_ele_1D"::Cstring, phL.phi_eleD::Ptr{Cdouble}, PDI_OUT::Cint,
  1026. "velocity_x"::Cstring, tmp_vec_p::Ptr{Cdouble}, PDI_OUT::Cint,
  1027. "velocity_y"::Cstring, tmp_vec_p0::Ptr{Cdouble}, PDI_OUT::Cint,
  1028. "radius"::Cstring, num.current_radius::Ref{Cdouble}, PDI_OUT::Cint,
  1029. C_NULL::Ptr{Cvoid})::Cint
  1030. #compute numerical radius
  1031. PDI_status = @ccall "libpdi".PDI_multi_expose("compute_radius"::Cstring,
  1032. "levelset_p"::Cstring, grid_p.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  1033. "mesh_p_x"::Cstring, grid_p.x::Ptr{Cdouble}, PDI_OUT::Cint,
  1034. "mesh_p_y"::Cstring, grid_p.y::Ptr{Cdouble}, PDI_OUT::Cint,
  1035. "radius_vec"::Cstring, radius_pdi::Ptr{Cdouble}, PDI_INOUT::Cint,
  1036. C_NULL::Ptr{Cvoid})::Cint
  1037. num.current_radius = radius_pdi[1]
  1038. print("\n radius pdi ", radius_pdi[1])
  1039. # slice = levelset_p[nx//2,:]
  1040. # x_1D = mesh_p_y[nx//2,:]
  1041. # try
  1042. # radius_vertical = compute_radius_from_levelset_slice(grid_p.LS[num.iLSpdi].u[:,div(grid_p.nx,2)],
  1043. # grid_p.y[:,div(grid_p.nx,2)])
  1044. # # catch error
  1045. # # volume_cell = grid_p.LS[num.iLSpdi].geoS.cap[:,:,5] #bubble
  1046. # volume_cell = grid_p.LS[num.iLSpdi].geoL.cap[:,:,5] #drop
  1047. # center_of_mass_x, center_of_mass_y = calculate_centroid(grid_p.x, grid_p.y, volume_cell)
  1048. # indices_bubble_mass_center = find_slice_coord_bubble_mass_center(center_of_mass_x,center_of_mass_y,
  1049. # num,grid_p)
  1050. # radius_horizontal = compute_radius_from_levelset_slice(grid_p.LS[num.iLSpdi].u[indices_bubble_mass_center[1],:],
  1051. # grid_p.y[indices_bubble_mass_center[1],:])
  1052. # if isnothing(radius_vertical)
  1053. # print("\n error radius vertical")
  1054. # if isnothing(radius_horizontal)
  1055. # print("\n error radius horizontal and vertical")
  1056. # else
  1057. # num.current_radius = radius_horizontal
  1058. # end
  1059. # else
  1060. # if isnothing(radius_horizontal)
  1061. # print("\n error radius horizontal")
  1062. # else
  1063. # num.current_radius = max(radius_horizontal, radius_vertical)
  1064. # end
  1065. # end
  1066. # # end
  1067. # num.current_radius = maximum(compute_radii_from_slices(
  1068. # grid_p.LS[num.iLSpdi].u,
  1069. # x_grid::AbstractMatrix,
  1070. # y_grid::AbstractMatrix,
  1071. # slices::Vector{Tuple{Union{Int, Colon}, Union{Int, Colon}}};
  1072. # center_x,center_y)
  1073. if num.sphere_post_processing == 1
  1074. compute_bubble_drop_radius(num, grid_p)
  1075. end
  1076. if (num.one_fluid_model == 1 && num.solve_Navier_Stokes_liquid_phase == 1 && num.solve_Navier_Stokes == 1)
  1077. # rise_velocity_y =0.0
  1078. # PDI_status = @ccall "libpdi".PDI_multi_expose("post_processing_rising_bubble_first_share"::Cstring,
  1079. # "nstep"::Cstring, num.current_iter ::Ref{Clonglong}, PDI_OUT::Cint,
  1080. # # "rho_one_fluid"::Cstring, rho_one_fluid::Ptr{Cdouble}, PDI_OUT::Cint,
  1081. # # "rho_one_fluid_u"::Cstring, rho_one_fluid_u::Ptr{Cdouble}, PDI_OUT::Cint,
  1082. # # "rho_one_fluid_v"::Cstring, rho_one_fluid_v::Ptr{Cdouble}, PDI_OUT::Cint,
  1083. # # "mu_one_fluid"::Cstring, mu_one_fluid::Ptr{Cdouble}, PDI_OUT::Cint,
  1084. # "rise_velocity_y"::Cstring, rise_velocity_y::Ref{Cdouble}, PDI_OUT::Cint,
  1085. # "timestep"::Cstring, num.timestep_n::Ref{Cdouble}, PDI_OUT::Cint,
  1086. # # "volume_fraction"::Cstring, volume_fraction::Ptr{Cdouble}, PDI_OUT::Cint,
  1087. # # "volume_cell"::Cstring, grid_p.LS[end].geoS.dcap[:,:,5]::Ptr{Cdouble}, PDI_OUT::Cint, #geoS for bubble phase
  1088. # # "mesh_p_x"::Cstring, grid_p.x::Ptr{Cdouble}, PDI_OUT::Cint,
  1089. # # "mesh_p_y"::Cstring, grid_p.y::Ptr{Cdouble}, PDI_OUT::Cint,
  1090. # # "dcap_1"::Cstring, grid_p.LS[num.iLSpdi].geoS.dcap[:,:,1]::Ptr{Cdouble}, PDI_OUT::Cint, #geoS for bubble phase
  1091. # # "dcap_2"::Cstring, grid_p.LS[num.iLSpdi].geoS.dcap[:,:,2]::Ptr{Cdouble}, PDI_OUT::Cint, #geoS for bubble phase
  1092. # # "dcap_3"::Cstring, grid_p.LS[num.iLSpdi].geoS.dcap[:,:,3]::Ptr{Cdouble}, PDI_OUT::Cint, #geoS for bubble phase
  1093. # # "dcap_4"::Cstring, grid_p.LS[num.iLSpdi].geoS.dcap[:,:,4]::Ptr{Cdouble}, PDI_OUT::Cint, #geoS for bubble phase
  1094. # C_NULL::Ptr{Cvoid})::Cint
  1095. update_one_fluid_density_viscosity(num,grid_p,grid_u,grid_v,volume_fraction,levelset_one_fluid,rho_one_fluid,
  1096. rho_one_fluid_u,rho_one_fluid_v,mu_one_fluid,tmp_vec_p0)
  1097. # PDI_status = @ccall "libpdi".PDI_multi_expose("print_timestep"::Cstring,
  1098. # "nstep"::Cstring, num.current_iter ::Ref{Clonglong}, PDI_OUT::Cint,
  1099. # "time"::Cstring, num.time::Ref{Cdouble}, PDI_OUT::Cint,
  1100. # "timestep"::Cstring, num.timestep_n::Ref{Cdouble}, PDI_OUT::Cint,
  1101. # C_NULL::Ptr{Cvoid})::Cint
  1102. # #region initial values
  1103. # PDI_status = @ccall "libpdi".PDI_multi_expose("post_processing_rising_bubble"::Cstring,
  1104. # #endregion initial values
  1105. end
  1106. if num.one_fluid_model == 1 && num.solve_Navier_Stokes == 1
  1107. conservation = compute_conservation_mass(num,phL, grid_p ,grid_u, grid_v, rho_one_fluid)
  1108. else
  1109. conservation = 0 # TODO
  1110. end
  1111. # Compute divergence of velocity
  1112. Duv = op.opC_pL.AxT * vec1(phL.uD,grid_u) .+ op.opC_pL.Gx_b * vecb(phL.uD,grid_u) .+
  1113. op.opC_pL.AyT * vec1(phL.vD,grid_v) .+ op.opC_pL.Gy_b * vecb(phL.vD,grid_v)
  1114. for iLS in 1:num.nLS
  1115. if !is_navier(BC_int[iLS]) && !is_navier_cl(BC_int[iLS]) #otherwise normal velocity null if no blowing
  1116. Duv .+= op.opC_pL.Gx[iLS] * veci(phL.uD,grid_u,iLS+1) .+
  1117. op.opC_pL.Gy[iLS] * veci(phL.vD,grid_v,iLS+1)
  1118. end
  1119. end
  1120. if num.solve_Navier_Stokes == 1 && num.solve_Navier_Stokes == 1
  1121. PDI_status = @ccall "libpdi".PDI_multi_expose("print_conservation"::Cstring,
  1122. "nstep"::Cstring, num.current_iter::Ref{Clonglong}, PDI_OUT::Cint,
  1123. "conservation"::Cstring, conservation::Ref{Cdouble}, PDI_OUT::Cint,
  1124. "velocity_divergence"::Cstring, Duv::Ptr{Cdouble}, PDI_OUT::Cint,
  1125. # "p_1D"::Cstring, phL.pD::Ptr{Cdouble}, PDI_OUT::Cint,
  1126. C_NULL::Ptr{Cvoid})::Cint
  1127. #save initialised electrical potential and current (iter 0)
  1128. if num.electrical_potential>0
  1129. compute_grad_phi_ele!(num, grid_p, grid_u, grid_v, grid_u.LS[end], grid_v.LS[end], phL,
  1130. op.opC_pL, elec_cond,tmp_vec_u,tmp_vec_v,tmp_vec_p,tmp_vec_p0,tmp_vec_p1) #TODO current
  1131. end
  1132. # PDI_status = @ccall "libpdi".PDI_multi_expose("check_conservation"::Cstring,
  1133. # "nstep"::Cstring, num.current_iter::Ref{Clonglong}, PDI_OUT::Cint,
  1134. # "conservation"::Cstring, conservation::Ref{Cdouble}, PDI_OUT::Cint,
  1135. # "velocity_divergence"::Cstring, Duv::Ptr{Cdouble}, PDI_OUT::Cint,
  1136. # "u_1D"::Cstring, phL.uD::Ptr{Cdouble}, PDI_OUT::Cint,
  1137. # "v_1D"::Cstring, phL.vD::Ptr{Cdouble}, PDI_OUT::Cint,
  1138. # "p_1D"::Cstring, phL.pD::Ptr{Cdouble}, PDI_OUT::Cint,
  1139. # C_NULL::Ptr{Cvoid})::Cint
  1140. end
  1141. simulation_finished = false
  1142. #TODO variable time steps
  1143. #region time loop
  1144. while (num.current_iter < num.max_iterations + 1) && (num.time < num.end_time) && (num.stop_simulation == 0)
  1145. #update time
  1146. num.time += num.timestep_n
  1147. num.current_iter += 1
  1148. #region start iter
  1149. #region Adapt timestep
  1150. num.timestep_n = adapt_timestep!(num, phL, phS, grid_u, grid_v,adapt_timestep_mode)
  1151. # printstyled(color=:green, @sprintf "\n num.CFL : %.2e dt : %.2e num.timestep_n : %.2e\n" num.CFL num.timestep_n num.timestep_n)
  1152. # print("\n num.stop_simulation start loop ",num.stop_simulation)
  1153. #endregion adapt time
  1154. if grid_p.LS[1].geoL.dcap[1,1,:] == 0.0
  1155. printstyled(color=:red, @sprintf "\n Error operator null \n")
  1156. return
  1157. end
  1158. # Print information at the start of temporal iteration and check definition of operators
  1159. # cf update_all_ls_data (true VS false)
  1160. PDI_status = @ccall "libpdi".PDI_multi_expose("print_start_temporal_iteration"::Cstring,
  1161. "nstep"::Cstring, num.current_iter::Ref{Clonglong}, PDI_OUT::Cint,
  1162. "time"::Cstring, num.time::Ref{Cdouble}, PDI_OUT::Cint,
  1163. # "levelset_p"::Cstring, grid_p.LS[num.index_levelset_pdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  1164. "dcap"::Cstring, grid_p.LS[num.index_levelset_pdi].geoL.dcap[:,:,:]::Ptr{Cdouble}, PDI_OUT::Cint,
  1165. # grid_p.LS[1].geoL.dcap[1,1,:]
  1166. C_NULL::Ptr{Cvoid})::Cint
  1167. # if num.io_pdi>0
  1168. # #or permutedims(grid_p.LS[num.iLSpdi].geoL.dcap, (3, 2, 1)) (3, 1, 2)
  1169. # try
  1170. # # num.iLSpdi = 1 # TODO all grid_p.LS
  1171. # PDI_status = @ccall "libpdi".PDI_multi_expose("write_capacities"::Cstring,
  1172. # # "dcap"::Cstring, permutedims(grid_p.LS[num.iLSpdi].geoL.dcap, (3, 2, 1))::Ptr{Cdouble}, PDI_OUT::Cint,
  1173. # "dcap_1"::Cstring, grid_p.LS[num.iLSpdi].geoL.dcap[:,:,1]::Ptr{Cdouble}, PDI_OUT::Cint,
  1174. # "dcap_2"::Cstring, grid_p.LS[num.iLSpdi].geoL.dcap[:,:,2]::Ptr{Cdouble}, PDI_OUT::Cint,
  1175. # "dcap_3"::Cstring, grid_p.LS[num.iLSpdi].geoL.dcap[:,:,3]::Ptr{Cdouble}, PDI_OUT::Cint,
  1176. # "dcap_4"::Cstring, grid_p.LS[num.iLSpdi].geoL.dcap[:,:,4]::Ptr{Cdouble}, PDI_OUT::Cint,
  1177. # C_NULL::Ptr{Cvoid})::Cint
  1178. # catch error
  1179. # printstyled(color=:red, @sprintf "\n PDI error \n")
  1180. # print(error)
  1181. # printstyled(color=:red, @sprintf "\n PDI error \n")
  1182. # end
  1183. # end #if io_pdi
  1184. #endregion start iter
  1185. # PDI (IO)
  1186. if electrolysis
  1187. #TODO not necessary to expose everything now for ex only grid_p.LS ? and the rest later
  1188. intfc_vtx_x,intfc_vtx_y,intfc_vtx_field,intfc_vtx_connectivities,intfc_vtx_num, intfc_seg_num = convert_interfacial_D_to_segments(num,grid_p,phL.TD,1,2)
  1189. #TODO when to write elec dat, ...
  1190. if num.io_pdi>0
  1191. try
  1192. # printstyled(color=:red, @sprintf "\n PDI test \n" )
  1193. # phi_array=phL.phi_ele #do not transpose since python row major
  1194. if num.electrical_potential > 0
  1195. # print("\n type of elec_cond ", typeof(elec_cond)," \n")
  1196. try
  1197. compute_grad_phi_ele!(num, grid_p, grid_u, grid_v,grid_u.LS[end], grid_v.LS[end],
  1198. phL,
  1199. # phS,
  1200. op.opC_pL,
  1201. # op.opC_pS,
  1202. elec_cond,tmp_vec_u,tmp_vec_v,tmp_vec_p,tmp_vec_p0,tmp_vec_p1) #TODO current
  1203. catch
  1204. @error("compute_grad_phi_ele!")
  1205. break
  1206. end
  1207. end
  1208. # #store in us, vs instead of Eus, Evs
  1209. # interpolate_grid_liquid!(grid_p,grid_u,grid_v,phL.Eu, phL.Ev,tmp_vec_p,tmp_vec_p0)
  1210. # @ccall "libpdi".PDI_multi_expose("write_data_elec"::Cstring,
  1211. # "i_current_x"::Cstring, tmp_vec_p::Ptr{Cdouble}, PDI_OUT::Cint,
  1212. # "i_current_y"::Cstring, tmp_vec_p0::Ptr{Cdouble}, PDI_OUT::Cint,
  1213. # "i_current_mag"::Cstring, phL.i_current_mag::Ptr{Cdouble}, PDI_OUT::Cint,
  1214. # "phi_ele_1D"::Cstring, phL.phi_eleD::Ptr{Cdouble}, PDI_OUT::Cint,
  1215. # C_NULL::Ptr{Cvoid})::Cint
  1216. interpolate_staggered_u_v_to_scalar_grid_one_fluid_or_one_phase!(num,grid_p,grid_u,grid_v,phL.u,phL.v,tmp_vec_p,tmp_vec_p0)
  1217. # print("\n before write \n ")
  1218. # num.iLSpdi = 1 # all grid_p.LS iLS = 1 # or all grid_p.LS ?
  1219. # Exposing data to PDI for IO
  1220. # if writing "D" array (bulk, interface, border), add "_1D" to the name
  1221. # printstyled(color=:magenta, @sprintf "\n PDI write_data_start_loop %.5i \n" num.current_iter)
  1222. PDI_status = @ccall "libpdi".PDI_multi_expose("write_data_start_loop"::Cstring,
  1223. "nstep"::Cstring, num.current_iter::Ref{Clonglong}, PDI_OUT::Cint,
  1224. "time"::Cstring, num.time::Ref{Cdouble}, PDI_OUT::Cint,
  1225. "u_1D"::Cstring, phL.uD::Ptr{Cdouble}, PDI_OUT::Cint,
  1226. "v_1D"::Cstring, phL.vD::Ptr{Cdouble}, PDI_OUT::Cint,
  1227. "p_1D"::Cstring, phL.pD::Ptr{Cdouble}, PDI_OUT::Cint,
  1228. "levelset_p"::Cstring, grid_p.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  1229. "levelset_u"::Cstring, grid_u.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  1230. "levelset_v"::Cstring, grid_v.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  1231. "trans_scal_1DT"::Cstring, phL.trans_scalD'::Ptr{Cdouble}, PDI_OUT::Cint,
  1232. "velocity_x"::Cstring, tmp_vec_p::Ptr{Cdouble}, PDI_OUT::Cint,
  1233. "velocity_y"::Cstring, tmp_vec_p0::Ptr{Cdouble}, PDI_OUT::Cint,
  1234. "radius"::Cstring, num.current_radius::Ref{Cdouble}, PDI_OUT::Cint,
  1235. "intfc_vtx_num"::Cstring, intfc_vtx_num::Ref{Clonglong}, PDI_OUT::Cint,
  1236. "intfc_seg_num"::Cstring, intfc_seg_num::Ref{Clonglong}, PDI_OUT::Cint,
  1237. "intfc_vtx_x"::Cstring, intfc_vtx_x::Ptr{Cdouble}, PDI_OUT::Cint,
  1238. "intfc_vtx_y"::Cstring, intfc_vtx_y::Ptr{Cdouble}, PDI_OUT::Cint,
  1239. "intfc_vtx_field"::Cstring, intfc_vtx_field::Ptr{Cdouble}, PDI_OUT::Cint,
  1240. "intfc_vtx_connectivities"::Cstring, intfc_vtx_connectivities::Ptr{Clonglong}, PDI_OUT::Cint,
  1241. C_NULL::Ptr{Cvoid})::Cint
  1242. catch error
  1243. printstyled(color=:red, @sprintf "\n PDI error \n")
  1244. print(error)
  1245. printstyled(color=:red, @sprintf "\n PDI error \n")
  1246. end
  1247. end #if io_pdi
  1248. end #if electrolysis
  1249. if !stefan
  1250. grid_p.V .= speed #*ones(grid_p.ny, grid_p.nx)
  1251. end
  1252. #region Heat equation
  1253. # Solve heat equation
  1254. if heat
  1255. if heat_solid_phase
  1256. kill_dead_cells!(phS.T, grid_p, grid_p.LS[1].geoS)
  1257. veci(phS.TD,grid_p,1) .= vec(phS.T)
  1258. set_heat!(
  1259. BC_int[1], num, grid_p, op.opC_TS, grid_p.LS[1].geoS, phS, num.θd, BC_TS, grid_p.LS[1].MIXED, grid_p.LS[1].geoS.projection,
  1260. ATS, BTS,rhs_scal,
  1261. op.opS, grid_u, grid_u.LS[1].geoS, grid_v, grid_v.LS[1].geoS,
  1262. periodic_x, periodic_y, heat_convection, advection, BC_int
  1263. )
  1264. mul!(rhs_scal, BTS, phS.TD, 1.0, 1.0)
  1265. phS.TD .= ATS \ rhs_scal
  1266. phS.T .= reshape(veci(phS.TD,grid_p,1), grid_p)
  1267. end
  1268. if heat_liquid_phase
  1269. kill_dead_cells!(phL.T, grid_p, grid_p.LS[1].geoL)
  1270. veci(phL.TD,grid_p,1) .= vec(phL.T)
  1271. set_heat!(
  1272. BC_int[1], num, grid_p, op.opC_TL, grid_p.LS[1].geoL, phL, num.θd, BC_TL, grid_p.LS[1].MIXED, grid_p.LS[1].geoL.projection,
  1273. ATL, BTL,rhs_scal,
  1274. op.opL, grid_u, grid_u.LS[1].geoL, grid_v, grid_v.LS[1].geoL,
  1275. periodic_x, periodic_y, heat_convection, advection, BC_int
  1276. )
  1277. mul!(rhs_scal, BTL, phL.TD, 1.0, 1.0)
  1278. phL.TD .= ATL \ rhs_scal
  1279. phL.T .= reshape(veci(phL.TD,grid_p,1), grid_p)
  1280. end
  1281. end # #if heat
  1282. #endregion heat equation
  1283. #region Electrolysis
  1284. #TODO scalar without electrical potential
  1285. if electrolysis && (num.solve_potential == 1 ) && (num.solve_species == 1)
  1286. if electrolysis_liquid_phase
  1287. #region Electrolysis: Poisson
  1288. if num.electrical_potential > 0
  1289. solve_poisson_loop!(num, grid_p, grid_u, grid_v, op, Ascal, rhs_scal,F_residual,
  1290. tmp_vec_p,tmp_vec_p0,tmp_vec_p1, a1_p, BC_phi_ele, phL, phS,elec_cond,
  1291. elec_condD, tmp_vec_u, tmp_vec_v, i_butler, ls_advection, heat)
  1292. end
  1293. #endregion Poisson
  1294. #TODO check BC not overwritten by different scalars
  1295. #TODO check ls advection true when num.n scalars
  1296. # print("\n vecb_L",vecb_L(phL.phi_eleD, grid_p))
  1297. # print("\n phL.phi_ele[:,1]",phL.phi_ele[:,1])
  1298. #TODO phL.phi_ele[:,1] or vecb_L(phL.phi_eleD, grid_p)
  1299. # we suppose phi(x=0)=... cf Khalighi
  1300. #but here BC
  1301. # New start scalar loop
  1302. #region velocity
  1303. # TODO
  1304. interpolate_interface_velocity!(phL,grid_u,grid_v)
  1305. #endregion velocity
  1306. #region Impose velocity
  1307. if imposed_velocity == "zero"
  1308. phL.u .= 0.0
  1309. phL.v .= 0.0
  1310. phL.uD .= 0.0
  1311. phL.vD .= 0.0
  1312. phL.p .= 0.0
  1313. phL.pD .= 0.0
  1314. elseif imposed_velocity == "constant"
  1315. #Required to modify whole uD vD
  1316. phL.u .= 0.0
  1317. phL.v .= BC_vL.bottom.val
  1318. phL.uD .= 0.0
  1319. phL.vD .= BC_vL.bottom.val
  1320. phL.pD .= 0.0
  1321. if ((num.current_iter-1)%show_every == 0)
  1322. printstyled(color=:red, @sprintf "\n Imposed velocity v min %.2e max %.2e\n" minimum(phL.vD) maximum(phL.vD))
  1323. printstyled(color=:red, @sprintf "\n Imposed velocity u min %.2e max %.2e\n" minimum(phL.uD) maximum(phL.uD))
  1324. end
  1325. elseif imposed_velocity == "Poiseuille_bottom_top"
  1326. vPoiseuille = Poiseuille_fmax.(grid_v.x,num.v_inlet,num.L0)
  1327. #Required to modify whole uD vD
  1328. phL.u .= 0.0
  1329. phL.v .= vPoiseuille
  1330. phL.uD .= 0.0 #Dirichlet and Neumann
  1331. # phL.vD .= BC_vL.bottom.val
  1332. # vecb...TODO
  1333. # ...
  1334. elseif imposed_velocity == "radial"
  1335. impose_radial_velocity(phS,phL,num)
  1336. end #imposed_velocity
  1337. #endregion Impose velocity
  1338. #region Update current
  1339. # if num.electrolysis_reaction == "Butler_no_concentration"
  1340. # update_electrical_current_from_Butler_Volmer!(num,grid_p,heat,phL.phi_eleD,i_butler;phL.T)
  1341. # # #TODO dev multiple levelsets
  1342. # # if heat
  1343. # # i_butler = butler_volmer_no_concentration.(num.alpha_a,num.alpha_c,num.Faraday,num.i0,vecb_L(phL.phi_eleD, grid_p),
  1344. # # num.phi_ele1,num.Ru,phL.T)
  1345. # # else
  1346. # # if num.nLS == 1
  1347. # # i_butler = butler_volmer_no_concentration.(num.alpha_a,num.alpha_c,num.Faraday,num.i0,vecb_L(phL.phi_eleD, grid_p),
  1348. # # num.phi_ele1,num.Ru,num.temperature0)
  1349. # # # else
  1350. # # #imposed by LS 2
  1351. # # # iLS_elec = 2
  1352. # # # i_butler = butler_volmer_no_concentration.(num.alpha_a,num.alpha_c,num.Faraday,num.i0,veci(phL.phi_eleD, grid_p,iLS_elec+1),
  1353. # # # num.phi_ele1,num.Ru,num.temperature0)
  1354. # # end
  1355. # # end
  1356. # end
  1357. # if num.electrolysis_reaction_symb in (:Butler_no_concentration, :fixed_current)
  1358. if num.electrolysis_reaction_symb === :Butler_no_concentration
  1359. # if num.verbosity>0
  1360. # print("\n electrode_definition_function ",electrode_definition_function)
  1361. # end
  1362. update_electrical_current_from_Butler_Volmer_func!(num,grid_p,heat,phL.phi_eleD,i_butler,electrode_definition_function;phL.T)
  1363. #if fixed do not update
  1364. end
  1365. #endregion Update current
  1366. #region Scalar transport: update boundary conditions
  1367. if num.nb_transported_scalars>0
  1368. # printstyled(color=:magenta, @sprintf "\n num.nb_transported_scalars %.5i " num.nb_transported_scalars)
  1369. for iscal=1:num.nb_transported_scalars
  1370. # @views kill_dead_cells_val!(phL.trans_scal[:,:,iscal], grid_p, grid_p.LS[1].geoL,0.0)
  1371. # @views kill_dead_cells_val!(phL.trans_scal[:,:,iscal], grid_p, grid_p.LS[1].geoL,num.concentration0[iscal])
  1372. if num.kill_dead_cells == 0
  1373. @views kill_dead_cells_val!(phL.trans_scal[:,:,iscal], grid_p, grid_p.LS[end].geoL,0.0)
  1374. else
  1375. @views kill_dead_cells_val!(phL.trans_scal[:,:,iscal], grid_p, grid_p.LS[end].geoL,num.concentration0[iscal])
  1376. end
  1377. @views veci(phL.trans_scalD[:,iscal],grid_p,1) .= vec(phL.trans_scal[:,:,iscal])
  1378. if num.nLS == 1
  1379. #BC for LS 2 in scalar transport : done in scalar loop
  1380. # if iscal==1 || iscal==2
  1381. # inv_stoechiometric_coeff = -1.0/2.0 #H2 and KOH
  1382. # elseif iscal == 3
  1383. # inv_stoechiometric_coeff = 1.0 #H2O consummed
  1384. # end
  1385. inv_stoechiometric_coeff = num.inv_stoechiometric_coeff[iscal]
  1386. if num.electrolysis_reaction_symb === :Butler_no_concentration
  1387. # BC at left wall
  1388. # -(-/i_butler) because i=-lambda grad phi and BC at left: -e_x
  1389. BC_trans_scal[iscal].left.val = i_butler./(num.Faraday*num.diffusion_coeff[iscal])*inv_stoechiometric_coeff
  1390. # debug
  1391. # for testn in 1:grid_p.ny
  1392. # printstyled(color=:green, @sprintf "\n jtmp : %.5i j : %.5i border %.5e\n" testn grid_p.ny-testn+1 vecb_L(phL.trans_scalD[:,iscal], grid_p)[testn])
  1393. # end
  1394. # elseif num.electrolysis_reaction_symb === :fixed_current && num.nLS == 1
  1395. #already initialised in convergence.jl
  1396. # print("\n scalar ", iscal, " ", BC_trans_scal[iscal].bottom.val)
  1397. # BC_trans_scal[iscal].bottom.val = i_butler./(num.Faraday*num.diffusion_coeff[iscal])*inv_stoechiometric_coeff
  1398. end
  1399. end
  1400. # if num.scalar_transport_implementation > 0
  1401. # printstyled(color=:red, @sprintf "\n scalar_transport_implementation")
  1402. # if num.time>num.nucleation_time
  1403. # BC_trans_scal[1].int = Dirichlet(val = num.concentration0[1])
  1404. # else
  1405. # BC_trans_scal[1].int = Neumann()
  1406. # print("\n BC_trans_scal[1].int ", BC_trans_scal[1].int )
  1407. # end
  1408. # end
  1409. end
  1410. #TODO convection_Cdivu BC divergence
  1411. #TODO check num.nb_transported_scalars>1
  1412. if ((num.current_iter-1)%show_every == 0)
  1413. # printstyled(color=:cyan, @sprintf "\n before scalar transport \n")
  1414. # print_electrolysis_statistics(num,grid_p,phL)
  1415. PDI_status = @ccall "libpdi".PDI_multi_expose("print_variables"::Cstring,
  1416. "nstep"::Cstring, num.current_iter::Ref{Clonglong}, PDI_OUT::Cint,
  1417. "time"::Cstring, num.time::Ref{Cdouble}, PDI_OUT::Cint,
  1418. "u_1D"::Cstring, phL.uD::Ptr{Cdouble}, PDI_OUT::Cint,
  1419. "v_1D"::Cstring, phL.vD::Ptr{Cdouble}, PDI_OUT::Cint,
  1420. "p_1D"::Cstring, phL.pD::Ptr{Cdouble}, PDI_OUT::Cint,
  1421. "levelset_p"::Cstring, grid_p.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  1422. "levelset_u"::Cstring, grid_u.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  1423. "levelset_v"::Cstring, grid_v.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  1424. "trans_scal_1DT"::Cstring, phL.trans_scalD'::Ptr{Cdouble}, PDI_OUT::Cint,
  1425. "phi_ele_1D"::Cstring, phL.phi_eleD::Ptr{Cdouble}, PDI_OUT::Cint,
  1426. C_NULL::Ptr{Cvoid})::Cint
  1427. end
  1428. # printstyled(color=:red, @sprintf "\n levelset: before scalar_transport\n")
  1429. # println(grid_p.LS[1].geoL.dcap[1,1,:])
  1430. #TODO better alloc
  1431. # geo = [grid_p.LS[iLS].geoL for iLS in 1:num._nLS]
  1432. # geo_u = [grid_u.LS[iLS].geoL for iLS in 1:num._nLS]
  1433. # geo_v = [grid_v.LS[iLS].geoL for iLS in 1:num._nLS]
  1434. # laps = set_matrices!(
  1435. # num, grid_p, geo, grid_u, geo_u, grid_v, geo_v,
  1436. # op.opC_pL, op.opC_uL, op.opC_vL,
  1437. # periodic_x, periodic_y)
  1438. if electrolysis_advection
  1439. # if imposed_velocity == "zero" && num.current_iter ==16
  1440. # num.ϵwall = 0.0
  1441. # print("\n changed eps wall")
  1442. # end
  1443. #printstyled(color=:cyan, @sprintf "\n epsilon %.2e %.2e \n" num.ϵ num.ϵwall )
  1444. update_all_ls_data(num, grid_p, grid_u, grid_v, BC_int, periodic_x, periodic_y)
  1445. end
  1446. # printstyled(color=:red, @sprintf "\n return before debug mem\n")
  1447. # return
  1448. # if num.nLS ==1 #TODO dev multiple levelsets
  1449. #PDI (IO)
  1450. if num.io_pdi>0
  1451. #or permutedims(grid_p.LS[num.iLSpdi].geoL.dcap, (3, 2, 1)) (3, 1, 2)
  1452. try
  1453. # num.iLSpdi = 1 # TODO all grid_p.LS
  1454. PDI_status = @ccall "libpdi".PDI_multi_expose("write_capacities"::Cstring,
  1455. # "dcap"::Cstring, permutedims(grid_p.LS[num.iLSpdi].geoL.dcap, (3, 2, 1))::Ptr{Cdouble}, PDI_OUT::Cint,
  1456. "dcap_1"::Cstring, grid_p.LS[num.iLSpdi].geoL.dcap[:,:,1]::Ptr{Cdouble}, PDI_OUT::Cint,
  1457. "dcap_2"::Cstring, grid_p.LS[num.iLSpdi].geoL.dcap[:,:,2]::Ptr{Cdouble}, PDI_OUT::Cint,
  1458. "dcap_3"::Cstring, grid_p.LS[num.iLSpdi].geoL.dcap[:,:,3]::Ptr{Cdouble}, PDI_OUT::Cint,
  1459. "dcap_4"::Cstring, grid_p.LS[num.iLSpdi].geoL.dcap[:,:,4]::Ptr{Cdouble}, PDI_OUT::Cint,
  1460. C_NULL::Ptr{Cvoid})::Cint
  1461. catch error
  1462. printstyled(color=:red, @sprintf "\n PDI error \n")
  1463. print(error)
  1464. printstyled(color=:red, @sprintf "\n PDI error \n")
  1465. end
  1466. end #if io_pdi
  1467. # # #TODO better alloc
  1468. # geo = [grid_p.LS[iLS].geoL for iLS in 1:num._nLS]
  1469. # geo_u = [grid_u.LS[iLS].geoL for iLS in 1:num._nLS]
  1470. # geo_v = [grid_v.LS[iLS].geoL for iLS in 1:num._nLS]
  1471. # laps = set_matrices!(
  1472. # num, grid_p, geo, grid_u, geo_u, grid_v, geo_v,
  1473. # op.opC_pL, op.opC_uL, op.opC_vL,
  1474. # periodic_x, periodic_y)
  1475. #interface term in rhs comes from op.opC_TL
  1476. #TODO variable CL
  1477. PDI_status = @ccall "libpdi".PDI_multi_expose("write_iso"::Cstring,
  1478. "nstep"::Cstring, num.current_iter::Ref{Clonglong}, PDI_OUT::Cint,
  1479. "levelset_iso"::Cstring, grid_p.LS[num.iLSpdi].iso::Ptr{Cdouble}, PDI_OUT::Cint,
  1480. C_NULL::Ptr{Cvoid})::Cint
  1481. # printstyled(color=:magenta, @sprintf "\n Before scalar transport\n")
  1482. # printstyled(color=:cyan, @sprintf "\n Before scalar transport\n")
  1483. # printstyled(color=:green, @sprintf "\n Before scalar transport\n")
  1484. scalar_transport!(num, grid_p, grid_u, grid_v,
  1485. op.opC_TL, #op
  1486. op.opL, #op_conv
  1487. phL,
  1488. BC_trans_scal,
  1489. BC_int,
  1490. Ascal,
  1491. Bscal,
  1492. all_CUTCT,
  1493. rhs_scal,
  1494. tmp_vec_p, #used to store a0 for rhs of interfacial value
  1495. tmp_vec_u,
  1496. tmp_vec_v,
  1497. mass_transfer_rate,
  1498. periodic_x,
  1499. periodic_y,
  1500. electrolysis_convection,
  1501. ls_advection)
  1502. print("\n num.stop_simulation after scalar ",num.stop_simulation)
  1503. mask_1D = fnzeros(grid_p,num)
  1504. compute_mask_1D!(num,grid_p,mask_1D)
  1505. PDI_status = @ccall "libpdi".PDI_multi_expose("check_concentrations"::Cstring,
  1506. "nstep"::Cstring, num.current_iter ::Ref{Clonglong}, PDI_OUT::Cint,
  1507. "time"::Cstring, num.time::Ref{Cdouble}, PDI_OUT::Cint,
  1508. "trans_scal_1DT"::Cstring, phL.trans_scalD'::Ptr{Cdouble}, PDI_OUT::Cint,
  1509. "mask_1D"::Cstring, mask_1D::Ptr{Cdouble}, PDI_OUT::Cint,
  1510. C_NULL::Ptr{Cvoid})::Cint
  1511. PDI_status = @ccall "libpdi".PDI_multi_expose("write_mask_one_phase"::Cstring,
  1512. "nstep"::Cstring, num.current_iter ::Ref{Clonglong}, PDI_OUT::Cint,
  1513. "mask_1D"::Cstring, mask_1D::Ptr{Cdouble}, PDI_OUT::Cint,
  1514. C_NULL::Ptr{Cvoid})::Cint
  1515. # if fix
  1516. # print("\n BC_trans_scal ",BC_trans_scal[1])
  1517. # print("\n BC_trans_scal ",BC_trans_scal[1].bottom.val)
  1518. concentration_boundary_layer_width,averaged_electrode_concentration = compute_concentration_boundary_layer_width(num,grid_p,num.diffusion_coeff[1],
  1519. num.current,num.saturation_concentration_H2,phL.trans_scalD[:,1],mask_1D,electrode_definition_function)
  1520. # compute_concentration_boundary_layer_width(num,diffusion_coefficient,current,saturation_concentration,concentration_1D,mask_1D,func)
  1521. sherwood = 2*num.R / concentration_boundary_layer_width #num.R : initial radius
  1522. #TODO test rewrite diffusion + convection at interface with dot m
  1523. sherwood_bubble = num.ambiant_pressure / (num.Ru * num.temperature0) * 2 * num.current_radius * (num.current_radius-num.previous_radius) /num.timestep_n / (num.diffusion_coeff[1] * (averaged_electrode_concentration - num.saturation_concentration_H2))
  1524. # sherwood = compute_sherwood()
  1525. PDI_status = @ccall "libpdi".PDI_multi_expose("write_sherwood"::Cstring,
  1526. "nstep"::Cstring, num.current_iter ::Ref{Clonglong}, PDI_OUT::Cint,
  1527. "concentration_boundary_layer_width"::Cstring, concentration_boundary_layer_width::Ref{Cdouble}, PDI_OUT::Cint,
  1528. "sherwood"::Cstring, sherwood::Ref{Cdouble}, PDI_OUT::Cint,
  1529. "sherwood_bubble"::Cstring, sherwood_bubble::Ref{Cdouble}, PDI_OUT::Cint,
  1530. C_NULL::Ptr{Cvoid})::Cint
  1531. # PDI_status = @ccall "libpdi".PDI_multi_expose("check_concentrations"::Cstring,
  1532. # scalar_transport!(BC_trans_scal, num, grid_p, , grid_p.LS[1].geoL, phL, num.concentration0,
  1533. # grid_p.LS[1].MIXED, grid_p.LS[1].geoL.projection, op.opL, grid_u, grid_u.LS[1].geoL, grid_v, grid_v.LS[1].geoL,
  1534. # periodic_x, periodic_y, electrolysis_convection, ls_advection, BC_int, num.diffusion_coeff,Ascal,Bscal,all_CUTCT,rhs_scal)
  1535. # else
  1536. # printstyled(color=:red, @sprintf "\n TODO multiple LS \n" )
  1537. # end
  1538. # scalar_transport_2!(BC_trans_scal, num, grid_p, op.opC_TL, grid_p.LS[1].geoL, phL, num.concentration0,
  1539. # grid_p.LS[1].MIXED, grid_p.LS[1].geoL.projection, op.opL, grid_u, grid_u.LS[1].geoL, grid_v, grid_v.LS[1].geoL,
  1540. # periodic_x, periodic_y, electrolysis_convection, true, BC_int, num.diffusion_coeff)
  1541. if ((num.current_iter-1)%show_every == 0)
  1542. # printstyled(color=:cyan, @sprintf "\n after scalar transport \n")
  1543. # print_electrolysis_statistics(num,grid_p,phL)
  1544. PDI_status = @ccall "libpdi".PDI_multi_expose("print_variables"::Cstring,
  1545. "nstep"::Cstring, num.current_iter ::Ref{Clonglong}, PDI_OUT::Cint,
  1546. "time"::Cstring, num.time::Ref{Cdouble}, PDI_OUT::Cint,
  1547. "u_1D"::Cstring, phL.uD::Ptr{Cdouble}, PDI_OUT::Cint,
  1548. "v_1D"::Cstring, phL.vD::Ptr{Cdouble}, PDI_OUT::Cint,
  1549. "p_1D"::Cstring, phL.pD::Ptr{Cdouble}, PDI_OUT::Cint,
  1550. "levelset_p"::Cstring, grid_p.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  1551. "levelset_u"::Cstring, grid_u.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  1552. "levelset_v"::Cstring, grid_v.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  1553. "trans_scal_1DT"::Cstring, phL.trans_scalD'::Ptr{Cdouble}, PDI_OUT::Cint,
  1554. "phi_ele_1D"::Cstring, phL.phi_eleD::Ptr{Cdouble}, PDI_OUT::Cint,
  1555. C_NULL::Ptr{Cvoid})::Cint
  1556. # scal_error=0.0
  1557. # for iscal in 1:num.nb_transported_scalars
  1558. # # printstyled(color=:cyan, @sprintf "\n after scalar transport %.2i %.2e \n" iscal maximum(abs.(phL.trans_scal[:,:,iscal])))
  1559. # # printstyled(color=:cyan, @sprintf "\n after scalar transport %.2i %.2e \n" iscal maximum(abs.(phL.trans_scalD[:,iscal])))
  1560. # # scal_error_bulk = maximum(abs.(phL.trans_scal[:,:,iscal].-num.concentration0[iscal])./num.concentration0[iscal])
  1561. # # scal_error_border = maximum(abs.(vecb(phL.trans_scalD[:,iscal],grid_p).-num.concentration0[iscal])./num.concentration0[iscal])
  1562. # # scal_error = max(scal_error_bulk,scal_error_border,scal_error)
  1563. # end
  1564. # printstyled(color=:cyan, @sprintf "\n error after scalar transport %.2e num.CFL %.2e\n" scal_error num.v_inlet*num.timestep_n/grid_p.dx[1,1])
  1565. end
  1566. if imposed_velocity != "none" && num.debug== "scalar_testing"
  1567. scal_error=0.0
  1568. for iscal in 1:num.nb_transported_scalars
  1569. # print("\n maximum ",maximum(phL.trans_scalD[:,iscal]), )
  1570. # printstyled(color=:cyan, @sprintf "\n error after scalar transport max %.2e min %.2e\n" maximum(phL.trans_scalD[:,iscal]) minimum(phL.trans_scalD[:,iscal]))
  1571. scal_error_bulk = maximum(abs.(phL.trans_scal[:,:,iscal].-num.concentration0[iscal])./num.concentration0[iscal])
  1572. scal_error_border = maximum(abs.(vecb(phL.trans_scalD[:,iscal],grid_p).-num.concentration0[iscal])./num.concentration0[iscal])
  1573. scal_error = max(scal_error_bulk,scal_error_border,scal_error)
  1574. end
  1575. printstyled(color=:cyan, @sprintf "\n error after scalar transport %.2e num.CFL %.2e\n" scal_error num.v_inlet*num.timestep_n/grid_p.dx[1,1])
  1576. # printstyled(color=:red, @sprintf "\n Poiseuille \n")
  1577. # # Check the velocity field before the scalar transport
  1578. # test_Poiseuille(num,phL.vD,grid_v)
  1579. # printstyled(color=:cyan, @sprintf "\n pressure min %.2e max %.2e\n" minimum(phL.p[1,:]) maximum(phL.p[1,:]))
  1580. # printstyled(color=:cyan, @sprintf "\n pressure min %.2e max %.2e\n" minimum(phL.p[end,:]) maximum(phL.p[end,:]))
  1581. # printstyled(color=:cyan, @sprintf "\n pressure min %.2e max %.2e\n" BC_pL.bottom.val BC_pL.top.val )
  1582. # compute_grad_p!(num,grid_p, grid_u, grid_v, phL.pD, op.opC_pL, op.opC_uL, op.opC_vL)
  1583. end
  1584. end #num.nb_transported_scalars>0
  1585. #endregion Scalar transport
  1586. # if imposed_velocity =="none"
  1587. # printstyled(color=:red, @sprintf "\n after scalar transport \n")
  1588. # # Check the velocity field before the scalar transport
  1589. # test_Poiseuille(num,phL,grid_v)
  1590. # end
  1591. end #if electrolysis_liquid_phase
  1592. end #if electrolysis
  1593. #endregion Electrolysis
  1594. #PDI (IO)
  1595. if num.io_pdi>0
  1596. try
  1597. # printstyled(color=:red, @sprintf "\n PDI test \n" )
  1598. # phi_array=phL.phi_ele #do not transpose since python row major
  1599. # Compute electrical current, interpolate velocity on scalar grid_p
  1600. # if num.electrical_potential>0 compute_grad_phi_ele!(num, grid_p, grid_u, grid_v, phL, phS, op.opC_pL, op.opC_pS) #TODO current
  1601. # if electrolysis && num.nb_transported_scalars>1
  1602. # if heat
  1603. # elec_cond = 2*num.Faraday^2 .*phL.trans_scal[:,:,2].*num.diffusion_coeff[2]./(num.Ru.*phL.T) #phL.T
  1604. # else
  1605. # elec_cond = 2*num.Faraday^2 .*phL.trans_scal[:,:,2].*num.diffusion_coeff[2]./(num.Ru*num.temperature0)
  1606. # end
  1607. # else
  1608. # elec_cond = ones(grid_p)
  1609. # printstyled(color=:green, @sprintf "\n conductivity one")
  1610. # end
  1611. # phL.i_current_mag .*= elec_cond # i=-κ∇ϕ here magnitude
  1612. #store in us, vs instead of Eus, Evs
  1613. # interpolate_grid_liquid!(grid_p,grid_u,grid_v,phL.Eu, phL.Ev,tmp_vec_p,tmp_vec_p0)
  1614. # printstyled(color=:red, @sprintf "\n test i current\n" )
  1615. # print("\n phi ",phL.phi_ele[64,127]," ",phL.phi_ele[64,128]," ",(phL.phi_ele[64,128]-phL.phi_ele[64,127])/grid_p.dx[64,128]," ",(phL.phi_ele[64,128]-phL.phi_ele[64,127])/grid_p.dx[64,127]*elec_cond[64,127], " cond ", elec_cond[64,127]," \n")
  1616. # tmp_vec_p .*= elec_cond
  1617. # tmp_vec_p0 .*= elec_cond
  1618. # @ccall "libpdi".PDI_multi_expose("write_data_elec"::Cstring,
  1619. # "i_current_x"::Cstring, tmp_vec_p::Ptr{Cdouble}, PDI_OUT::Cint,
  1620. # "i_current_y"::Cstring, tmp_vec_p0::Ptr{Cdouble}, PDI_OUT::Cint,
  1621. # "i_current_mag"::Cstring, phL.i_current_mag::Ptr{Cdouble}, PDI_OUT::Cint,
  1622. # "phi_ele_1D"::Cstring, phL.phi_eleD::Ptr{Cdouble}, PDI_OUT::Cint,
  1623. # C_NULL::Ptr{Cvoid})::Cint
  1624. interpolate_staggered_u_v_to_scalar_grid_one_fluid_or_one_phase!(num,grid_p,grid_u,grid_v,phL.u,phL.v,tmp_vec_p,tmp_vec_p0)
  1625. # num.iLSpdi = 1 # TODO all grid_p.LS
  1626. # Exposing data to PDI for IO
  1627. # if writing "D" array (bulk, interface, border), add "_1D" to the name
  1628. PDI_status = @ccall "libpdi".PDI_multi_expose("write_data"::Cstring,
  1629. "nstep"::Cstring, num.current_iter::Ref{Clonglong}, PDI_OUT::Cint,
  1630. "time"::Cstring, num.time::Ref{Cdouble}, PDI_OUT::Cint,
  1631. "timestep"::Cstring, num.timestep_n::Ref{Cdouble}, PDI_OUT::Cint,
  1632. "nx"::Cstring, grid_p.nx::Ref{Clonglong}, PDI_OUT::Cint,
  1633. "ny"::Cstring, grid_p.ny::Ref{Clonglong}, PDI_OUT::Cint,
  1634. "u_1D"::Cstring, phL.uD::Ptr{Cdouble}, PDI_OUT::Cint,
  1635. "v_1D"::Cstring, phL.vD::Ptr{Cdouble}, PDI_OUT::Cint,
  1636. "p_1D"::Cstring, phL.pD::Ptr{Cdouble}, PDI_OUT::Cint,
  1637. "levelset_p"::Cstring, grid_p.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  1638. "levelset_u"::Cstring, grid_u.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  1639. "levelset_v"::Cstring, grid_v.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  1640. "trans_scal_1DT"::Cstring, phL.trans_scalD'::Ptr{Cdouble}, PDI_OUT::Cint,
  1641. "phi_ele_1D"::Cstring, phL.phi_eleD::Ptr{Cdouble}, PDI_OUT::Cint,
  1642. "velocity_x"::Cstring, tmp_vec_p::Ptr{Cdouble}, PDI_OUT::Cint,
  1643. "velocity_y"::Cstring, tmp_vec_p0::Ptr{Cdouble}, PDI_OUT::Cint,
  1644. "radius"::Cstring, num.current_radius::Ref{Cdouble}, PDI_OUT::Cint,
  1645. C_NULL::Ptr{Cvoid})::Cint
  1646. # if num.nb_transported_scalars>0
  1647. # PDI_status = @ccall "libpdi".PDI_multi_expose("write_data_species"::Cstring,
  1648. # "nstep"::Cstring, num.current_iter::Ref{Clonglong}, PDI_OUT::Cint,
  1649. # "trans_scal_1DT"::Cstring, phL.trans_scalD'::Ptr{Cdouble}, PDI_OUT::Cint,
  1650. # C_NULL::Ptr{Cvoid})::Cint
  1651. # end
  1652. #TODO debug with volume fraction
  1653. # A = zeros(gv.ny, gv.nx+1)
  1654. # for jplot in 1:gv.ny
  1655. # for iplot in 1:gv.nx+1
  1656. # II = CartesianIndex(jplot, iplot) #(id_y, id_x)
  1657. # pII = lexicographic(II, grid_p.ny + 1)
  1658. # A[jplot,iplot] = 1 ./ op.opC_vL.iMx.diag[pII]
  1659. # end
  1660. # end
  1661. # print("\n after write \n ")
  1662. # printstyled(color=:red, @sprintf "\n PDI test end\n" )
  1663. catch error
  1664. printstyled(color=:red, @sprintf "\n PDI error \n")
  1665. print(error)
  1666. printstyled(color=:red, @sprintf "\n PDI error \n")
  1667. end
  1668. end #if io_pdi
  1669. #region compute mass transfer
  1670. if num.solve_Navier_Stokes_liquid_phase == 1 && num.phase_change_method >0
  1671. num.previous_radius = num.current_radius
  1672. # num.status =
  1673. compute_mass_transfer_rate_main!(num, grid_p, grid_u, grid_v, op, phL, phS, BC_int, electrolysis, electrolysis_phase_change_case,
  1674. periodic_x, periodic_y, λ, Vmean, num.iLSpdi, mode_2d, show_every,
  1675. mass_transfer_rate,mass_transfer_rate_vec1,
  1676. mass_transfer_rate_vecb,mass_transfer_rate_veci, mass_transfer_rate_redistributed, tmp_vec_p, tmp_vec_p0, tmp_vec_p1,
  1677. nb_gaz_acceptors, volume_fraction, interface_length)
  1678. #endregion compute mass transfer
  1679. end
  1680. #region Navier-Stokes
  1681. if num.solve_Navier_Stokes_liquid_phase == 1
  1682. if num.time < num.nucleation_time
  1683. printstyled(color=:red, @sprintf "\n Navier-Stokes not solved")
  1684. navier_stokes = false
  1685. else
  1686. printstyled(color=:red, @sprintf "\n Navier-Stokes solved")
  1687. navier_stokes = true
  1688. end
  1689. if navier_stokes
  1690. # Adapt cell volume W for gradients
  1691. # cf 4/3 factor for Laplacian
  1692. if num.laplacian == 1
  1693. AvLcopy = copy(AvL) #does not work if reset A after operations in compute_divergence!
  1694. Lvm1_L,bc_Lvm1_L,bc_Lvm1_b_L=compute_divergence!(num,
  1695. # grid_p,
  1696. # grid_u,
  1697. grid_v,
  1698. op.opC_vL,
  1699. AvLcopy,
  1700. # rhs_scal,
  1701. # tmp_vec_p, #a0
  1702. tmp_vec_1D_v0,
  1703. tmp_vec_1D_v,
  1704. Lvm1_L,
  1705. bc_Lvm1_L,
  1706. bc_Lvm1_b_L
  1707. # tmp_vec_u0,
  1708. # tmp_vec_v0,
  1709. # tmp_vec_1D,
  1710. # ls_advection
  1711. )
  1712. print("\nbefore pressure")
  1713. II = CartesianIndex(div(grid_v.ny,2),1)
  1714. pII = lexicographic(II,grid_v.ny)
  1715. print("\nLv[pII,:] ",Lvm1_L[pII,:])
  1716. print("\bc_Lvm1_b[pII,:] ",bc_Lvm1_b_L[pII,:])
  1717. ApLcopy = copy(Ascal)
  1718. Lpm1_L,bc_Lpm1_L,bc_Lpm1_b_L=compute_divergence!(num,
  1719. # grid_p,
  1720. # grid_u,
  1721. grid_p,
  1722. op.opC_pL,
  1723. ApLcopy,
  1724. # rhs_scal,
  1725. # tmp_vec_p, #a0
  1726. tmp_vec_1D_p0,
  1727. tmp_vec_1D_p,
  1728. Lpm1_L,
  1729. bc_Lpm1_L,
  1730. bc_Lpm1_b_L
  1731. # tmp_vec_u0,
  1732. # tmp_vec_v0,
  1733. # tmp_vec_1D,
  1734. # ls_advection
  1735. )
  1736. end
  1737. if num.pressure_velocity_coupling == 3
  1738. # num.iLSpdi = 1 # TODO all grid_p.LS
  1739. PDI_status = @ccall "libpdi".PDI_multi_expose("print_capacities"::Cstring,
  1740. # "dcap"::Cstring, permutedims(grid_p.LS[num.iLSpdi].geoL.dcap, (3, 2, 1))::Ptr{Cdouble}, PDI_OUT::Cint,
  1741. "dcap_1"::Cstring, grid_u.LS[num.iLSpdi].geoL.dcap[:,:,1]::Ptr{Cdouble}, PDI_OUT::Cint,
  1742. "dcap_2"::Cstring, grid_u.LS[num.iLSpdi].geoL.dcap[:,:,2]::Ptr{Cdouble}, PDI_OUT::Cint,
  1743. "dcap_3"::Cstring, grid_u.LS[num.iLSpdi].geoL.dcap[:,:,3]::Ptr{Cdouble}, PDI_OUT::Cint,
  1744. "dcap_4"::Cstring, grid_u.LS[num.iLSpdi].geoL.dcap[:,:,4]::Ptr{Cdouble}, PDI_OUT::Cint,
  1745. C_NULL::Ptr{Cvoid})::Cint
  1746. PDI_status = @ccall "libpdi".PDI_multi_expose("print_capacities"::Cstring,
  1747. # "dcap"::Cstring, permutedims(grid_p.LS[num.iLSpdi].geoL.dcap, (3, 2, 1))::Ptr{Cdouble}, PDI_OUT::Cint,
  1748. "dcap_1"::Cstring, grid_v.LS[num.iLSpdi].geoL.dcap[:,:,1]::Ptr{Cdouble}, PDI_OUT::Cint,
  1749. "dcap_2"::Cstring, grid_v.LS[num.iLSpdi].geoL.dcap[:,:,2]::Ptr{Cdouble}, PDI_OUT::Cint,
  1750. "dcap_3"::Cstring, grid_v.LS[num.iLSpdi].geoL.dcap[:,:,3]::Ptr{Cdouble}, PDI_OUT::Cint,
  1751. "dcap_4"::Cstring, grid_v.LS[num.iLSpdi].geoL.dcap[:,:,4]::Ptr{Cdouble}, PDI_OUT::Cint,
  1752. C_NULL::Ptr{Cvoid})::Cint
  1753. # print("\n cap_1 ",grid_u.LS[num.iLSpdi].geoL.dcap[1,:,1])
  1754. # print("\n cap_1 ",grid_u.LS[num.iLSpdi].geoL.dcap[2,:,1])
  1755. # print("\n cap_1 ",grid_v.LS[num.iLSpdi].geoL.dcap[1,:,1])
  1756. # print("\n cap_1 ",grid_v.LS[num.iLSpdi].geoL.dcap[2,:,1])
  1757. # print("\n cap_2 ",grid_v.LS[num.iLSpdi].geoL.dcap[1,:,2])
  1758. # print("\n cap_2 ",grid_v.LS[num.iLSpdi].geoL.dcap[2,:,2])
  1759. # print("\n cap_3 ",grid_v.LS[num.iLSpdi].geoL.dcap[1,:,3])
  1760. # print("\n cap_3 ",grid_v.LS[num.iLSpdi].geoL.dcap[2,:,3])
  1761. # for u grid_p
  1762. # cap 1 same
  1763. # cap_1 [0.0, 1.0e-5, 1.0e-5, 1.0e-5, 1.0e-5, 1.0e-5, 1.0e-5, 1.0e-5, 1.0e-5, 1.0e-5, 1.0e-5]
  1764. end
  1765. # if !advection
  1766. # @time no_slip_condition!(num, grid_p, grid_u, grid_u.LS[1], grid_v, grid_v.LS[1], periodic_x, periodic_y)
  1767. # # grid_u.V .= num.Δ / (1 * num.timestep_n)
  1768. # # grid_v.V .= 0.0
  1769. # end
  1770. # Pressure-velocity coupling
  1771. if (num.one_fluid_model == 1 && num.solve_Navier_Stokes_liquid_phase == 1)
  1772. # interpolate_staggered_u_v_to_scalar_grid_one_fluid_or_one_phase!(num,grid_p,grid_u,grid_v,phL.u,phL.v,tmp_vec_p,tmp_vec_p0)
  1773. tmp_vec_p .= 0.0
  1774. tmp_vec_p0 .= 0.0
  1775. for j = 1:grid_p.ny
  1776. for i = 1:grid_p.nx
  1777. tmp_vec_p[j,i] =(phL.u[j,i]+phL.u[j,i+1])/2
  1778. tmp_vec_p0[j,i]=(phL.v[j,i]+phL.v[j+1,i])/2
  1779. end
  1780. end
  1781. update_one_fluid_density_viscosity(num,grid_p,grid_u,grid_v,volume_fraction,levelset_one_fluid,rho_one_fluid,
  1782. rho_one_fluid_u,rho_one_fluid_v,mu_one_fluid,tmp_vec_p0)
  1783. total_interface_length = compute_interface_length!(num, grid_p, 1, interface_length)
  1784. # MIXED =
  1785. nb_levelsets = num.nLS
  1786. num.nLS = 0 #1 #deactivate cut-cell for one-fluid model
  1787. #region deactivate LS
  1788. empty_capacities = vcat(zeros(7), zeros(4))
  1789. full_capacities = vcat(ones(7), 0.5.*ones(4))
  1790. for grid_iter in [grid_p,grid_u,grid_v]
  1791. grid_iter.LS[1].u .= 1.0
  1792. grid_iter.LS[end].u .= 1.0
  1793. # for j in 1:grid_iter.ny
  1794. # for i in 1:grid_iter.nx
  1795. # II = CartesianIndex(j,i)
  1796. # # grid_iter.LS[end].geoL.cap[II,:] .= full_capacities
  1797. # # grid_iter.LS[end].geoS.cap[II,:] .= empty_capacities
  1798. # end
  1799. # end
  1800. end
  1801. # grid_u.LS[end].geoL.cap[:,:,:] .= full_capacities
  1802. # grid_u.LS[end].geoS.cap[:,:,:] .= empty_capacities
  1803. # grid_v.LS[end].geoL.cap[:,:,:] .= full_capacities
  1804. # grid_v.LS[end].geoS.cap[:,:,:] .= empty_capacities
  1805. #endregion deactivate LS
  1806. NB_indices = update_all_ls_data(num, grid_p, grid_u, grid_v, BC_int, periodic_x, periodic_y,true,true)
  1807. geoL = [grid_p.LS[iLS].geoL for iLS in 1:num._nLS]
  1808. geo_uL = [grid_u.LS[iLS].geoL for iLS in 1:num._nLS]
  1809. geo_vL = [grid_v.LS[iLS].geoL for iLS in 1:num._nLS]
  1810. #region reset centroids
  1811. for grid_iter in [grid_p,grid_u,grid_v]
  1812. for II in grid_iter.ind.inside
  1813. grid_iter.LS[1].geoL.centroid[II] = Point(0.0,0.0)
  1814. end
  1815. end
  1816. #endregion reset centroids
  1817. #TODO reactivate centroids ?
  1818. # TODO update density
  1819. # if num.pressure_velocity_coupling == 0
  1820. #region update LS
  1821. #endregion update LS
  1822. #pbm mass_transfer_rateL
  1823. PDI_status = @ccall "libpdi".PDI_multi_expose("check_mass_transfer_rate_NS"::Cstring,
  1824. # "conservation"::Cstring, conservation::Ref{Cdouble}, PDI_OUT::Cint,
  1825. "mass_transfer_rate"::Cstring, mass_transfer_rate::Ptr{Cdouble}, PDI_OUT::Cint,
  1826. # "p_1D"::Cstring, phL.pD::Ptr{Cdouble}, PDI_OUT::Cint,
  1827. C_NULL::Ptr{Cvoid})::Cint
  1828. #region update LS for convection (bool=true)+ one fluid
  1829. # At every iteration, update_all_ls_data is called twice, once inside run.jl
  1830. # and another one (if there's advection of the levelset) inside set_heat!.
  1831. # The difference between both is a flag as last argument, inside run.jl is implicitly defined
  1832. # as true and inside set_heat! is false. If you're calling your version of set_heat! several times,
  1833. # then you're calling the version with the flag set to false, but for the convective term it has to be set to true.
  1834. # The flag=true, the capacities are set for the convection, the flag=false they are set for the other operators
  1835. if advection
  1836. # update_all_ls_data(num, grid_p, grid_u, grid_v, BC_int, periodic_x, periodic_y, true)
  1837. update_all_ls_data(num, grid_p, grid_u, grid_v, BC_int, periodic_x, periodic_y, true,true)
  1838. if num.convection == 0
  1839. # op.opL is op_conv
  1840. set_convection_preallocated!(num, grid_p, geoL[end], grid_u, grid_u.LS, grid_v, grid_v.LS, phL.u, phL.v, op.opL,
  1841. phL, BC_uL, BC_vL,op.opC_pL, op.opC_uL, op.opC_vL,
  1842. velocity_and_BC_convection_u_x ,
  1843. velocity_and_BC_convection_u_y ,
  1844. velocity_and_BC_convection_v_x ,
  1845. velocity_and_BC_convection_v_y)
  1846. # Mm1_L .= op.opC_pL.M
  1847. # Mum1_L .= op.opC_uL.M
  1848. # Mvm1_L .= op.opC_vL.M
  1849. else
  1850. end
  1851. end
  1852. #endregion update LS for convection (bool=true)+ one fluid
  1853. #region update LS for other operators than convection (bool=false)+ one fluid
  1854. # update_all_ls_data(num, grid_p, grid_u, grid_v, BC_int, periodic_x, periodic_y, false)
  1855. update_all_ls_data(num, grid_p, grid_u, grid_v, BC_int, periodic_x, periodic_y, false,true)
  1856. #endregion
  1857. if (num.one_fluid_model == 1 && num.solve_Navier_Stokes_liquid_phase == 1) && (num.solve_Navier_Stokes == 1)
  1858. if num.activate_interface == 0
  1859. volumic_surface_tension_u .= 0.0
  1860. volumic_surface_tension_v .= 0.0
  1861. else
  1862. if num.surface_tension == 0
  1863. compute_surface_tension_VOF!(num,grid_p, grid_u, grid_v, op.opC_pL, op.opC_uL, op.opC_vL,
  1864. volume_fraction,levelset_one_fluid,volumic_surface_tension_u,volumic_surface_tension_v,tmp_vec_p,tmp_vec_p0)
  1865. elseif num.surface_tension == 1
  1866. # compute_surface_tension_LS!(num,grid_p, grid_u, grid_v, opC_p, opC_u, opC_v,
  1867. # volume_fraction,levelset_one_fluid,volumic_surface_tension_u,volumic_surface_tension_v,tmp_vec_p,tmp_vec_p0)
  1868. compute_surface_tension_LS!(num,grid_p, grid_u, grid_v, op.opC_pL, op.opC_uL, op.opC_vL,
  1869. volume_fraction,levelset_one_fluid,volumic_surface_tension_u,volumic_surface_tension_v,tmp_vec_p,tmp_vec_p0,
  1870. levelset_1D, levelset_heavyside_2D,
  1871. tmp_vec_u0,tmp_vec_v0, #normal_and_dirac_u, normal_and_dirac_v,
  1872. tmp_vec_u1,tmp_vec_v1,#normal_u, normal_v,
  1873. tmp_vec_u,tmp_vec_v,#curvature_u, curvature_v
  1874. )
  1875. # elseif num. TODO HF
  1876. end
  1877. end
  1878. end
  1879. PDI_status = @ccall "libpdi".PDI_multi_expose("write_one_fluid_surface_tension_concise"::Cstring,
  1880. "nstep"::Cstring, num.current_iter ::Ref{Clonglong}, PDI_OUT::Cint,
  1881. "volumic_surface_tension_u"::Cstring, volumic_surface_tension_u::Ptr{Cdouble}, PDI_OUT::Cint,
  1882. "volumic_surface_tension_v"::Cstring, volumic_surface_tension_v::Ptr{Cdouble}, PDI_OUT::Cint,
  1883. C_NULL::Ptr{Cvoid})::Cint
  1884. #BC TODO
  1885. # @error("\n check temporal terms")
  1886. # Mum1_L is put in B matrix that multiplies v
  1887. # print("\n advection ", ns_advection, " adv ",advection)
  1888. one_fluid_NS_ls_advection = true #update matrix
  1889. Lpm1_L, bc_Lpm1_L, bc_Lpm1_b_L, Lum1_L, bc_Lum1_L, bc_Lum1_b_L,
  1890. Lvm1_L, bc_Lvm1_L, bc_Lvm1_b_L, Mm1_L, Mum1_L, Mvm1_L, Cum1L, Cvm1L = solve_one_fluid_NS!(
  1891. time_scheme, BC_int,
  1892. num, grid_p, geoL, grid_u, geo_uL, grid_v, geo_vL, phL,
  1893. BC_uL, BC_vL, BC_pL,
  1894. op.opC_pL, op.opC_uL, op.opC_vL, op.opL,
  1895. # op.opC_TL,
  1896. AuL, BuL, AvL, BvL, AϕL, AuvL, BuvL,rhs_uv,
  1897. Lpm1_L, bc_Lpm1_L, bc_Lpm1_b_L, Lum1_L, bc_Lum1_L, bc_Lum1_b_L, Lvm1_L, bc_Lvm1_L, bc_Lvm1_b_L,
  1898. Cum1L, Cvm1L, Mum1_L, Mvm1_L,
  1899. periodic_x, periodic_y, ns_advection, one_fluid_NS_ls_advection, num.current_iter, Ra, navier,
  1900. volume_fraction,
  1901. levelset_one_fluid,
  1902. rho_one_fluid,
  1903. mu_one_fluid,
  1904. rho_one_fluid_u,
  1905. # mu_one_fluid_u,
  1906. rho_one_fluid_v,
  1907. # mu_one_fluid_v,
  1908. volumic_surface_tension_u,
  1909. volumic_surface_tension_v,
  1910. convection_u,convection_v,
  1911. viscosity_coeff_for_du_dx ,
  1912. viscosity_coeff_for_du_dy ,
  1913. viscosity_coeff_for_dv_dx ,
  1914. viscosity_coeff_for_dv_dy,
  1915. # velocity_and_BC_convection_u_x ,
  1916. # velocity_and_BC_convection_u_y ,
  1917. # velocity_and_BC_convection_v_x ,
  1918. # velocity_and_BC_convection_v_y ,
  1919. tmp_vec_p,
  1920. tmp_vec_p0,
  1921. rhs_phi,
  1922. pres_free_surfaceL,jump_mass_transfer_rateL,mass_transfer_rate )
  1923. #region ciprianoMulticomponentDropletEvaporation2024
  1924. if extend_liquid_velocity
  1925. # num.phase_change_currently_activated == 1
  1926. phase_change_currently_activated = 0
  1927. # no need to recompute Lpm1_L, bc_Lpm1_L, bc_Lpm1_b_L, Lum1_L, bc_Lum1_L, bc_Lum1_b_L,
  1928. # Lvm1_L, bc_Lvm1_L, bc_Lvm1_b_L
  1929. # Mm1_L_ext_vel, Mum1_L_ext_vel, Mvm1_L_ext_vel same as Mm1_L, Mum1_L, Mvm1_L
  1930. # because :
  1931. # Mm1_L = copy(op.opC_pL.M)
  1932. # Mum1_L = copy(op.opC_uL.M)
  1933. # Mvm1_L = copy(op.opC_vL.M)
  1934. Lpm1_L, bc_Lpm1_L, bc_Lpm1_b_L, Lum1_L, bc_Lum1_L, bc_Lum1_b_L,
  1935. Lvm1_L, bc_Lvm1_L, bc_Lvm1_b_L,
  1936. Mm1_L, Mum1_L, Mvm1_L,
  1937. Cum1L_ext_vel, Cvm1L_ext_vel = solve_one_fluid_NS_no_phase!(
  1938. time_scheme, BC_int,
  1939. num, grid_p, geoL, grid_u, geo_uL, grid_v, geo_vL,
  1940. # phL,
  1941. p_ext_vel, pD_ext_vel, phi_ext_vel, u_ext_vel, v_ext_vel, u_predictionD_ext_vel, v_predictionD_ext_vel, uD_ext_vel, vD_ext_vel, u_prediction_ext_vel, v_prediction_ext_vel, uT_ext_vel,
  1942. pres_grad_x, pres_grad_y,
  1943. phase_change_currently_activated,
  1944. BC_uL, BC_vL, BC_pL,
  1945. op.opC_pL, op.opC_uL, op.opC_vL, op.opL,
  1946. # op.opC_TL,
  1947. AuL, BuL, AvL, BvL, AϕL, AuvL, BuvL,rhs_uv,
  1948. Lpm1_L, bc_Lpm1_L, bc_Lpm1_b_L,
  1949. Lum1_L, bc_Lum1_L, bc_Lum1_b_L,
  1950. Lvm1_L, bc_Lvm1_L, bc_Lvm1_b_L,
  1951. Cum1L_ext_vel, Cvm1L_ext_vel,
  1952. Mum1_L, Mvm1_L,
  1953. periodic_x, periodic_y, ns_advection, advection, num.current_iter, Ra, navier,
  1954. volume_fraction,
  1955. levelset_one_fluid,
  1956. rho_one_fluid,
  1957. mu_one_fluid,
  1958. rho_one_fluid_u,
  1959. rho_one_fluid_v,
  1960. volumic_surface_tension_u,
  1961. volumic_surface_tension_v,
  1962. convection_u,convection_v,
  1963. viscosity_coeff_for_du_dx ,
  1964. viscosity_coeff_for_du_dy ,
  1965. viscosity_coeff_for_dv_dx ,
  1966. viscosity_coeff_for_dv_dy,
  1967. tmp_vec_p,
  1968. tmp_vec_p0,
  1969. rhs_phi,
  1970. pres_free_surfaceL,jump_mass_transfer_rateL,mass_transfer_rate )
  1971. PDI_status = @ccall "libpdi".PDI_multi_expose("velocity_extension"::Cstring,
  1972. "u_ext_vel"::Cstring, u_ext_vel::Ptr{Cdouble}, PDI_OUT::Cint,
  1973. "v_ext_vel"::Cstring, v_ext_vel::Ptr{Cdouble}, PDI_OUT::Cint,
  1974. C_NULL::Ptr{Cvoid})::Cint
  1975. end
  1976. #endregion ciprianoMulticomponentDropletEvaporation2024
  1977. print("\n num.stop_simulation after NS ",num.stop_simulation)
  1978. #region reactivate cut-cell for one-fluid model
  1979. num.nLS = nb_levelsets
  1980. grid_p.LS[1].u .= levelset_one_fluid
  1981. grid_p.LS[end].u .= levelset_one_fluid
  1982. NB_indices = update_all_ls_data(num, grid_p, grid_u, grid_v, BC_int, periodic_x, periodic_y)
  1983. # TODO check after activation NS after nucleation
  1984. # geoL = [grid_p.LS[iLS].geoL for iLS in 1:num._nLS]
  1985. # geo_uL = [grid_u.LS[iLS].geoL for iLS in 1:num._nLS]
  1986. # geo_vL = [grid_v.LS[iLS].geoL for iLS in 1:num._nLS]
  1987. # reactivate centroids
  1988. # printstyled(color=:red, @sprintf "\n reactivate centroids \n")
  1989. # x_centroid = grid_p.x .+ getproperty.(grid_p.LS[1].geoL.centroid, :x) .* grid_p.dx #geoS
  1990. # display(x_centroid)
  1991. # y_centroid = grid_p.y .+ getproperty.(grid_p.LS[1].geoL.centroid, :y) .* grid_p.dy #geoS
  1992. # display(y_centroid)
  1993. # display(levelset_one_fluid)
  1994. #endregion reactivate cut-cell for one-fluid model
  1995. else
  1996. if num.pressure_velocity_coupling == 0
  1997. if ns_solid_phase
  1998. geoS = [grid_p.LS[iLS].geoS for iLS in 1:num._nLS]
  1999. geo_uS = [grid_u.LS[iLS].geoS for iLS in 1:num._nLS]
  2000. geo_vS = [grid_v.LS[iLS].geoS for iLS in 1:num._nLS]
  2001. Lpm1_S, bc_Lpm1_S, bc_Lpm1_b_S, Lum1_S, bc_Lum1_S, bc_Lum1_b_S, Lvm1_S, bc_Lvm1_S, bc_Lvm1_b_S,Mm1_S, Mum1_S, Mvm1_S, Cum1S, Cvm1S = pressure_projection!(
  2002. time_scheme, BC_int,
  2003. num, grid_p, geoS, grid_u, geo_uS, grid_v, geo_vS, phS,
  2004. BC_uS, BC_vS, BC_pS,
  2005. op.opC_pS, op.opC_uS, op.opC_vS, op.opS,
  2006. AuS, BuS, AvS, BvS, AϕS, AuvS, BuvS,
  2007. Lpm1_S, bc_Lpm1_S, bc_Lpm1_b_S, Lum1_S, bc_Lum1_S, bc_Lum1_b_S, Lvm1_S, bc_Lvm1_S, bc_Lvm1_b_S,
  2008. Cum1S, Cvm1S, Mum1_S, Mvm1_S,
  2009. periodic_x, periodic_y, ns_advection, advection, num.current_iter, Ra, navier,pres_free_surfaceS,jump_mass_transfer_rateS,mass_transfer_rateS
  2010. )
  2011. end
  2012. if ns_liquid_phase
  2013. geoL = [grid_p.LS[iLS].geoL for iLS in 1:num._nLS]
  2014. geo_uL = [grid_u.LS[iLS].geoL for iLS in 1:num._nLS]
  2015. geo_vL = [grid_v.LS[iLS].geoL for iLS in 1:num._nLS]
  2016. # Mum1_L is put in B matrix that multiplies v
  2017. Lpm1_L, bc_Lpm1_L, bc_Lpm1_b_L, Lum1_L, bc_Lum1_L, bc_Lum1_b_L, Lvm1_L, bc_Lvm1_L, bc_Lvm1_b_L, Mm1_L, Mum1_L, Mvm1_L, Cum1L, Cvm1L = pressure_projection!(
  2018. time_scheme, BC_int,
  2019. num, grid_p, geoL, grid_u, geo_uL, grid_v, geo_vL, phL,
  2020. BC_uL, BC_vL, BC_pL,
  2021. op.opC_pL, op.opC_uL, op.opC_vL, op.opL,
  2022. AuL, BuL, AvL, BvL, AϕL, AuvL, BuvL,
  2023. Lpm1_L, bc_Lpm1_L, bc_Lpm1_b_L, Lum1_L, bc_Lum1_L, bc_Lum1_b_L, Lvm1_L, bc_Lvm1_L, bc_Lvm1_b_L,
  2024. Cum1L, Cvm1L, Mum1_L, Mvm1_L,
  2025. periodic_x, periodic_y, ns_advection, advection, num.current_iter, Ra, navier,pres_free_surfaceL,jump_mass_transfer_rateL,mass_transfer_rate
  2026. )
  2027. # if num.current_iter == 1
  2028. # phL.u .= -0.5 .* grid_u.y .+ getproperty.(grid_u.LS[1].geoL.centroid, :y) .* grid_u.dy
  2029. # phL.v .= 0.5 .* grid_v.x .+ getproperty.(grid_v.LS[1].geoL.centroid, :x) .* grid_v.dx
  2030. # phL.u[grid_u.LS[1].SOLID] .= 0.0
  2031. # phL.v[grid_v.LS[1].SOLID] .= 0.0
  2032. # end
  2033. # linear_advection!(
  2034. # num, grid_p, grid_p.LS[1].geoL, grid_u, grid_u.LS[1].geoL, grid_v, grid_v.LS[1].geoL, phL,
  2035. # BC_uL, BC_vL, op.opL
  2036. # )
  2037. end
  2038. elseif num.pressure_velocity_coupling > 1
  2039. if ns_liquid_phase
  2040. geoL = [grid_p.LS[iLS].geoL for iLS in 1:num._nLS]
  2041. geo_uL = [grid_u.LS[iLS].geoL for iLS in 1:num._nLS]
  2042. geo_vL = [grid_v.LS[iLS].geoL for iLS in 1:num._nLS]
  2043. # Mum1_L is put in B matrix that multiplies v
  2044. Lpm1_L, bc_Lpm1_L, bc_Lpm1_b_L, Lum1_L, bc_Lum1_L, bc_Lum1_b_L, Lvm1_L, bc_Lvm1_L, bc_Lvm1_b_L, Mm1_L, Mum1_L, Mvm1_L, Cum1L, Cvm1L = coupled_pressure_velocity!(
  2045. time_scheme, BC_int,
  2046. num, grid_p, geoL, grid_u, geo_uL, grid_v, geo_vL, phL,
  2047. BC_uL, BC_vL, BC_pL,
  2048. op.opC_pL, op.opC_uL, op.opC_vL, op.opL,
  2049. AuL, BuL, AvL, BvL, AϕL, AuvL, BuvL,rhs_uv,
  2050. Lpm1_L, bc_Lpm1_L, bc_Lpm1_b_L, Lum1_L, bc_Lum1_L, bc_Lum1_b_L, Lvm1_L, bc_Lvm1_L, bc_Lvm1_b_L,
  2051. Cum1L, Cvm1L, Mum1_L, Mvm1_L,
  2052. periodic_x, periodic_y, ns_advection, advection, num.current_iter, Ra, navier,pres_free_surfaceL,jump_mass_transfer_rateL,mass_transfer_rate
  2053. )
  2054. # if num.current_iter == 1
  2055. # phL.u .= -0.5 .* grid_u.y .+ getproperty.(grid_u.LS[1].geoL.centroid, :y) .* grid_u.dy
  2056. # phL.v .= 0.5 .* grid_v.x .+ getproperty.(grid_v.LS[1].geoL.centroid, :x) .* grid_v.dx
  2057. # phL.u[grid_u.LS[1].SOLID] .= 0.0
  2058. # phL.v[grid_v.LS[1].SOLID] .= 0.0
  2059. # end
  2060. # linear_advection!(
  2061. # num, grid_p, grid_p.LS[1].geoL, grid_u, grid_u.LS[1].geoL, grid_v, grid_v.LS[1].geoL, phL,
  2062. # BC_uL, BC_vL, op.opL
  2063. # )
  2064. end
  2065. end #if num.pressure_velocity_coupling
  2066. end # if (num.one_fluid_model == 1 && num.solve_Navier_Stokes_liquid_phase == 1)
  2067. end # if navier_stokes
  2068. #region conservation, divergence checks
  2069. # TODO check global mass conservation and divergence free
  2070. not_divergence_free = true
  2071. #need one-fluid capa
  2072. conservation = compute_conservation_mass(num,phL, grid_p ,grid_u, grid_v, rho_one_fluid)
  2073. # Compute divergence of velocity
  2074. Duv = op.opC_pL.AxT * vec1(phL.uD,grid_u) .+ op.opC_pL.Gx_b * vecb(phL.uD,grid_u) .+
  2075. op.opC_pL.AyT * vec1(phL.vD,grid_v) .+ op.opC_pL.Gy_b * vecb(phL.vD,grid_v)
  2076. for iLS in 1:num.nLS
  2077. if !is_navier(BC_int[iLS]) && !is_navier_cl(BC_int[iLS]) #otherwise normal velocity null if no blowing
  2078. Duv .+= op.opC_pL.Gx[iLS] * veci(phL.uD,grid_u,iLS+1) .+
  2079. op.opC_pL.Gy[iLS] * veci(phL.vD,grid_v,iLS+1)
  2080. end
  2081. end
  2082. #TODO divergence when Navier ?
  2083. PDI_status = @ccall "libpdi".PDI_multi_expose("print_conservation"::Cstring,
  2084. "nstep"::Cstring, num.current_iter::Ref{Clonglong}, PDI_OUT::Cint,
  2085. "conservation"::Cstring, conservation::Ref{Cdouble}, PDI_OUT::Cint,
  2086. "velocity_divergence"::Cstring, Duv::Ptr{Cdouble}, PDI_OUT::Cint,
  2087. # "p_1D"::Cstring, phL.pD::Ptr{Cdouble}, PDI_OUT::Cint,
  2088. C_NULL::Ptr{Cvoid})::Cint
  2089. if maximum(Duv)< num.epsilon_divergence
  2090. not_divergence_free = false
  2091. end
  2092. if abs(conservation) > num.epsilon_conservation || not_divergence_free
  2093. PDI_status = @ccall "libpdi".PDI_multi_expose("conservation_error"::Cstring,
  2094. "u_1D"::Cstring, phL.uD::Ptr{Cdouble}, PDI_OUT::Cint,
  2095. "v_1D"::Cstring, phL.vD::Ptr{Cdouble}, PDI_OUT::Cint,
  2096. "p_1D"::Cstring, phL.pD::Ptr{Cdouble}, PDI_OUT::Cint,
  2097. C_NULL::Ptr{Cvoid})::Cint
  2098. end
  2099. #endregion conservation, divergence checks
  2100. # PDI_status = @ccall "libpdi".PDI_multi_expose("check_pressure_velocity"::Cstring,
  2101. # "u_1D"::Cstring, phL.uD::Ptr{Cdouble}, PDI_OUT::Cint,
  2102. # "v_1D"::Cstring, phL.vD::Ptr{Cdouble}, PDI_OUT::Cint,
  2103. # "p_1D"::Cstring, phL.pD::Ptr{Cdouble}, PDI_OUT::Cint,
  2104. # C_NULL::Ptr{Cvoid})::Cint
  2105. end
  2106. #endregion Navier-Stokes
  2107. #region old block phase change
  2108. #cf old_phase_change_block.jl
  2109. #endregion old block phase change
  2110. # printstyled(color=:red, @sprintf "\n after phase change radius: %.2e \n" num.current_radius)
  2111. if verbose && adaptative_t
  2112. println("num.timestep_n = $num.timestep_n")
  2113. end
  2114. # printstyled(color=:red, @sprintf "\n advection")
  2115. if num.verbosity>0
  2116. print("\n num.advection_LS_mode ",num.advection_LS_mode," advection ",advection)
  2117. end
  2118. #region Advection
  2119. if advection || electrolysis_advection
  2120. if num.io_pdi>0
  2121. PDI_status = @ccall "libpdi".PDI_multi_expose("write_before_LS_adv"::Cstring,
  2122. "normal_velocity_intfc"::Cstring, grid_p.V::Ptr{Cdouble}, PDI_OUT::Cint,
  2123. C_NULL::Ptr{Cvoid})::Cint
  2124. end # if num.io_pdi>0
  2125. printstyled(color=:red, @sprintf "\n select advection")
  2126. select_advection!(num, grid_p, BC_int, BC_u, grid_u, grid_v, CFL_sc, periodic_x, periodic_y,
  2127. θ_out, rhs_LS, utmp, electrolysis_phase_change_case, mass_transfer_rate, levelset_1D,
  2128. volume_fraction,
  2129. tmp_vec_p,tmp_vec_p0,
  2130. tmp_vec_u,tmp_vec_v,tmp_vec_u0,tmp_vec_v0,tmp_vec_u1,tmp_vec_v1,
  2131. op,
  2132. phL, u_ext_vel, v_ext_vel)
  2133. # printstyled(color=:red, @sprintf "\n after advection_LS_mode radius: %.2e \n" num.current_radius)
  2134. #region reinitialize Levelset
  2135. #TODO document
  2136. if num.levelset_reinitialize == 0
  2137. if analytical
  2138. u[grid_p.ind.b_top[1]] .= sqrt.(grid_p.x[grid_p.ind.b_top[1]] .^ 2 + grid_p.y[grid_p.ind.b_top[1]] .^ 2) .- (num.R + speed*num.current_iter*num.timestep_n);
  2139. u[grid_p.ind.b_bottom[1]] .= sqrt.(grid_p.x[grid_p.ind.b_bottom[1]] .^ 2 + grid_p.y[grid_p.ind.b_bottom[1]] .^ 2) .- (num.R + speed*num.current_iter*num.timestep_n);
  2140. u[grid_p.ind.b_left[1]] .= sqrt.(grid_p.x[grid_p.ind.b_left[1]] .^ 2 + grid_p.y[grid_p.ind.b_left[1]] .^ 2) .- (num.R + speed*num.current_iter*num.timestep_n);
  2141. u[grid_p.ind.b_right[1]] .= sqrt.(grid_p.x[grid_p.ind.b_right[1]] .^ 2 + grid_p.y[grid_p.ind.b_right[1]] .^ 2) .- (num.R + speed*num.current_iter*num.timestep_n);
  2142. elseif num.nb_reinit > 0
  2143. if auto_reinit == 1 && (num.current_iter-1)%num.reinit_every == 0
  2144. for iLS in 1:num.nLS
  2145. if !is_wall(BC_int[iLS])
  2146. ls_rg, rl_rg_v = rg(num, grid_p, grid_p.LS[iLS].u, periodic_x, periodic_y, BC_int)
  2147. println("$(ls_rg)")
  2148. printstyled(color=:green, @sprintf "\n ls_rg : %.2e \n" ls_rg)
  2149. if ls_rg >= num.δreinit || num.current_iter == 1
  2150. print("(ls_rg >= num.δreinit || num.current_iter == 1): yes")
  2151. # println("yes")
  2152. RK2_reinit!(ls_scheme, grid_p, grid_p.ind, iLS, grid_p.LS[iLS].u, num.nb_reinit, periodic_x, periodic_y, BC_u, BC_int)
  2153. ls_rg, rl_rg_v = rg(num, grid_p, grid_p.LS[iLS].u, periodic_x, periodic_y, BC_int)
  2154. println("$(ls_rg) ")
  2155. printstyled(color=:green, @sprintf "\n ls_rg : %.2e \n" ls_rg)
  2156. end
  2157. end
  2158. end
  2159. elseif (num.current_iter-1)%num.reinit_every == 0
  2160. for iLS in 1:num.nLS
  2161. if !is_wall(BC_int[iLS])
  2162. RK2_reinit!(ls_scheme, grid_p, grid_p.ind, iLS, grid_p.LS[iLS].u, num.nb_reinit, periodic_x, periodic_y, BC_u, BC_int)
  2163. end
  2164. end
  2165. # elseif num.nLS > 1
  2166. # for iLS in 1:num.nLS
  2167. # if !is_wall(BC_int[iLS])
  2168. # RK2_reinit!(ls_scheme, grid_p, grid_p.ind, iLS, grid_p.LS[iLS].u, 2num.nb_reinit, periodic_x, periodic_y, BC_u, BC_int, true)
  2169. # end
  2170. # end
  2171. end
  2172. end
  2173. # Numerical breakup
  2174. if free_surface && breakup ==1
  2175. count, id_break = breakup_n(grid_p.LS[1].u, grid_p.nx, grid_p.ny, grid_p.dx, grid_p.dy, periodic_x, periodic_y, NB_indices, 5e-2)
  2176. println(count)
  2177. if count > count_limit_breakup
  2178. println("BREAK UP!!")
  2179. breakup_f(grid_p, grid_p.LS[1].u, id_break)
  2180. RK2_reinit!(ls_scheme, grid_p, grid_p.ind, 1, grid_p.LS[1].u, num.nb_reinit, periodic_x, periodic_y, BC_u, BC_int)
  2181. end
  2182. end
  2183. elseif num.levelset_reinitialize == -1
  2184. printstyled(color=:red, @sprintf "\n No reinit")
  2185. end #if num.levelset_reinitialize
  2186. end
  2187. #endregion reinitialize Levelset
  2188. # printstyled(color=:red, @sprintf "\n after reinit radius: %.2e \n" num.current_radius)
  2189. if verbose
  2190. if (num.current_iter-1)%show_every == 0
  2191. printstyled(color=:green, @sprintf "\n Current iteration : %d (%d%%) | t = %.2e \n" (num.current_iter) 100*(num.current_iter)/num.max_iterations num.time)
  2192. #TODO CFL
  2193. # printstyled(color=:green, @sprintf "\n num.CFL : %.2e num.CFL : %.2e num.timestep_n : %.2e\n" num.CFL max(abs.(grid_p.V)..., abs.(phL.u)..., abs.(phL.v)..., abs.(phS.u)..., abs.(phS.v)...)*num.timestep_n/num.Δ num.timestep_n)
  2194. if heat && length(grid_p.LS[end].MIXED) != 0
  2195. print(@sprintf "V_mean = %.2e V_max = %.2e V_min = %.2e\n" mean(grid_p.V[grid_p.LS[1].MIXED]) findmax(grid_p.V[grid_p.LS[1].MIXED])[1] findmin(grid_p.V[grid_p.LS[1].MIXED])[1])
  2196. print(@sprintf "κ_mean = %.2e κ_max = %.2e κ_min = %.2e\n" mean(grid_p.LS[1].κ[grid_p.LS[1].MIXED]) findmax(grid_p.LS[1].κ[grid_p.LS[1].MIXED])[1] findmin(grid_p.LS[1].κ[grid_p.LS[1].MIXED])[1])
  2197. elseif advection && length(grid_p.LS[end].MIXED) != 0
  2198. V_mean = mean([mean(grid_u.V[grid_p.LS[1].MIXED]), mean(grid_v.V[grid_p.LS[1].MIXED])])
  2199. V_max = max(findmax(grid_u.V[grid_p.LS[1].MIXED])[1], findmax(grid_v.V[grid_p.LS[1].MIXED])[1])
  2200. V_min = min(findmin(grid_u.V[grid_p.LS[1].MIXED])[1], findmin(grid_v.V[grid_p.LS[1].MIXED])[1])
  2201. # print(@sprintf "Vol_ratio = %.3f%%\n" (volume(grid_p.LS[end].geoL) / V0L * 100))
  2202. print(@sprintf "V_mean = %.2e V_max = %.2e V_min = %.2e\n" V_mean V_max V_min)
  2203. print(@sprintf "κ_mean = %.2e κ_max = %.2e κ_min = %.2e\n" mean(grid_p.LS[1].κ[grid_p.LS[1].MIXED]) findmax(grid_p.LS[1].κ[grid_p.LS[1].MIXED])[1] findmin(grid_p.LS[1].κ[grid_p.LS[1].MIXED])[1])
  2204. end
  2205. if navier_stokes
  2206. if ns_solid_phase
  2207. normuS = norm(phS.u)
  2208. normvS = norm(phS.v)
  2209. normpS = norm(phS.p.*num.timestep_n)
  2210. print("$(@sprintf("norm(uS) %.6e", normuS))\t$(@sprintf("norm(vS) %.6e", normvS))\t$(@sprintf("norm(pS) %.6e", normpS))\n")
  2211. end
  2212. if ns_liquid_phase
  2213. # normuL = norm(phL.u)
  2214. # normvL = norm(phL.v)
  2215. # normpL = norm(phL.p.*num.timestep_n)
  2216. # print("$(@sprintf("norm(uL) %.6e", normuL))\t$(@sprintf("norm(vL) %.6e", normvL))\t$(@sprintf("norm(pL) %.6e", normpL))\n")
  2217. if electrolysis
  2218. # print_electrolysis_statistics(num,grid_p,phL)
  2219. PDI_status = @ccall "libpdi".PDI_multi_expose("print_variables"::Cstring,
  2220. "nstep"::Cstring, num.current_iter ::Ref{Clonglong}, PDI_OUT::Cint,
  2221. "time"::Cstring, num.time::Ref{Cdouble}, PDI_OUT::Cint,
  2222. "u_1D"::Cstring, phL.uD::Ptr{Cdouble}, PDI_OUT::Cint,
  2223. "v_1D"::Cstring, phL.vD::Ptr{Cdouble}, PDI_OUT::Cint,
  2224. "p_1D"::Cstring, phL.pD::Ptr{Cdouble}, PDI_OUT::Cint,
  2225. "levelset_p"::Cstring, grid_p.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  2226. "levelset_u"::Cstring, grid_u.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  2227. "levelset_v"::Cstring, grid_v.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  2228. "trans_scal_1DT"::Cstring, phL.trans_scalD'::Ptr{Cdouble}, PDI_OUT::Cint,
  2229. "phi_ele_1D"::Cstring, phL.phi_eleD::Ptr{Cdouble}, PDI_OUT::Cint,
  2230. C_NULL::Ptr{Cvoid})::Cint
  2231. end
  2232. end
  2233. end
  2234. end
  2235. end
  2236. PDI_status = @ccall "libpdi".PDI_multi_expose("write_after_advection"::Cstring,
  2237. "nstep"::Cstring, num.current_iter::Ref{Clonglong}, PDI_OUT::Cint,
  2238. "time"::Cstring, num.time::Ref{Cdouble}, PDI_OUT::Cint,
  2239. "levelset_p"::Cstring, grid_p.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  2240. "levelset_u"::Cstring, grid_u.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  2241. "levelset_v"::Cstring, grid_v.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  2242. C_NULL::Ptr{Cvoid})::Cint
  2243. # if levelset && (advection || num.current_iter<2 || electrolysis_advection)
  2244. if levelset && (advection || num.current_iter<2)
  2245. try
  2246. NB_indices = update_all_ls_data(num, grid_p, grid_u, grid_v, BC_int, periodic_x, periodic_y)
  2247. catch errorLS
  2248. println(@sprintf "\n CRASHED after %d iterations \n" num.current_iter)
  2249. printstyled(color=:red, @sprintf "\n grid_p.LS not updated \n")
  2250. print(errorLS)
  2251. print(errorLS.task.exception)
  2252. return
  2253. end
  2254. # printstyled(color=:red, @sprintf "\n levelset 4:\n")
  2255. # println(grid_p.LS[1].geoL.dcap[1,1,:])
  2256. grid_p.LS[end].geoL.fresh .= false
  2257. grid_u.LS[end].geoL.fresh .= false
  2258. grid_v.LS[end].geoL.fresh .= false
  2259. get_fresh_cells!(grid_p, grid_p.LS[end].geoL, Mm1_L, grid_p.ind.all_indices)
  2260. get_fresh_cells!(grid_u, grid_u.LS[end].geoL, Mum1_L, grid_u.ind.all_indices)
  2261. get_fresh_cells!(grid_v, grid_v.LS[end].geoL, Mvm1_L, grid_v.ind.all_indices)
  2262. FRESH_L_u = findall(grid_u.LS[end].geoL.fresh)
  2263. FRESH_L_v = findall(grid_v.LS[end].geoL.fresh)
  2264. if navier_stokes
  2265. init_fresh_cells!(grid_u, veci(phL.uD,grid_u,1), veci(phL.uD,grid_u,1),
  2266. grid_u.LS[end].geoL.projection, FRESH_L_u, periodic_x, periodic_y)
  2267. init_fresh_cells!(grid_v, veci(phL.vD,grid_v,1), veci(phL.vD,grid_v,1),
  2268. grid_v.LS[end].geoL.projection, FRESH_L_v, periodic_x, periodic_y)
  2269. if num.nLS>1 #not monophasic
  2270. init_fresh_cells!(grid_u, veci(phL.uD,grid_u,2), veci(phL.uD,grid_u,1),
  2271. grid_u.LS[end].geoL.projection, FRESH_L_u, periodic_x, periodic_y)
  2272. init_fresh_cells!(grid_v, veci(phL.vD,grid_v,2), veci(phL.vD,grid_v,1),
  2273. grid_v.LS[end].geoL.projection, FRESH_L_v, periodic_x, periodic_y)
  2274. end
  2275. end
  2276. if num.solve_solid == 1
  2277. grid_p.LS[end].geoS.fresh .= false
  2278. grid_u.LS[end].geoS.fresh .= false
  2279. grid_v.LS[end].geoS.fresh .= false
  2280. get_fresh_cells!(grid_p, grid_p.LS[end].geoS, Mm1_S, grid_p.ind.all_indices)
  2281. get_fresh_cells!(grid_u, grid_u.LS[end].geoS, Mum1_S, grid_u.ind.all_indices)
  2282. get_fresh_cells!(grid_v, grid_v.LS[end].geoS, Mvm1_S, grid_v.ind.all_indices)
  2283. FRESH_S_u = findall(grid_u.LS[end].geoS.fresh)
  2284. FRESH_S_v = findall(grid_v.LS[end].geoS.fresh)
  2285. if navier_stokes
  2286. init_fresh_cells!(grid_u, veci(phL.uD,grid_u,1), veci(phL.uD,grid_u,1),
  2287. grid_u.LS[end].geoL.projection, FRESH_L_u, periodic_x, periodic_y)
  2288. init_fresh_cells!(grid_v, veci(phL.vD,grid_v,1), veci(phL.vD,grid_v,1),
  2289. grid_v.LS[end].geoL.projection, FRESH_L_v, periodic_x, periodic_y)
  2290. if num.nLS>1 #not monophasic
  2291. init_fresh_cells!(grid_u, veci(phL.uD,grid_u,2), veci(phL.uD,grid_u,1),
  2292. grid_u.LS[end].geoL.projection, FRESH_L_u, periodic_x, periodic_y)
  2293. init_fresh_cells!(grid_v, veci(phL.vD,grid_v,2), veci(phL.vD,grid_v,1),
  2294. grid_v.LS[end].geoL.projection, FRESH_L_v, periodic_x, periodic_y)
  2295. end
  2296. end
  2297. end
  2298. if iszero(num.current_iter%num.save_every) || num.current_iter==num.max_iterations
  2299. snap = num.current_iter÷num.save_every+1
  2300. if save_radius
  2301. radius[snap] = find_radius(grid_p, grid_p.LS[1])
  2302. end
  2303. if hill
  2304. a = zeros(length(grid_p.LS[1].MIXED))
  2305. for i in eachindex(grid_p.LS[1].MIXED)
  2306. a[i] = grid_p.LS[1].geoL.projection[grid_p.LS[1].MIXED[i]].pos.y
  2307. end
  2308. radius[snap] = mean(a)
  2309. end
  2310. # if save_length
  2311. # fwd.length[snap] = arc_length2(grid_p.LS[1].geoS.projection, grid_p.LS[1].MIXED)
  2312. # end
  2313. end
  2314. end
  2315. if num.nLS>1 #not monophasic
  2316. intfc_vtx_x,intfc_vtx_y,intfc_vtx_field,intfc_vtx_connectivities,intfc_vtx_num, intfc_seg_num = convert_interfacial_D_to_segments(num,grid_p,phL.TD,1,2)
  2317. barycenter_x_coord = mean(intfc_vtx_x)
  2318. PDI_status = @ccall "libpdi".PDI_multi_expose("update_levelset"::Cstring,
  2319. "nstep"::Cstring, num.current_iter ::Ref{Clonglong}, PDI_OUT::Cint,
  2320. "time"::Cstring, num.time::Ref{Cdouble}, PDI_OUT::Cint,
  2321. "levelset_p"::Cstring, grid_p.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  2322. "levelset_u"::Cstring, grid_u.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  2323. "levelset_v"::Cstring, grid_v.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  2324. "intfc_vtx_num"::Cstring, intfc_vtx_num::Ref{Clonglong}, PDI_OUT::Cint,
  2325. "intfc_seg_num"::Cstring, intfc_seg_num::Ref{Clonglong}, PDI_OUT::Cint,
  2326. "intfc_vtx_x"::Cstring, intfc_vtx_x::Ptr{Cdouble}, PDI_OUT::Cint,
  2327. "intfc_vtx_y"::Cstring, intfc_vtx_y::Ptr{Cdouble}, PDI_OUT::Cint,
  2328. "intfc_vtx_field"::Cstring, intfc_vtx_field::Ptr{Cdouble}, PDI_OUT::Cint,
  2329. "intfc_vtx_connectivities"::Cstring, intfc_vtx_connectivities::Ptr{Clonglong}, PDI_OUT::Cint,
  2330. "barycenter_x_coord"::Cstring, barycenter_x_coord::Ref{Cdouble}, PDI_OUT::Cint,
  2331. C_NULL::Ptr{Cvoid})::Cint
  2332. end
  2333. #endregion Advection
  2334. #region old Navier-Stokes block
  2335. # cf old_Navier_Stokes_block.jl
  2336. #endregion old Navier-Stokes block
  2337. #region end loop post-processing
  2338. if (num.one_fluid_model == 1 && num.solve_Navier_Stokes_liquid_phase == 1)
  2339. # interpolate_staggered_u_v_to_scalar_grid_one_fluid_or_one_phase!(num,grid_p,grid_u,grid_v,phL.u,phL.v,tmp_vec_p,tmp_vec_p0)
  2340. tmp_vec_p .= 0.0
  2341. tmp_vec_p0 .= 0.0
  2342. for j = 1:grid_p.ny
  2343. for i = 1:grid_p.nx
  2344. tmp_vec_p[j,i] =(phL.u[j,i]+phL.u[j,i+1])/2
  2345. tmp_vec_p0[j,i]=(phL.v[j,i]+phL.v[j+1,i])/2
  2346. end
  2347. end
  2348. #TODO compute once, write once
  2349. update_one_fluid_density_viscosity(num,grid_p,grid_u,grid_v,volume_fraction,levelset_one_fluid,rho_one_fluid,
  2350. rho_one_fluid_u,rho_one_fluid_v,mu_one_fluid,tmp_vec_p0)
  2351. end
  2352. #endregion end loop post-processing
  2353. # cD, cL, D, L = force_coefficients!(num, grid_p, grid_u, grid_v, op.opL, fwd, phL; step = num.current_iter+1, saveCoeffs = false)
  2354. # if iszero(num.current_iter%num.save_every) || num.current_iter==num.max_iterations
  2355. # snap = num.current_iter÷num.save_every+1
  2356. # if num.current_iter==num.max_iterations
  2357. # snap = size(fwd.T,1)
  2358. # end
  2359. # fwd.t[snap] = num.time
  2360. # @views fwd.V[snap,:,:] .= grid_p.V
  2361. # if advection
  2362. # fwdS.Vratio[snap] = volume(grid_p.LS[end].geoS) / V0S
  2363. # fwdL.Vratio[snap] = volume(grid_p.LS[end].geoL) / V0L
  2364. # end
  2365. # end
  2366. # @views fwd.Cd[num.current_iter+1] = cD
  2367. # @views fwd.Cl[num.current_iter+1] = cL
  2368. # # @views fwd.radius[num.current_iter+1] = num.current_radius
  2369. # PDI (IO)
  2370. if electrolysis
  2371. if num.io_pdi>0
  2372. try
  2373. # printstyled(color=:red, @sprintf "\n PDI test \n" )
  2374. # phi_array=phL.phi_ele #do not transpose since python row major
  2375. # Compute electrical current, interpolate velocity on scalar grid_p
  2376. # if num.electrical_potential>0 compute_grad_phi_ele!(num, grid_p, grid_u, grid_v, phL, phS, op.opC_pL, op.opC_pS) #TODO current
  2377. if num.electrical_potential>0
  2378. compute_grad_phi_ele!(num, grid_p, grid_u, grid_v, grid_u.LS[end], grid_v.LS[end], phL,
  2379. op.opC_pL, elec_cond,tmp_vec_u,tmp_vec_v,tmp_vec_p,tmp_vec_p0,tmp_vec_p1) #TODO current
  2380. end
  2381. # #store in us, vs instead of Eus, Evs
  2382. # interpolate_grid_liquid!(grid_p,grid_u,grid_v,phL.Eu, phL.Ev,tmp_vec_p,tmp_vec_p0)
  2383. # #TODO i_current_mag need cond
  2384. # @ccall "libpdi".PDI_multi_expose("write_data_elec"::Cstring,
  2385. # "i_current_x"::Cstring, tmp_vec_p::Ptr{Cdouble}, PDI_OUT::Cint,
  2386. # "i_current_y"::Cstring, tmp_vec_p0::Ptr{Cdouble}, PDI_OUT::Cint,
  2387. # "i_current_mag"::Cstring, phL.i_current_mag::Ptr{Cdouble}, PDI_OUT::Cint,
  2388. # "phi_ele_1D"::Cstring, phL.phi_eleD::Ptr{Cdouble}, PDI_OUT::Cint,
  2389. # C_NULL::Ptr{Cvoid})::Cint
  2390. # interpolate_grid_liquid!(grid_p,grid_u,grid_v,phL.Eu, phL.Ev,Eus,Evs)
  2391. interpolate_staggered_u_v_to_scalar_grid_one_fluid_or_one_phase!(num,grid_p,grid_u,grid_v,phL.u,phL.v,tmp_vec_p,tmp_vec_p0)
  2392. # num.iLSpdi = 1 # TODO all grid_p.LS
  2393. # Exposing data to PDI for IO
  2394. # if writing "D" array (bulk, interface, border), add "_1D" to the name
  2395. PDI_status = @ccall "libpdi".PDI_multi_expose("write_data"::Cstring,
  2396. "nstep"::Cstring, num.current_iter::Ref{Clonglong}, PDI_OUT::Cint,
  2397. "time"::Cstring, num.time::Ref{Cdouble}, PDI_OUT::Cint,
  2398. "timestep"::Cstring, num.timestep_n::Ref{Cdouble}, PDI_OUT::Cint,
  2399. "nx"::Cstring, grid_p.nx::Ref{Clonglong}, PDI_OUT::Cint,
  2400. "ny"::Cstring, grid_p.ny::Ref{Clonglong}, PDI_OUT::Cint,
  2401. "u_1D"::Cstring, phL.uD::Ptr{Cdouble}, PDI_OUT::Cint,
  2402. "v_1D"::Cstring, phL.vD::Ptr{Cdouble}, PDI_OUT::Cint,
  2403. "p_1D"::Cstring, phL.pD::Ptr{Cdouble}, PDI_OUT::Cint,
  2404. "levelset_p"::Cstring, grid_p.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  2405. "levelset_u"::Cstring, grid_u.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  2406. "levelset_v"::Cstring, grid_v.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  2407. "trans_scal_1DT"::Cstring, phL.trans_scalD'::Ptr{Cdouble}, PDI_OUT::Cint,
  2408. "phi_ele_1D"::Cstring, phL.phi_eleD::Ptr{Cdouble}, PDI_OUT::Cint,
  2409. "velocity_x"::Cstring, tmp_vec_p::Ptr{Cdouble}, PDI_OUT::Cint,
  2410. "velocity_y"::Cstring, tmp_vec_p0::Ptr{Cdouble}, PDI_OUT::Cint,
  2411. "radius"::Cstring, num.current_radius::Ref{Cdouble}, PDI_OUT::Cint,
  2412. C_NULL::Ptr{Cvoid})::Cint
  2413. catch error
  2414. printstyled(color=:red, @sprintf "\n PDI error \n")
  2415. print(error)
  2416. printstyled(color=:red, @sprintf "\n PDI error \n")
  2417. end
  2418. end #if io_pdi
  2419. if num.status == 1 #due to num.nH2<0...
  2420. return
  2421. end
  2422. #region test NaN
  2423. if num.solve_solid == 1
  2424. if (any(isnan, phL.uD) || any(isnan, phL.vD) || any(isnan, phL.TD) ||
  2425. any(isnan, phS.uD) || any(isnan, phS.vD) || any(isnan, phS.TD) ||
  2426. any(isnan, phL.trans_scalD) || any(isnan, phL.phi_eleD) ||
  2427. norm(phL.u) > 1e8 || norm(phL.T) > 1e8 ||
  2428. norm(phS.u) > 1e8 || norm(phS.T) > 1e8 ||
  2429. # norm(phL.trans_scal) > 1e8 ||
  2430. norm(phL.phi_ele) > 1e8
  2431. # ||
  2432. # any(phL.trans_scal .<0)
  2433. )
  2434. println(@sprintf "\n CRASHED start \n")
  2435. print("\n phL.uD: ",any(isnan, phL.uD) , "\n phL.vD: ",any(isnan, phL.vD) , "\n phL.TD: ",any(isnan, phL.TD) ,
  2436. "\n phS.uD: ",any(isnan, phS.uD) , "\n phS.vD: ",any(isnan, phS.vD) , "\n phS.TD: ",any(isnan, phS.TD) ,
  2437. "\n phL.trans_scalD: ",any(isnan, phL.trans_scalD) , "\n phL.phi_eleD: ",any(isnan, phL.phi_eleD) ,
  2438. "\n phL.u: ",norm(phL.u) > 1e8 , "\n phS.u: ",norm(phS.u) > 1e8 , "\n phL.T: ",norm(phL.T) > 1e8 ,
  2439. "\n phS.T: ",norm(phS.T) > 1e8 , "\n phL.trans_scal: ",norm(phL.trans_scal) > 1e8 ,
  2440. "\n phL.phi_ele: ",norm(phL.phi_ele) > 1e8,"\n any(phL.trans_scal .<0): ", any(phL.trans_scal .<0))
  2441. num.status = 1
  2442. end
  2443. else
  2444. if (any(isnan, phL.uD) || any(isnan, phL.vD) || any(isnan, phL.TD) ||
  2445. any(isnan, phL.trans_scalD) || any(isnan, phL.phi_eleD) ||
  2446. norm(phL.u) > 1e8 || norm(phL.T) > 1e8 ||
  2447. # norm(phL.trans_scal) > 1e8 ||
  2448. norm(phL.phi_ele) > 1e8
  2449. # ||
  2450. # any(phL.trans_scal .<0)
  2451. )
  2452. println(@sprintf "\n CRASHED start \n")
  2453. # println(@sprintf "\n CRASHED after %d iterations \n" num.current_iter)
  2454. print("\n phL.uD: ",any(isnan, phL.uD) , "\n phL.vD: ",any(isnan, phL.vD) , "\n phL.TD: ",any(isnan, phL.TD) ,
  2455. "\n phL.trans_scalD: ",any(isnan, phL.trans_scalD) , "\n phL.phi_eleD: ",any(isnan, phL.phi_eleD) ,
  2456. "\n phL.u: ",norm(phL.u) > 1e8, "\n phL.T: ",norm(phL.T) > 1e8 ,
  2457. "\n phL.trans_scal: ",norm(phL.trans_scal) > 1e8 ,
  2458. "\n phL.phi_ele: ",norm(phL.phi_ele) > 1e8,"\n any(phL.trans_scal .<0): ", any(phL.trans_scal .<0))
  2459. num.status = 1
  2460. end
  2461. end
  2462. if num.status == 1
  2463. PDI_status = @ccall "libpdi".PDI_multi_expose("print_variables"::Cstring,
  2464. "nstep"::Cstring, num.current_iter ::Ref{Clonglong}, PDI_OUT::Cint,
  2465. "time"::Cstring, num.time::Ref{Cdouble}, PDI_OUT::Cint,
  2466. "u_1D"::Cstring, phL.uD::Ptr{Cdouble}, PDI_OUT::Cint,
  2467. "v_1D"::Cstring, phL.vD::Ptr{Cdouble}, PDI_OUT::Cint,
  2468. "p_1D"::Cstring, phL.pD::Ptr{Cdouble}, PDI_OUT::Cint,
  2469. "levelset_p"::Cstring, grid_p.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  2470. "levelset_u"::Cstring, grid_u.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  2471. "levelset_v"::Cstring, grid_v.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  2472. "trans_scal_1DT"::Cstring, phL.trans_scalD'::Ptr{Cdouble}, PDI_OUT::Cint,
  2473. "phi_ele_1D"::Cstring, phL.phi_eleD::Ptr{Cdouble}, PDI_OUT::Cint,
  2474. C_NULL::Ptr{Cvoid})::Cint
  2475. return num.current_iter
  2476. end
  2477. else #not electrolysis
  2478. if num.solve_solid == 1
  2479. if (any(isnan, phL.uD) || any(isnan, phL.vD) || any(isnan, phL.TD) ||
  2480. any(isnan, phS.uD) || any(isnan, phS.vD) || any(isnan, phS.TD) ||
  2481. norm(phL.u) > 1e8 || norm(phS.u) > 1e8 || norm(phL.T) > 1e8 || norm(phS.T) > 1e8)
  2482. println(@sprintf "\n CRASHED after %d iterations \n" num.current_iter)
  2483. num.status = 1
  2484. return
  2485. end
  2486. else
  2487. if (any(isnan, phL.uD) || any(isnan, phL.vD) || any(isnan, phL.TD) ||
  2488. norm(phL.u) > 1e8 || norm(phL.T) > 1e8 )
  2489. println(@sprintf "\n CRASHED after %d iterations \n" num.current_iter)
  2490. num.status = 1
  2491. return
  2492. end
  2493. end
  2494. end #if electrolysis
  2495. #endregion test NaN
  2496. #region update iter number and time
  2497. # num.current_iter += 1
  2498. if num.time + num.timestep_n > num.end_time
  2499. print("\n num.time + num.timestep_n > num.end_time, break")
  2500. break
  2501. end
  2502. #endregion update iter number and time
  2503. end
  2504. #endregion time loop
  2505. #region print end
  2506. if verbose
  2507. try
  2508. printstyled(color=:blue, @sprintf "\n Final iteration : %d (%d%%) | t = %.2e \n" (num.current_iter-1) 100*(num.current_iter-1)/num.max_iterations num.time)
  2509. print("\n num.time ",num.time," stop_simulation ",num.stop_simulation)
  2510. print("\n num.time ",num.time," num.end_time",num.end_time,"num.timestep_n",num.timestep_n)
  2511. print("\n")
  2512. if stefan && advection
  2513. print(@sprintf "V_mean = %.2e V_max = %.2e V_min = %.2e V_stdev = %.5f\n" mean(grid_p.V[grid_p.LS[1].MIXED]) findmax(grid_p.V[grid_p.LS[1].MIXED])[1] findmin(grid_p.V[grid_p.LS[1].MIXED])[1] std(grid_p.V[grid_p.LS[1].MIXED]))
  2514. print(@sprintf "κ_mean = %.2e κ_max = %.2e κ_min = %.2e κ_stdev = %.5f\n" mean(grid_p.LS[1].κ[grid_p.LS[1].MIXED]) findmax(grid_p.LS[1].κ[grid_p.LS[1].MIXED])[1] findmin(grid_p.LS[1].κ[grid_p.LS[1].MIXED])[1] std(grid_p.LS[1].κ[grid_p.LS[1].MIXED]))
  2515. end
  2516. if free_surface && advection
  2517. # print(@sprintf "Vol_ratio = %.3f%%\n" (volume(grid_p.LS[end].geoL) / V0L * 100))
  2518. print(@sprintf "V_mean = %.2e V_max = %.2e V_min = %.2e V_stdev = %.5f\n" mean(grid_p.V[grid_p.LS[1].MIXED]) findmax(grid_p.V[grid_p.LS[1].MIXED])[1] findmin(grid_p.V[grid_p.LS[1].MIXED])[1] std(grid_p.V[grid_p.LS[1].MIXED]))
  2519. print(@sprintf "κ_mean = %.2e κ_max = %.2e κ_min = %.2e κ_stdev = %.5f\n" mean(grid_p.LS[1].κ[grid_p.LS[1].MIXED]) findmax(grid_p.LS[1].κ[grid_p.LS[1].MIXED])[1] findmin(grid_p.LS[1].κ[grid_p.LS[1].MIXED])[1] std(grid_p.LS[1].κ[grid_p.LS[1].MIXED]))
  2520. end
  2521. if navier_stokes
  2522. if ns_solid_phase
  2523. normuS = norm(phS.u)
  2524. normvS = norm(phS.v)
  2525. normpS = norm(phS.p.*num.timestep_n)
  2526. print("$(@sprintf("norm(uS) %.6e", normuS))\t$(@sprintf("norm(vS) %.6e", normvS))\t$(@sprintf("norm(pS) %.6e", normpS))\n")
  2527. end
  2528. if ns_liquid_phase
  2529. normuL = norm(phL.u)
  2530. normvL = norm(phL.v)
  2531. normpL = norm(phL.p.*num.timestep_n)
  2532. print("$(@sprintf("norm(uL) %.6e", normuL))\t$(@sprintf("norm(vL) %.6e", normvL))\t$(@sprintf("norm(pL) %.6e", normpL))\n")
  2533. if electrolysis
  2534. print_electrolysis_statistics(num,grid_p,phL)
  2535. PDI_status = @ccall "libpdi".PDI_multi_expose("print_variables"::Cstring,
  2536. "nstep"::Cstring, num.current_iter ::Ref{Clonglong}, PDI_OUT::Cint,
  2537. "time"::Cstring, num.time::Ref{Cdouble}, PDI_OUT::Cint,
  2538. "u_1D"::Cstring, phL.uD::Ptr{Cdouble}, PDI_OUT::Cint,
  2539. "v_1D"::Cstring, phL.vD::Ptr{Cdouble}, PDI_OUT::Cint,
  2540. "p_1D"::Cstring, phL.pD::Ptr{Cdouble}, PDI_OUT::Cint,
  2541. "levelset_p"::Cstring, grid_p.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  2542. "levelset_u"::Cstring, grid_u.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  2543. "levelset_v"::Cstring, grid_v.LS[num.iLSpdi].u::Ptr{Cdouble}, PDI_OUT::Cint,
  2544. "trans_scal_1DT"::Cstring, phL.trans_scalD'::Ptr{Cdouble}, PDI_OUT::Cint,
  2545. "phi_ele_1D"::Cstring, phL.phi_eleD::Ptr{Cdouble}, PDI_OUT::Cint,
  2546. C_NULL::Ptr{Cvoid})::Cint
  2547. end
  2548. end
  2549. end
  2550. print("\n\n")
  2551. catch
  2552. @show (length(grid_p.LS[end].MIXED))
  2553. end
  2554. end #if verbose
  2555. #endregion print end
  2556. if levelset && (save_radius || hill)
  2557. #TODO save radius
  2558. return # radius
  2559. # elseif flapping
  2560. # return xc, yc
  2561. else
  2562. return
  2563. end
  2564. end