kill(all);
load("ecleanbase.mac");

/* ------------------------------------------------------------------------- */
/* flux */
/* ------------------------------------------------------------------------- */

eclean_Dinc:ratsubst(c,1/(sqrt(%epsilon)*sqrt(%mu)), eclean_D);
eclean_sflux:hyp_upwind_flux([-%chi*c,-c,0,c,%chi*c], eclean_Dinc);

/*
print("e-clean system flux in terms of characteristic variables:");
print(eclean_sflux);
*/

/* FIXME: eclean_V should not depend on epsilon and mu, but it does 
   For now, make cp and cm equal. */

eclean_sflux:subst(
  [cp=1/(sqrt(%epsilon)*sqrt(%mu)), 
   cm=1/(sqrt(%epsilon)*sqrt(%mu)),
   %chip=%chi,
   %chim=%chi], 
  eclean_sflux);

print("e-clean system flux in terms of physical variables:");
eclean_wflux:fullhypsimp(eclean_V.ev(eclean_sflux, 
  [sm=eclean_sminw,sp=eclean_spinw]));
print(eclean_wflux);

eclean_strongwflux:eclean_A.eclean_wm - eclean_wflux;

eclean_maxstrongdiff:fullhypsimp(
  eclean_strongwflux
  -append(max_strongwflux,matrix([0]))
  );
print("e-clean additional strong-form flux wrt Maxwell system:");
print(eclean_maxstrongdiff);

/*
eclean_simple_maxstrongdiff:1/2*append(
  c^2*(%phi[m]-%phi[p])*n
  -%chi*c*n*(n.(max_Em-max_Ep)),
  [0,0,0],
  [-c*%chi*(%phi[m]-%phi[p])
  +%chi^2*n.(max_Em-max_Ep)]);
*/
eclean_simple_maxstrongdiff:1/2*append(
  %chi*c*n*(%phi[m]-%phi[p] - n.(max_Em-max_Ep)),
  [0,0,0],
  [c*%chi*(-(%phi[m]-%phi[p]) + n.(max_Em-max_Ep))]);
assert(norm_2_squared(hypsimp(
  eclean_maxstrongdiff
  - ev(eclean_simple_maxstrongdiff, [c=1/sqrt(%epsilon*%mu)])))=0);
  
/* ------------------------------------------------------------------------- */
/* Radiation BCs */
/* ------------------------------------------------------------------------- */

eclean_radbdryspinw:makelist(
  if eclean_D[i,i] >= 0 then eclean_sminw[i,1] else 0,
i, 1, length(eclean_D))$

/*
print("Radiation boundary condition for E-divclean system:");
print(fullhypsimp(eclean_V.eclean_radbdryspinw));

*/

/* ------------------------------------------------------------------------- */
/* Better PEC */
/* ------------------------------------------------------------------------- */
/* PEC means: n x E = 0. (no tangential field)

For normal Maxwell PEC, you prescribe E+ = - E-, even though the 
normal component is wrong (it should be equal to the E- normal component).
That doesn't matter because the Maxwell flux only looks at the tangential
component. But here, it suddenly ends up mattering, so we need to prescribe
the normal component correctly.
*/

eclean_simplepecwp:covect(append(max_pecbdrywp, [%phi[m]]));
eclean_betterpecwp:covect(append(
    normalcomp(max_Em)-tangentialcomp(max_Em), max_Hm, [-%phi[m]]));
eclean_betterpecsp:fullhypsimp(
  eclean_invV.ev(eclean_betterpecwp, 
    [Em=eclean_Emins, Hm=eclean_Hmins, %phi[m]=eclean_phimins]));

print("Better PEC condition in characteristic variables:");
print(eclean_betterpecsp);

print("Better PEC condition in physical variables:");
print(eclean_betterpecwp);

eclean_flux_at_betterpec:fullhypsimp(ev(append(max_strongwflux,matrix([0]))/*eclean_strongwflux*/,
  [Ep=subrange(eclean_betterpecwp,1,3),
   Hp=subrange(eclean_betterpecwp,4,6),
   %phi[p]=eclean_betterpecwp[7,1]]));

eclean_flux_at_simplepec:fullhypsimp(ev(append(max_strongwflux,matrix([0]))/*eclean_strongwflux*/,
  [Ep=subrange(eclean_simplepecwp,1,3),
   Hp=subrange(eclean_simplepecwp,4,6),
   %phi[p]=eclean_simplepecwp[7,1]]));

assert(norm_2_squared(hypsimp(eclean_flux_at_betterpec-eclean_flux_at_simplepec))=0);

/* ------------------------------------------------------------------------- */
/* Munz et al's dysfunctional fluxes */
/* ------------------------------------------------------------------------- */

eclean_munzpecwithphi(phival):=fullhypsimp(eclean_invV.
        vstack(vstack(-eclean_Emins, eclean_Hmins), [phival]));

/*
print("Munz et al PEC boundary with phi+=0:");
print(eclean_munzpecwithphi(0));
print("Munz et al PEC boundary with phi+=phi-:");
print(eclean_munzpecwithphi(eclean_phimins));
print("Munz et al PEC boundary with phi+=-phi-:");
print(eclean_munzpecwithphi(-eclean_phimins));
*/

/* ------------------------------------------------------------------------- */
/* chi-radiation + PEC BC */
/* ------------------------------------------------------------------------- */
eclean_chiradbdryspinw:[
  -eclean_sminw[3,1],
  -eclean_sminw[4,1],
  -eclean_sminw[1,1],
  -eclean_sminw[2,1],
  %beta*eclean_sminw[5,1],
  eclean_sminw[6,1],
  eclean_sminw[7,1]
  ]$

eclean_chiradwp:fullhypsimp(eclean_V.eclean_chiradbdryspinw);

print("PEC+chirad BC for div E cleaning system");
print(eclean_chiradwp);

eclean_simple_chiradwp:append(
  -max_Em
  +2*n*(n.max_Em),
  max_Hm,
  [%phi[m]]
  );

eclean_diff_chiradwp:hypsimp(eclean_chiradwp
    - subst([c=1/sqrt(%epsilon*%mu)], eclean_simple_chiradwp));
    
/*
assert(norm_2_squared(eclean_diff_chiradwp)=0);
*/
  
/*
print("Limit of PEC+chirad BC as %phi, %chi -> 0");
print(fullhypsimp(limit(limit(
  subst([%phi[m]=phi],eclean_chiradwp),phi,0),%chi,0)));
  */

print("Flux at PEC+chirad:");
print(fullhypsimp(ev(eclean_strongwflux,
  [Ep=subrange(eclean_chiradwp,1,3),
   Hp=subrange(eclean_chiradwp,4,6),
   %phi[p]=eclean_chiradwp[7,1]])));
