CPML implementation, soft source, change of J update timestep#87
CPML implementation, soft source, change of J update timestep#87Antoniahuber wants to merge 4 commits into
Conversation
|
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, This is just a first suggestion, we can continue to iterate with the API design |
There was a problem hiding this comment.
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
| 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": |
There was a problem hiding this comment.
I guess in all of these it should be 'cpml'?
| 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) |
There was a problem hiding this comment.
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?
| 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 |
There was a problem hiding this comment.
I think reading the code, you could just fill the Field class directly, hence not needing to create and delete these quantities
| alpha_max=0.1, | ||
| sigma_factor=1, | ||
| pml_exp=4, | ||
| sourcetype="hard", |
There was a problem hiding this comment.
Maybe source_type to keep the convention?
| 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 |
There was a problem hiding this comment.
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
| 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) |
There was a problem hiding this comment.
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
| solver.E[:, :, self.zs, "x"] = Et * self.ExProfile | ||
|
|
||
|
|
||
| class GaussianPacket: |
There was a problem hiding this comment.
What is the difference with the currently implemented WavePacket? or this is your spectrum source?
There was a problem hiding this comment.
I think in general, we should the changes to this file in a different pull request, as it is not strictly related to CPML
There was a problem hiding this comment.
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
sourcetypefield.
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.
| if self.tinj is None: | ||
| self.tinj = 6 * self.sigmaz |
| 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)]) |
| if self.f is None: | ||
| self.f = c_light / self.wavelength |
| if self.tinj is None: | ||
| self.tinj = 6 * self.sigmaz |
| # Fill PML BCs | ||
| if self.activate_cpml: | ||
| if verbose: | ||
| print("Filling CPML parameters...") | ||
| self.one_step = self._one_step_cpml |
📝 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
✅ Checklist
docs/or included inexamples/andnotebooks/)📌 Related Issues / PRs
Closes #issue-number