Wrapper around DFT objects that allows delayed initialization of the structure. When splitting the structure into chunks for parallel simulations, we want to know all of the details of the simulation in order to ensure that each processor gets a similar amount of work. The problem with
| 625 | |
| 626 | |
| 627 | class DftObj: |
| 628 | """Wrapper around DFT objects that allows delayed initialization of the structure. |
| 629 | |
| 630 | When splitting the structure into chunks for parallel simulations, we want to know all |
| 631 | of the details of the simulation in order to ensure that each processor gets a similar |
| 632 | amount of work. The problem with DFTs is that the `add_flux` style methods immediately |
| 633 | initialize the structure and fields. So, if the user adds multiple DFT objects to the |
| 634 | simulation, the load balancing code only knows about the first one and can't split the |
| 635 | work up nicely. To circumvent this, we delay the execution of the `add_flux` methods |
| 636 | as late as possible. When `add_flux` (or `add_near2far`, etc.) is called, we: |
| 637 | |
| 638 | 1. Create an instance of the appropriate subclass of `DftObj` (`DftForce`, `DftFlux`, etc.). |
| 639 | Set its args property to the list of arguments passed to `add_flux`, and set its func |
| 640 | property to the 'real' `add_flux`, which is prefixed by an underscore. |
| 641 | |
| 642 | 2. Add this `DftObj` to the list Simulation.dft_objects. When we actually run the |
| 643 | simulation, we call `Simulation._evaluate_dft_objects`, which calls `dft.func(*args)` |
| 644 | for each dft in the list. |
| 645 | |
| 646 | If the user tries to access a property or call a function on the `DftObj` before |
| 647 | `Simulation._evaluate_dft_objects` is called, then we initialize the C++ object through |
| 648 | swigobj_attr and return the property they requested. |
| 649 | """ |
| 650 | |
| 651 | def __init__(self, func, args): |
| 652 | """Construct a `DftObj`.""" |
| 653 | self.func = func |
| 654 | self.args = args |
| 655 | self.swigobj = None |
| 656 | |
| 657 | def swigobj_attr(self, attr): |
| 658 | if self.swigobj is None: |
| 659 | self.swigobj = self.func(*self.args) |
| 660 | return getattr(self.swigobj, attr) |
| 661 | |
| 662 | @property |
| 663 | def save_hdf5(self): |
| 664 | return self.swigobj_attr("save_hdf5") |
| 665 | |
| 666 | @property |
| 667 | def load_hdf5(self): |
| 668 | return self.swigobj_attr("load_hdf5") |
| 669 | |
| 670 | @property |
| 671 | def scale_dfts(self): |
| 672 | return self.swigobj_attr("scale_dfts") |
| 673 | |
| 674 | @property |
| 675 | def remove(self): |
| 676 | return self.swigobj_attr("remove") |
| 677 | |
| 678 | @property |
| 679 | def freq(self): |
| 680 | return self.swigobj_attr("freq") |
| 681 | |
| 682 | @property |
| 683 | def where(self): |
| 684 | return self.swigobj_attr("where") |
nothing calls this directly
no outgoing calls
no test coverage detected