Giter Site home page Giter Site logo

Comments (8)

richardotis avatar richardotis commented on June 13, 2024

Decorator concept

def CustomModel(Model):
    # pure=True (default) means it doesn't mutate self.models
    @contribution
    def custom_energy(phase, param_search):
        # ...
        return result
    @contribution(pure=False, order=2)
    def custom_energy2(phase, param_search, models):
        # ...
        # models can be mutated here to modify self.models
        return result
    @contribution(pure=False, order=3)
    def custom_energy3(phase, param_search, models):
        # ...
        # models can be mutated here to modify self.models
        # models already contains custom_energy2 contribution due to order argument
        return result

from pycalphad.

richardotis avatar richardotis commented on June 13, 2024

Decorator concept 2

class CustomModel(Model):
    @contribution(order=0)
    def custom_energy(self, phase, param_search):
        # ...
        return result
    @contribution(order=2)
    def custom_energy2(self, phase, param_search):
        # ...
        # self.models can be mutated here
        return result
    @contribution(order=3)
    def custom_energy3(self, phase, param_search):
        # ...
        # self.models can be mutated here
        # self.models already contains custom_energy2 contribution due to order argument
        return result

I'm not happy with how subclassing + the order kwarg can hide contributions in difficult-to-debug places.

from pycalphad.

richardotis avatar richardotis commented on June 13, 2024

Metaclass concept

We use a metaclass (not shown but theoretically defined for Model) to generate a build_phase member function at definition time, based on the contents of a magic contributions attribute. This would have the nice property of being backwards-compatible, since we can choose not to overwrite build_phase if it's defined by the user. (We can also define contributions using the metaclass if the user doesn't define it.)

To deal with the awkward issue that the order-disorder contribution should always be last (unless the user is doing something special), we can check for this case in the metaclass and produce a warning. (We can turn the warning off using a magic __disable_warnings__ attribute.)

class CustomModel(Model):
    contributions = [('ref', 'reference_energy'), ('idmix', 'ideal_mixing_energy'),
                     ('xsmix', 'excess_mixing_energy'), ('mag', 'magnetic_energy'),
                     ('custom', 'custom_energy'), ('ord', 'atomic_ordering_energy')]
    def custom_energy(self, phase, param_search):
        # ...
        return result

from pycalphad.

richardotis avatar richardotis commented on June 13, 2024

It's possible to implement the "metaclass concept" API with some simple checks in build_phase, without resorting to metaclasses, so I'm working on a proof-of-concept now. It may require us to do a breaking API change so that the atomic ordering contribution has the same function signature as the others, but I'm still investigating.

from pycalphad.

richardotis avatar richardotis commented on June 13, 2024

@bocklund Can you look at 93ba8b2 and offer comments? If you look at the included test I definitely think the proposed new API is much cleaner and simpler for the user, but I hesitate to break the build_phase and *_energy function APIs for users currently defining custom models with the method shown in the parent post. However there's probably only one user that currently does this, and I will be visiting them shortly, so maybe this API breakage isn't a big deal.

from pycalphad.

richardotis avatar richardotis commented on June 13, 2024

I've already rewritten the code for the one user I am aware of using this feature, so I'm going to consider this API breakage inconsequential. We'll note the breakage in the changelog of the next release.

from pycalphad.

richardotis avatar richardotis commented on June 13, 2024

Custom properties require no further changes since they are now easier to write.

self.CUSTPROP = (self.GM + 5).xreplace(dbe.symbols)

Then you can pass CUSTPROP to the output kwarg of calculate or equilibrium.

from pycalphad.

richardotis avatar richardotis commented on June 13, 2024

I'm more or less satisfied with how this works now, so I will close this.

from pycalphad.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.