Skip to content

CPML implementation, soft source, change of J update timestep#87

Open
Antoniahuber wants to merge 4 commits into
ImpedanCEI:mainfrom
Antoniahuber:mergedCPML
Open

CPML implementation, soft source, change of J update timestep#87
Antoniahuber wants to merge 4 commits into
ImpedanCEI:mainfrom
Antoniahuber:mergedCPML

Conversation

@Antoniahuber

@Antoniahuber Antoniahuber commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

📝 Pull Request Summary

The soft source creates continuity with the cells surrounding the injection line in x and y direction and therefore creates less noise.
The CPML is needed to absorb waves and evanescent fields reaching the boundaries. It is needed for low frequency waves and general higher absorption of outgoing waves.

🔧 Changes Made

  • Boundaries: changed the PML parameter assignment, the conductivity being activated for the PML and added split PEC/PMC boundary matrices
  • SolverFIT3D: added CPML initialization and update functions, changed J update time step, converted to a soft source. MPI update functions are missing for now!!!
  • Source: changed hard beam source to a soft beam source, added mode source and gaussian source

✅ Checklist

  • Code follows the project's style and guidelines
  • Added tests for new functionality
  • Updated documentation (mentioned in docs/ or included in examples/ and notebooks/)
  • Verified that changes do not break existing functionality (automatic tests passing)

📌 Related Issues / PRs

Closes #issue-number

@Antoniahuber Antoniahuber self-assigned this Jun 24, 2026
@Antoniahuber Antoniahuber added the enhancement New feature or request label Jun 24, 2026
@elenafuengar

elenafuengar commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

Amazing work!!! Thank you Antonia 💟

However, as discussed, we need to keep the previous PML implementation and the hard source too. Same for the un-split time-stepping. Our policy for now is to preserve legacy, at least until the first production release :)

I suggest to control the use of the new implementation by new parameters in the Solver class for the split time-stepping, then enable the CPML via 'cpml' instead of 'pml' in the boundary conditions, and the use of a soft source via an argument in for example, solver.wakesolve.

This is just a first suggestion, we can continue to iterate with the API design

@elenafuengar elenafuengar left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me know what you think of the comments! We're almost there, just missing the test.

For the test, we need a new file 014, you can use a textbook case for now that has a low reflection. In case you decide to go for this, you can keep the sources in this PR and omit my comment on sources.py

Finally, before merging, would be nice if the CPML is documented in the physicsguide.md inside the docs/, and/or shown how to use it with a new example or notebook

Comment thread wakis/boundaries.py
talpha_x, talpha_y, talpha_z = np.zeros(self.Nx), np.zeros(self.Ny), np.zeros(self.Nz)

# Fill
if self.bc_low[0].lower() == "pml":

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess in all of these it should be 'cpml'?

Comment thread wakis/boundaries.py
self.talpha = Field(self.Nx, self.Ny, self.Nz, dtype=self.dtype)
self.sigmaPml = Field(self.Nx, self.Ny, self.Nz, dtype=self.dtype)
self.tsigmaPml = Field(self.Nx, self.Ny, self.Nz, dtype=self.dtype)
sigmaPml_x, sigmaPml_y, sigmaPml_z = np.zeros(self.Nx), np.zeros(self.Ny), np.zeros(self.Nz)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you need also the kappa_x kappa_y kappa_z (etc), does it not work with only (e.g.) self.kappa.field_x?

Comment thread wakis/boundaries.py
self.talpha[:, :, :, 'y'] = talpha_y[np.newaxis, :, np.newaxis]
self.talpha[:, :, :, 'z'] = talpha_z[np.newaxis, np.newaxis, :]

del sigmaPml_x, sigmaPml_y, sigmaPml_z

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think reading the code, you could just fill the Field class directly, hence not needing to create and delete these quantities

Comment thread wakis/solverFIT3D.py
alpha_max=0.1,
sigma_factor=1,
pml_exp=4,
sourcetype="hard",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe source_type to keep the convention?

Comment thread wakis/solverFIT3D.py
self.psiEb = Field(self.Nx, self.Ny, self.Nz, use_gpu=self.use_gpu, dtype=self.dtype)
else:
self.tDsiDmuiDaC = self.iDa * self.iDmu * self.C * self.Ds
self.itDaiDepsDstC = self.iDeps * self.itDa * self.C.transpose() * self.tDs

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all this code needs to go inside boundaries.py, in a private function. Then it can be called here, something like:

if self.activate_cpml:
    self._initialize_CPML_matrices()

Feel free to change the name of course

Comment thread wakis/solverFIT3D.py
self.dtyz = mkl_sparse_mat(self.dtyz)
self.dtyx = mkl_sparse_mat(self.dtyx)
self.dtzx = mkl_sparse_mat(self.dtzx)
self.dtzy = mkl_sparse_mat(self.dtzy)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same for these, in a function (could be in solver, but not in the init

The rule of thumb is that, if it takes more than 2-5 lines, it should be a function

Comment thread wakis/sources.py
solver.E[:, :, self.zs, "x"] = Et * self.ExProfile


class GaussianPacket:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the difference with the currently implemented WavePacket? or this is your spectrum source?

Comment thread wakis/sources.py

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in general, we should the changes to this file in a different pull request, as it is not strictly related to CPML

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends Wakis’ 3D FIT solver with CPML boundary support and adds new/updated source injection models (including “soft” source updates) to reduce numerical noise and improve boundary absorption, particularly at low frequencies.

Changes:

  • Add CPML parameter initialization and CPML-specific time-stepping paths in the solver and boundary handling.
  • Introduce “soft” source/current updates and add new source types (mode packet, gaussian packet, angled wave packet).
  • Update an MPI test’s expected solver logs to include the new sourcetype field.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 13 comments.

File Description
wakis/sources.py Adds soft-source behavior and introduces new source classes (mode/gaussian/angled packets).
wakis/solverFIT3D.py Adds CPML configuration parameters, CPML stepping implementation, and soft current update support.
wakis/boundaries.py Extends boundary condition handling for CPML and adds CPML parameter initialization logic.
tests/test_007_mpi_lossy_cavity.py Updates expected solver log fields to include sourcetype.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread wakis/boundaries.py
Comment thread wakis/boundaries.py
Comment thread wakis/boundaries.py
Comment thread wakis/boundaries.py
Comment thread wakis/boundaries.py
Comment thread wakis/sources.py
Comment on lines +914 to +915
if self.tinj is None:
self.tinj = 6 * self.sigmaz
Comment thread wakis/sources.py
Comment on lines +935 to +940
if self.sigmaz is None:
self.sigmaz = 10 * np.mean(
solver.dz
) # only feasible for not to ununiform grids
if self.sigmaxy is None:
self.sigmaxy = 5 * np.mean([np.mean(solver.dx), np.mean(solver.dy)])
Comment thread wakis/sources.py
Comment on lines +1125 to +1126
if self.f is None:
self.f = c_light / self.wavelength
Comment thread wakis/sources.py
Comment on lines +1130 to +1131
if self.tinj is None:
self.tinj = 6 * self.sigmaz
Comment thread wakis/solverFIT3D.py
Comment on lines +298 to +302
# Fill PML BCs
if self.activate_cpml:
if verbose:
print("Filling CPML parameters...")
self.one_step = self._one_step_cpml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants