Skip to content
Snippets Groups Projects
pml.mac 1.71 KiB
Newer Older
  • Learn to ignore specific revisions
  • Andreas Klöckner's avatar
    Andreas Klöckner committed
    kill(all);
    load("maxwellbase.mac");
    
    /*
    See
    S.G. Johnson, “Notes on Perfectly Matched Layers,” 2008;
    http://math.mit.edu/~stevenj/18.369/pml.pdf.
    */
    
    coords:[x,y,z];
    allvars:append([t],coords);
    
    max_E:makelist(concat(E,i),i,coords);
    max_H:makelist(concat(H,i),i,coords);
    max_w:vstack(max_E,max_H);
    
    depends(max_w,allvars);
    
    /* 
    The minus sign takes the operator from conservation form
      u_t + A u_x = 0
    into ODE form
      u_t = - A u_x.
    */
    sigexpr(c):=(1+%i*sigma[c]/omega);
    
    pml_op:-subst(makelist(concat('n, i)=1/sigexpr(i)*concat(d, i), i, coords), max_A);
    orig_op:-subst(makelist(concat('n, i)=concat(d, i), i, coords), max_A);
    
    op_rhs(op_mat, state):=block([rhss],
      rhss:op_mat.state,
    
      for c in coords do
        for var in state do
          rhss:subst(diff(var, c), concat(d, c)*var, rhss),
      rhss);
    
    pml_rhs:op_rhs(pml_op, max_w);
    orig_rhs:op_rhs(orig_op, max_w);
    
    make_ode(my_rhs, state):=
      covect(
        makelist(-%i*%omega*state[i]=my_rhs[i,1], i, 1, length(state)));
    
    pml_eqns:make_ode(pml_rhs, max_w);
    orig_eqns:make_ode(orig_rhs, max_w);
    
    kill_denom(eqns):=
      covect(makelist(
        block([eqn],
          eqn:eqns[i,1],
          for c in coords do
            if not freeof(sigma[c], eqn) then
              eqn:eqn*sigexpr(c),
          lhs(eqn)=multthru(rhs(eqn))),
        i,1,length(eqns)));
    
    simpler_eqns:kill_denom(pml_eqns);
    
    /*
    auxvar_coeffs:
    auxvars:makelist(concat(X,i),i,1,length(auxvar_coeffs));
    depends(auxvars,allvars);
    
    new_rhss:pml_rhs;
    for i: 1 thru length(auxvar_coeffs) do 
      new_rhss:ratsubst(concat(X,i), %i/omega*auxvar_coeffs[i,1], new_rhss);
    
    new_nonaux_eqns:covect(makelist(
      diff(max_w[i], t) = new_rhss[i,1], 
      i, 1, length(max_w)));
    aux_eqns:covect(makelist(diff(concat(X,i), t)=-auxvar_coeffs[i,1], i, 1, length(auxvar_coeffs)));
    */