コード例 #1
0
ファイル: test_configuration.cpp プロジェクト: lulzzz/KMCLib
// -------------------------------------------------------------------------- //
//
void Test_Configuration::testMatchLists()
{
    // Setup a configuration.
    std::vector< std::vector<double> > basis(3, std::vector<double>(3,0.0));
    basis[1][0] = 0.25;
    basis[1][1] = 0.25;
    basis[1][2] = 0.25;
    basis[2][0] = 0.75;
    basis[2][1] = 0.75;
    basis[2][2] = 0.75;

    std::vector<int> basis_sites(3);
    basis_sites[0] = 0;
    basis_sites[1] = 1;
    basis_sites[2] = 2;

    std::vector<std::string> basis_elements(3);
    basis_elements[0] = "A";
    basis_elements[1] = "B";
    basis_elements[2] = "B";

    // Make a 37x18x19 structure.
    const int nI = 37;
    const int nJ = 18;
    const int nK = 19;
    const int nB = 3;

    // Coordinates and elements.
    std::vector<std::vector<double> > coordinates;
    std::vector<std::string> elements;

    for (int i = 0; i < nI; ++i)
    {
        for (int j = 0; j < nJ; ++j)
        {
            for (int k = 0; k < nK; ++k)
            {
                for (int b = 0; b < nB; ++b)
                {
                    std::vector<double> c(3);
                    c[0] = i + basis[b][0];
                    c[1] = j + basis[b][1];
                    c[2] = k + basis[b][2];
                    coordinates.push_back(c);
                    elements.push_back(basis_elements[b]);
                }
            }
        }
    }

    elements[0]    = "V";
    elements[216]  = "V";
    elements[1434] = "V";
    elements[2101] = "V";

    // Possible types.
    std::map<std::string, int> possible_types;
    possible_types["*"] = 0;
    possible_types["A"] = 1;
    possible_types["B"] = 2;
    possible_types["V"] = 3;

    // Setup the configuration.
    Configuration configuration(coordinates, elements, possible_types);

    // Setup the lattice map.
    std::vector<int> repetitions(3);
    repetitions[0] = nI;
    repetitions[1] = nJ;
    repetitions[2] = nK;
    std::vector<bool> periodicity(3, true);
    LatticeMap lattice_map(nB, repetitions, periodicity);

    // Try to access the match lists before initialization. They should be
    // empty.
    CPPUNIT_ASSERT( configuration.minimalMatchList(10).empty()   );
    CPPUNIT_ASSERT( configuration.minimalMatchList(2101).empty() );
    CPPUNIT_ASSERT( configuration.minimalMatchList(1434).empty() );

    // Init the match lists.
    configuration.initMatchLists(lattice_map, 1);

    // This did something.
    CPPUNIT_ASSERT( !configuration.minimalMatchList(10).empty()   );
    CPPUNIT_ASSERT( !configuration.minimalMatchList(2101).empty() );
    CPPUNIT_ASSERT( !configuration.minimalMatchList(1434).empty() );

    // Get the match list the hard way.
    const std::vector<MinimalMatchListEntry> ref_1434 = \
        configuration.minimalMatchList( 1434,
                                        lattice_map.neighbourIndices(1434),
                                        lattice_map);
    // Check the size.
    CPPUNIT_ASSERT_EQUAL( static_cast<int>(ref_1434.size()),
                          static_cast<int>(configuration.minimalMatchList(1434).size()) );

    // Check the values.
    for (size_t i = 0; i < ref_1434.size(); ++i)
    {
        CPPUNIT_ASSERT_EQUAL( ref_1434[i].match_type,
                              configuration.minimalMatchList(1434)[i].match_type );
        CPPUNIT_ASSERT_EQUAL( ref_1434[i].update_type,
                              configuration.minimalMatchList(1434)[i].update_type );
        CPPUNIT_ASSERT_EQUAL( ref_1434[i].index,
                              configuration.minimalMatchList(1434)[i].index );
        CPPUNIT_ASSERT_DOUBLES_EQUAL( ref_1434[i].distance,
                                      configuration.minimalMatchList(1434)[i].distance,
                                      1.0e-14 );
        CPPUNIT_ASSERT_DOUBLES_EQUAL( ref_1434[i].coordinate.x(),
                                      configuration.minimalMatchList(1434)[i].coordinate.x(),
                                      1.0e-14 );
        CPPUNIT_ASSERT_DOUBLES_EQUAL( ref_1434[i].coordinate.y(),
                                      configuration.minimalMatchList(1434)[i].coordinate.y(),
                                      1.0e-14 );
        CPPUNIT_ASSERT_DOUBLES_EQUAL( ref_1434[i].coordinate.z(),
                                      configuration.minimalMatchList(1434)[i].coordinate.z(),
                                      1.0e-14 );

    }

    // Setup a process that changes V to B.

    // Get a process that finds a V between two B and turns one of
    // the Bs into an A.
    std::vector<std::string> process_elements1(3);
    process_elements1[0] = "V";
    process_elements1[1] = "B";
    process_elements1[2] = "B";

    std::vector<std::string> process_elements2(3);
    process_elements2[0] = "B";
    process_elements2[1] = "A";
    process_elements2[2] = "B";

    std::vector<std::vector<double> > process_coordinates(3, std::vector<double>(3, 0.0));

    process_coordinates[1][0] = -0.25;
    process_coordinates[1][1] = -0.25;
    process_coordinates[1][2] = -0.25;
    process_coordinates[2][0] =  0.25;
    process_coordinates[2][1] =  0.25;
    process_coordinates[2][2] =  0.25;

    const double rate = 13.7;
    Configuration c1(process_coordinates, process_elements1, possible_types);
    Configuration c2(process_coordinates, process_elements2, possible_types);
    Process p(c1, c2, rate, basis_sites);

    // Now, add index 1434 to the process.
    // We know by construction that these match.
    p.addSite(1434, 0.0);

    // For site 1434
    // 350 changes from 1 to 0
    // 1434 changes from 2 to 1
    // All other must remain unchanged.
    CPPUNIT_ASSERT_EQUAL( configuration.types()[1434], 3 );
    CPPUNIT_ASSERT_EQUAL( configuration.types()[350],  2 );
    CPPUNIT_ASSERT_EQUAL( configuration.types()[1433], 2 );
    CPPUNIT_ASSERT_EQUAL( configuration.types()[349],  2 );
    CPPUNIT_ASSERT_EQUAL( configuration.types()[351],  1 );
    CPPUNIT_ASSERT_EQUAL( configuration.types()[2517], 1 );

    // Peform the process.
    configuration.performProcess(p, 1434);

    // Check that the types were correctly updated.
    CPPUNIT_ASSERT_EQUAL( configuration.types()[1434], 2 );
    CPPUNIT_ASSERT_EQUAL( configuration.types()[350],  1 );
    CPPUNIT_ASSERT_EQUAL( configuration.types()[1433], 2 );
    CPPUNIT_ASSERT_EQUAL( configuration.types()[349],  2 );
    CPPUNIT_ASSERT_EQUAL( configuration.types()[351],  1 );
    CPPUNIT_ASSERT_EQUAL( configuration.types()[2517], 1 );

    // Check that updating the matchlist gets us the correct values.
    configuration.updateMatchList(1434);

    // Reference.
    const std::vector<MinimalMatchListEntry> ref2_1434 =        \
        configuration.minimalMatchList( 1434,
                                        lattice_map.neighbourIndices(1434),
                                        lattice_map);
    // Check the size.
    CPPUNIT_ASSERT_EQUAL( static_cast<int>(ref2_1434.size()),
                          static_cast<int>(configuration.minimalMatchList(1434).size()) );

    // Check the values.
    for (size_t i = 0; i < ref2_1434.size(); ++i)
    {
        CPPUNIT_ASSERT_EQUAL( ref2_1434[i].match_type,
                              configuration.minimalMatchList(1434)[i].match_type );
        CPPUNIT_ASSERT_EQUAL( ref2_1434[i].update_type,
                              configuration.minimalMatchList(1434)[i].update_type );
        CPPUNIT_ASSERT_EQUAL( ref2_1434[i].index,
                              configuration.minimalMatchList(1434)[i].index );
        CPPUNIT_ASSERT_DOUBLES_EQUAL( ref2_1434[i].distance,
                                      configuration.minimalMatchList(1434)[i].distance,
                                      1.0e-14 );
        CPPUNIT_ASSERT_DOUBLES_EQUAL( ref2_1434[i].coordinate.x(),
                                      configuration.minimalMatchList(1434)[i].coordinate.x(),
                                      1.0e-14 );
        CPPUNIT_ASSERT_DOUBLES_EQUAL( ref2_1434[i].coordinate.y(),
                                      configuration.minimalMatchList(1434)[i].coordinate.y(),
                                      1.0e-14 );
        CPPUNIT_ASSERT_DOUBLES_EQUAL( ref2_1434[i].coordinate.z(),
                                      configuration.minimalMatchList(1434)[i].coordinate.z(),
                                      1.0e-14 );

    }
}
コード例 #2
0
ファイル: test_configuration.cpp プロジェクト: lulzzz/KMCLib
// -------------------------------------------------------------------------- //
//
void Test_Configuration::testPerformProcess()
{
    // Setup a realistic system.
    std::vector< std::vector<double> > basis(3, std::vector<double>(3,0.0));
    basis[1][0] = 0.25;
    basis[1][1] = 0.25;
    basis[1][2] = 0.25;
    basis[2][0] = 0.75;
    basis[2][1] = 0.75;
    basis[2][2] = 0.75;

    std::vector<int> basis_sites(3);
    basis_sites[0] = 0;
    basis_sites[1] = 1;
    basis_sites[2] = 2;
    std::vector<std::string> basis_elements(3);
    basis_elements[0] = "A";
    basis_elements[1] = "B";
    basis_elements[2] = "B";

    // Make a 37x18x19 structure.
    const int nI = 37;
    const int nJ = 18;
    const int nK = 19;
    const int nB = 3;

    // Coordinates and elements.
    std::vector<std::vector<double> > coordinates;
    std::vector<std::string> elements;

    for (int i = 0; i < nI; ++i)
    {
        for (int j = 0; j < nJ; ++j)
        {
            for (int k = 0; k < nK; ++k)
            {
                for (int b = 0; b < nB; ++b)
                {
                    std::vector<double> c(3);
                    c[0] = i + basis[b][0];
                    c[1] = j + basis[b][1];
                    c[2] = k + basis[b][2];
                    coordinates.push_back(c);
                    elements.push_back(basis_elements[b]);
                }
            }
        }
    }

    elements[0]    = "V";
    elements[216]  = "V";   // These affects process 0,1 and 3
    elements[1434] = "V";
    elements[2101] = "V";   // This affects process 0,1 and 2

    // Possible types.
    std::map<std::string, int> possible_types;
    possible_types["*"] = 0;
    possible_types["A"] = 1;
    possible_types["B"] = 2;
    possible_types["V"] = 3;

    // Setup the configuration.
    Configuration configuration(coordinates, elements, possible_types);

    // Setup the lattice map.
    std::vector<int> repetitions(3);
    repetitions[0] = nI;
    repetitions[1] = nJ;
    repetitions[2] = nK;
    std::vector<bool> periodicity(3, true);
    LatticeMap lattice_map(nB, repetitions, periodicity);

    // Init the match lists.
    configuration.initMatchLists(lattice_map, 1);

    // Get a process that finds a V between two B and turns one of
    // the Bs into an A.
    std::vector<std::string> process_elements1(3);
    process_elements1[0] = "V";
    process_elements1[1] = "B";
    process_elements1[2] = "B";

    std::vector<std::string> process_elements2(3);
    process_elements2[0] = "B";
    process_elements2[1] = "A";
    process_elements2[2] = "B";

    std::vector<std::vector<double> > process_coordinates(3, std::vector<double>(3, 0.0));

    process_coordinates[1][0] = -0.25;
    process_coordinates[1][1] = -0.25;
    process_coordinates[1][2] = -0.25;
    process_coordinates[2][0] =  0.25;
    process_coordinates[2][1] =  0.25;
    process_coordinates[2][2] =  0.25;

    const double rate = 13.7;
    Configuration c1(process_coordinates, process_elements1, possible_types);
    Configuration c2(process_coordinates, process_elements2, possible_types);
    Process p(c1, c2, rate, basis_sites);

    // Now, add index 1434 to the process.
    // We know by construction that these match.
    p.addSite(1434, 0.0);

    // For site 1434
    // 350 changes from 1 to 0
    // 1434 changes from 2 to 1
    // All other must remain unchanged.
    CPPUNIT_ASSERT_EQUAL( configuration.types()[1434], 3 );
    CPPUNIT_ASSERT_EQUAL( configuration.types()[350],  2 );
    CPPUNIT_ASSERT_EQUAL( configuration.types()[1433], 2 );
    CPPUNIT_ASSERT_EQUAL( configuration.types()[349],  2 );
    CPPUNIT_ASSERT_EQUAL( configuration.types()[351],  1 );
    CPPUNIT_ASSERT_EQUAL( configuration.types()[2517], 1 );

    // Peform the process.
    configuration.performProcess(p, 1434);

    // Check that the types were correctly updated.
    CPPUNIT_ASSERT_EQUAL( configuration.types()[1434], 2 );
    CPPUNIT_ASSERT_EQUAL( configuration.types()[350],  1 );
    CPPUNIT_ASSERT_EQUAL( configuration.types()[1433], 2 );
    CPPUNIT_ASSERT_EQUAL( configuration.types()[349],  2 );
    CPPUNIT_ASSERT_EQUAL( configuration.types()[351],  1 );
    CPPUNIT_ASSERT_EQUAL( configuration.types()[2517], 1 );

    // Check that the correct indices were added to the list of affected.
    const std::vector<int> affected = p.affectedIndices();
    CPPUNIT_ASSERT_EQUAL( affected[0], 1434 );
    CPPUNIT_ASSERT_EQUAL( affected[1], 350  );

}
コード例 #3
0
ファイル: test_hash.cpp プロジェクト: PytLab/KMCLib
// -------------------------------------------------------------------------- //
//
void Test_Hash::testHashCustomRateInput()
{
    // Setup a configuration and a process.

    // -----------------------------------------------------------------------
    // Setup a valid configuration.
    std::vector<std::vector<double> > coords(2, std::vector<double>(3, 0.0));

    // One cell with two atoms.
    coords[0][0] = 0.0;
    coords[0][1] = 0.0;
    coords[0][2] = 0.0;
    coords[1][0] = 0.5;
    coords[1][1] = 0.3;
    coords[1][2] = 0.1;

    // Setup elements.
    std::vector<std::vector<std::string> > elements(2);
    elements[0] = std::vector<std::string>(1,"A");
    elements[1] = std::vector<std::string>(1,"B");

    // Setup the mapping from element to integer.
    std::map<std::string, int> possible_types;
    possible_types["*"] = 0;
    possible_types["A"] = 1;
    possible_types["B"] = 2;
    possible_types["C"] = 3;
    possible_types["D"] = 4;
    possible_types["E"] = 5;
    possible_types["F"] = 6;

    // Construct the configuration.
    Configuration config(coords, elements, possible_types);

    // Setup a non periodic cooresponding lattice map.
    const std::vector<int> repetitions(3, 1);
    const std::vector<bool> periodicity(3, false);
    const int basis = 2;
    std::vector<int> basis_sites;
    basis_sites.push_back(1);
    basis_sites.push_back(0);

    LatticeMap lattice_map(basis, repetitions, periodicity);
    config.initMatchLists(lattice_map, 13);

    // Construct a process that should match the second index.

    // Setup the two configurations.
    std::vector<std::vector<std::string> > elements1;
    elements1.push_back(std::vector<std::string>(1,"B"));
    elements1.push_back(std::vector<std::string>(1,"A"));
    std::vector<std::vector<std::string> > elements2;
    elements2.push_back(std::vector<std::string>(1,"C"));
    elements2.push_back(std::vector<std::string>(1,"A"));
    // Setup coordinates.
    std::vector<std::vector<double> > process_coords(2,std::vector<double>(3,0.0));
    process_coords[1][0] =  -0.5;
    process_coords[1][1] =  -0.5;
    process_coords[1][2] =  -0.5;
    // The configurations.
    const Configuration config1(process_coords, elements1, possible_types);
    const Configuration config2(process_coords, elements2, possible_types);

    // Construct the process with a random rate.
    seedRandom(19, true);
    const double rate = 13.7*randomDouble01();
    const CustomRateProcess process1(config1, config2, rate, basis_sites, 12.0, std::vector<int>(0), std::vector<Coordinate>(0), 917);
    const CustomRateProcess process2(config1, config2, rate, basis_sites, 12.0, std::vector<int>(0), std::vector<Coordinate>(0), 916);
    int index;
    // -----------------------------------------------------------------------

    {
        // Get the hash.
        index = 1;
        const unsigned long int hash1 = hashCustomRateInput(index, process1, config);
        const unsigned long int ref1 = 18009609292013583759u;
        CPPUNIT_ASSERT_EQUAL(hash1, ref1);

        // Get the hash.
        index = 0;
        const unsigned long int hash0 = hashCustomRateInput(index, process1, config);
        const unsigned long int ref0 = 4224368175550234772u;
        CPPUNIT_ASSERT_EQUAL(hash0, ref0);
    }

    {
        // Check against another process that differs in the process number.
        index = 1;
        const unsigned long int hash1 = hashCustomRateInput(index, process2, config);
        const unsigned long int ref1 = 4824710481459367137u;
        CPPUNIT_ASSERT_EQUAL(hash1, ref1);

        index = 0;
        const unsigned long int hash0 = hashCustomRateInput(index, process2, config);
        const unsigned long int ref0 = 17780468236463825071u;
        CPPUNIT_ASSERT_EQUAL(hash0, ref0);
    }

    // Check performance.
    if (false)
    {
        double t1 = cpu_time();
        unsigned long int hash_loop;
        for (int i = 0; i < 10000000; ++i)
        {
            hash_loop = hashCustomRateInput(index, process2, config);
        }
        double t2 = cpu_time();

        // Printout to avoid optimization.
        printf("hash0 %lx\n %e", hash_loop, (t2-t1)/10000000);
    }
}