diff --git a/GRSlib/GRS.py b/GRSlib/GRS.py index 35dab1b..cf2652e 100644 --- a/GRSlib/GRS.py +++ b/GRSlib/GRS.py @@ -2,9 +2,8 @@ from GRSlib.io.input import Config from GRSlib.converters.convert_factory import convert from GRSlib.motion.scoring_factory import scoring -from GRSlib.motion.scoring import Scoring +from GRSlib.motion.scoring import Scoring, elems, get_desc_count from GRSlib.motion.motion import Gradient, Optimize, Create - import random, copy, os, glob, shutil import numpy as np @@ -165,6 +164,36 @@ def get_score(self,data): raise RuntimeError(">>> Found unmatched BASIS for target and current descriptors") return score + + def get_ensemble(self,data): + print("Get ensemble called.") + print("Using elems:", elems) + scores = None + try: + scores = self.score.ensemble_score( + n_totconfig=10, # Example value + data_path='bcc.data', # Example value + cross_weight=1.0, + self_weight=1.0, + randomize_comps=False, + mincellsize=54, + maxcellsize=55, + target_comps={'W': 1.0}, # Ensure this is a dictionary + min_typ_global='box', + soft_strength=0.0, + nelements=len(elems), # Ensure elems is defined + n_descs=get_desc_count('coupling_coefficients.yace'), + mask=None, # Set this as needed + rand_comp=1) + print("Scores returned from ensemble_score:", scores) + except Exception as e: + print(f"An error occured while calculating the ensemble score: {e}") + return None + if scores is None or len(scores) == 0: + print("No scores were calculated returning None." + raise RuntimeError("Ensemble score could not be calculated.") + + return scores def propose_structure(self): """ diff --git a/GRSlib/motion/scoring.py b/GRSlib/motion/scoring.py index 4d39f2f..cb86488 100644 --- a/GRSlib/motion/scoring.py +++ b/GRSlib/motion/scoring.py @@ -1,17 +1,35 @@ -#from GRSlib.parallel_tools import ParallelTools +from GRSlib.Ver0_Files.opt_tools import internal_generate_cell, get_desc_count, * +from GRSlib.parallel_tools import ParallelTools #from GRSlib.motion.lossfunc.moments import Moments #from GRSlib.motion.lossfunc import Gradient from GRSlib.converters.sections.lammps_base import Base, _extract_compute_np +from examples.self_test.GRS_protocol import GRSModel, GRSSampler import lammps, lammps.mliap from lammps.mliap.loader import * from functools import partial -import numpy as np - +import numpy as vnp +from GRSlib.GRS import * #Scoring has to be a class within motion because we want a consistent reference for scores, and this #refrence will be LAMMPS using a constructed potential energy surface from the representation loss function. #Sub-classes of Scoring will be versions of this representation loss function (Moments, Entropy, etc), allowing #for custom verions to be added without trouble. +n_totconfig = 10 +data_path = 'bcc.data' +cross_weight =1.000000 +self_weight = 1.000000 +randomize_comps= False # # flag to use randomized compositions for elements in the dictionary: target_comps = {'Cr':1.0 } +mincellsize = 54 +maxcellsize=55 +target_comps = {'W:1.0'} +min_typ_global='box' #box or min +soft_strength=0.0 +elems=get_desc_count('coupling_coefficients.yace',return_elems=True) +nelements= len(elems) +n_descs= get_desc_count('coupling_coefficients.yace') +rand_comp =1 + + class Scoring: # def __init__(self, pt, config, data, loss_ff, **kwargs): @@ -95,3 +113,47 @@ def _extract_commands(self,string): add_lmp_lines = [x for x in string.splitlines() if x.strip() != ''] for line in add_lmp_lines: self.lmp.command(line) + + def ensemble_score(self, n_totconfig, data_path, cross_weight, self_weight, randomize_comps, mincellsize, maxcellsize, target_comps, min_typ_global, soft_strength, nelements, n_descs, mask, rand_comp): + if mask == None: + mask = range(n_descs) + self.mask = mask # Generates the multiple structures + scores = [] # Initialize a list to store scores + + print(f"Starting ensemble_score with {n_totconfig} configurations.") # Debugging line + + for i in range(1, n_totconfig + 1): + print(f"Configuration {i}/{n_totconfig} - Using indices: {mask}") # Debugging line + + # Generate the cell + g = internal_generate_cell(i, desired_size=vnp.random.choice(range(mincellsize, maxcellsize)), template=None, desired_comps=target_comps, use_template=None, min_typ=min_typ_global, soft_strength=soft_strength) + print(g) + print(f"Cell generated for configuration {i}: {g}") # Debugging line + + em = GRSModel(nelements, n_descs, mask=mask) + sampler = GRSSampler(em, g) + em.K_cross = cross_weight + em.K_self = self_weight + + print(f"Running minimization for configuration {i}.") # Debugging line + # Run the minimization process + sampler.run("minimize 1e-6 1e-6 1000 10000") + + print(f"Minimization completed for configuration {i}. Writing data.") # Debugging line + # Write the data to a file + sampler.run("write_data %s/sample.%i.dat " % (data_path, i)) + + print(f"Data written for configuration {i}. Updating model.") # Debugging line + sampler.update_model() # Updating the model combines generated structures + + # Calculate the score for the current configuration + score = self.get_score(g) # Pass the generated structure to get_score + print(f"Score for configuration {i}: {score}") # Debugging line + + if score is None: + print(f"Score for configuration {i} is None.") # Debugging line + + scores.append(score) # Append the score to the list + + print("Final scores list:", scores) # Debugging line + return scores # Return the list of scores