def test_sum_modifier():
    cp = ConfigParser(io.StringIO())
    pfr = Potential_Form_Registry(cp, register_standard=True)
    pfb = Potential_Form_Builder(pfr, Modifier_Registry())

    expression = "sum(as.constant 1.0 >=1.0 as.constant 2.0, >1.5 as.constant 3.0)"

    potdef = cp._parse_multi_range("A", expression).potential_form_instance
    potential_func = pfb.create_potential_function(potdef)

    assert pytest.approx(1.0) == potential_func(0.1)
    assert pytest.approx(1.0) == potential_func(0.5)
    assert pytest.approx(2.0) == potential_func(1.1)
    assert pytest.approx(5.0) == potential_func(1.6)

    # Try another expression
    expression = ">=0 as.constant 2.0 >=1.0 sum(as.constant 1.0 >= 2.0 as.constant 0.5, >=1.5 as.constant 10.0) >= 3.0 as.zero"

    potdef = cp._parse_multi_range("A", expression).potential_form_instance
    potential_func = pfb.create_potential_function(potdef)

    assert pytest.approx(2.0) == potential_func(0)
    assert pytest.approx(1.0) == potential_func(1)
    assert pytest.approx(11.0) == potential_func(1.6)
    assert pytest.approx(10.5) == potential_func(2.1)
    assert pytest.approx(0.0) == potential_func(3.1)
def test_modifier_parse_exceptions():
    """Check that a ConfigException is raised when parse errors are encountered"""

    parser = ConfigParser(io.StringIO())
    with pytest.raises(ConfigParserException):
        parser._parse_multi_range(u"A",
                                  u"potential1 1.0 2.0 3.0 potential2 2.0")
def test_sum_modifier():
    """Test instantiation of potential forms that use the sum() modifier and multiple ranges"""
    k = u"A"
    v = u"sum( as.constant 1.0 >=1.0 as.constant 2.0, >1.5 as.constant 3.0)"

    parser = ConfigParser(io.StringIO())

    potential_forms = [
        PotentialFormInstanceTuple(
            potential_form=u'as.constant',
            parameters=[1.0],
            start=MultiRangeDefinitionTuple(range_type=u">", start=0.0),
            next=PotentialFormInstanceTuple(potential_form=u'as.constant',
                                            parameters=[2.0],
                                            start=MultiRangeDefinitionTuple(
                                                range_type=u">=", start=1.0),
                                            next=None)),
        PotentialFormInstanceTuple(potential_form=u'as.constant',
                                   parameters=[3.0],
                                   start=MultiRangeDefinitionTuple(
                                       range_type=u">", start=1.5),
                                   next=None)
    ]

    expect = PotentialModifierTuple(modifier=u"sum",
                                    potential_forms=potential_forms,
                                    start=MultiRangeDefinitionTuple(
                                        range_type=u">", start=0.0),
                                    next=None)

    expect = PairPotentialTuple(species=k, potential_form_instance=expect)
    actual = parser._parse_multi_range(k, v)
    assert DeepDiff(expect, actual) == {}
def test_sum_modifier_fs_start():
    k = u"Al->Al"
    v = u">=0 sum(dens4 0.00019850823042883 2.5 >2.5 as.zero)"

    parser = ConfigParser(io.StringIO())
    actual = parser._parse_multi_range(k, v)
    assert DeepDiff(MultiRangeDefinitionTuple(u">=", 0),
                    actual.potential_form_instance.start) == {}
def test_modifier_with_nested_modifier():
    """Test instantiation of potential forms that has a modifier that has a nested modifier in its argument list"""
    k = u"A"
    v = u"zero >=1.0 sum(nested(constant 1.0 >2 zero), buck 10.0 0.1 32.0)"

    parser = ConfigParser(io.StringIO())

    potential_forms = [
        PMT(u'nested', [
            PFI(u'constant', [1.0], MRD(u'>', 0.0),
                PFI(u'zero', [], MRD(u'>', 2), None))
        ], MRD(u'>', 0.0), None),
        PFI(u'buck', [10.0, 0.1, 32.0], MRD(u'>', 0.0), None)
    ]

    expect = PFI(u'zero', [], MRD(u'>', 0.0),
                 PMT(u'sum', potential_forms, MRD(u'>=', 1.0), None))

    expect = PairPotentialTuple(species=k, potential_form_instance=expect)
    actual = parser._parse_multi_range(k, v)
    assert DeepDiff(expect, actual) == {}
def test_sum_modifier_as_part_of_multi_range():
    """Test instantiation of potential forms that use the sum() modifier as sub-range in potential definition"""
    k = u"A"
    v = u"as.constant 2.0 >=1.0 sum(as.constant 1.0 >= 2.0 as.constant 0.5, >=1.5 as.constant 10.0) >= 3.0 zero"

    parser = ConfigParser(io.StringIO())

    potential_forms = [
        PFI(u'as.constant', [1.0], MRD(u'>', 0.0),
            PFI(u'as.constant', [0.5], MRD(u'>=', 2.0), None)),
        PFI(u'as.constant', [10.0], MRD(u'>=', 1.5), None)
    ]

    expect = PFI(
        u'as.constant', [2.0], MRD(u'>', 0.0),
        PMT(u'sum', potential_forms, MRD(u'>=', 1.0),
            PFI(u'zero', [], MRD(u'>=', 3.0), None)))

    expect = PairPotentialTuple(species=k, potential_form_instance=expect)
    actual = parser._parse_multi_range(k, v)
    assert DeepDiff(expect, actual) == {}
def test_multi_range_potential_form():
    """Tests definition of multiple ranges for potential-form definitions"""

    k = u"A"
    v = u"potential 1.0 2.0 3.0"

    parser = ConfigParser(io.StringIO())
    actual = parser._parse_multi_range(k, v)
    assert actual.species == k
    assert actual.potential_form_instance.potential_form == u"potential"
    assert actual.potential_form_instance.parameters == [1.0, 2.0, 3.0]
    assert actual.potential_form_instance.next is None
    assert actual.potential_form_instance.start == (u'>', 0.0)

    k = u"A"
    v = u">=0 potential  1.0 2.0 3.0"

    actual = parser._parse_multi_range(k, v)
    assert actual.species == k
    assert actual.potential_form_instance.potential_form == u"potential"
    assert actual.potential_form_instance.parameters == [1.0, 2.0, 3.0]
    assert actual.potential_form_instance.next is None
    assert actual.potential_form_instance.start == (u'>=', 0.0)

    k = u"A"
    v = u">=0 potential >10 potentialb 1.0 2.0 3.0"

    actual = parser._parse_multi_range(k, v)
    assert actual.species == k
    assert actual.potential_form_instance.potential_form == u"potential"
    assert actual.potential_form_instance.parameters == []
    assert actual.potential_form_instance.start == (u'>=', 0.0)
    assert actual.potential_form_instance.next.potential_form == u"potentialb"
    assert actual.potential_form_instance.next.start == (u">", 10.0)
    assert actual.potential_form_instance.next.parameters == [1.0, 2.0, 3.0]

    v = u">= 0.0 potential 1.0 2.0 3.0"
    actual = parser._parse_multi_range(k, v)
    assert actual.potential_form_instance.start == (u'>=', 0.0)

    k = u"A"
    v = u"potential 1.0 2.0 3.0 >1e1 potentialb 5.0 6.0 7.0 >=2.0E1 zero"

    actual = parser._parse_multi_range(k, v)
    assert actual.species == k
    assert actual.potential_form_instance.potential_form == u"potential"
    assert actual.potential_form_instance.parameters == [1.0, 2.0, 3.0]
    assert not actual.potential_form_instance.next is None
    assert actual.potential_form_instance.start == (u'>', 0.0)

    actual = actual.potential_form_instance.next
    assert actual.potential_form == u"potentialb"
    assert actual.parameters == [5.0, 6.0, 7.0]
    assert not actual.next is None
    assert actual.start == (u'>', 10.0)

    actual = actual.next
    assert actual.potential_form == u"zero"
    assert actual.parameters == []
    assert actual.next is None
    assert actual.start == (u'>=', 20.0)

    k = u"A"
    v = u">0.01 potential 1.0"
    actual = parser._parse_multi_range(k, v)
    assert actual.potential_form_instance.start == (u'>', 0.01)
    v = u">1e-2 potential 1.0"
    actual = parser._parse_multi_range(k, v)
    assert actual.potential_form_instance.start == (u'>', 0.01)
    v = u">1.0E-2 potential 1.0"
    actual = parser._parse_multi_range(k, v)
    assert actual.potential_form_instance.start == (u'>', 0.01)