def setup(self):
        """
        Launch the first calculation for the input structure,
        and a second calculation for a shifted volume (increased by 4 angstrom^3)
        Store the outputs of the two calcs in r0 and r1
        """
        print "Workchain node identifiers: {}".format(self.calc)

        inputs0 = generate_scf_input_params(self.inputs.structure,
                                            str(self.inputs.code),
                                            self.inputs.pseudo_family)

        initial_volume = self.inputs.structure.get_cell_volume()
        new_volume = initial_volume + 4.  # In ang^3

        scaled_structure = get_structure(self.inputs.structure, new_volume)
        inputs1 = generate_scf_input_params(scaled_structure,
                                            str(self.inputs.code),
                                            self.inputs.pseudo_family)

        self.ctx.last_structure = scaled_structure

        # Run PW
        future0 = submit(PwProcess, **inputs0)
        future1 = submit(PwProcess, **inputs1)

        # Wait to complete before next step
        return ToContext(r0=future0, r1=future1)
    def move_next_step(self, ctx):        
        """
        Main routine that reads the two previous calculations r0 and r1,
        uses the Newton's algorithm on the pressure (i.e., fits the results
        with a parabola and sets the next point to calculate to the parabola 
        minimum).
        r0 gets replaced with r1, r1 will get replaced by the results of the
        new calculation.
        """
        ddE = get_second_derivative(ctx.r0['output_parameters'], ctx.r1['output_parameters'])
        V, E, dE = get_volume_energy_and_derivative(ctx.r1['output_parameters'])
        a,b,c = get_abc(V,E,dE,ddE)

        new_step_data = {'V': V, 'E': E, 'dE': dE, 'ddE': ddE,
                         'a': a, 'b': b, 'c': c}
        ctx.steps.append(new_step_data)
        
        # Minimum of a parabola
        new_volume = -b/2./a

        # remove older step
        ctx.r0 = ctx.r1
        scaled_structure = get_structure(self.inputs.structure, new_volume)
        ctx.last_structure = scaled_structure

        inputs = generate_scf_input_params(
            scaled_structure, str(self.inputs.code), str(self.inputs.pseudo_family))

        # Run PW                                                                                                                     
        future = self.submit(PwProcess, inputs)
        # Replace r1
        return ResultToContext(r1=future)
Exemplo n.º 3
0
def run_eos_wf(codename, pseudo_family, element):
    print "Workfunction node identifiers: {}".format(Process.current().calc)
    s0 = create_diamond_fcc(Str(element))

    calcs = {}
    for label, factor in zip(labels, scale_facs):
        s = rescale(s0, Float(factor))
        inputs = generate_scf_input_params(s, str(codename),
                                           Str(pseudo_family))
        print "Running a scf for {} with scale factor {}".format(
            element, factor)
        result = run(PwCalculation, **inputs)
        print "RESULT: {}".format(result)
        calcs[label] = get_info(result)

    eos = []
    for label in labels:
        eos.append(calcs[label])

    # Return information to plot the EOS
    ParameterData = DataFactory('parameter')
    retdict = {
        'initial_structure': s0,
        'result': ParameterData(dict={'eos_data': eos})
    }

    return retdict
    def setup(self):
        """Launch the first calculation for the input structure, and a second calculation for a shifted volume."""
        scaled_structure = get_structure(self.inputs.structure)
        self.ctx.last_structure = scaled_structure

        inputs0 = generate_scf_input_params(self.inputs.structure,
                                            self.inputs.code,
                                            self.inputs.pseudo_family)
        inputs1 = generate_scf_input_params(scaled_structure, self.inputs.code,
                                            self.inputs.pseudo_family)

        # Run two `PwCalculations`
        future0 = self.submit(PwCalculation, **inputs0)
        future1 = self.submit(PwCalculation, **inputs1)

        # Wait for them to complete before going to the next step
        return ToContext(r0=future0, r1=future1)
    def init(self, ctx):
        """
        Launch the first calculation for the input structure,
        and a second calculation for a shifted volume (increased by 4 angstrom^3)
        Store the outputs of the two calcs in r0 and r1
        """
        inputs0 = generate_scf_input_params(
            self.inputs.structure, str(self.inputs.code), str(self.inputs.pseudo_family))

        initial_volume = self.inputs.structure.get_cell_volume()
        new_volume = initial_volume + 4. # In ang^3

        scaled_structure = get_structure(self.inputs.structure, new_volume)
        inputs1 = generate_scf_input_params(
            scaled_structure, str(self.inputs.code), str(self.inputs.pseudo_family))

        ctx.last_structure = scaled_structure

        # Run PW
        future0 = self.submit(PwProcess, inputs0)
        future1 = self.submit(PwProcess, inputs1)

        # Wait to complete before next step
        return ResultToContext(r0=future0, r1=future1)
Exemplo n.º 6
0
def run_eos_wf(codename, pseudo_family, element):
	print "Workfunction node pk: {}".format(registry.current_calc_node)
	#Instantiate a JobCalc process and create basic structure
	JobCalc = PwCalculation.process()
	s0 = create_diamond_fcc(Str(element))
	eos=[]
	scale_facs = (0.98, 0.99, 1.0, 1.02, 1.04)
	for factor in  scale_facs:
		s = rescale(s0,Float(factor))
		inputs = generate_scf_input_params(
			s, str(codename), str(pseudo_family))
		print "Running a scf for {} with scale factor {}".format(
			element, factor)
	calc_results = run(JobCalc,**inputs)
	eos.append(get_info(calc_results))
	#Return information to plot the EOS
	ParameterData = DataFactory("parameter")
	return {'initial_structure': s0,'result': ParameterData(dict={'eos_data': eos})}
    def move_next_step(self):
        """
        Main routine that reads the two previous calculations r0 and r1,
        uses the Newton's algorithm on the pressure (i.e., fits the results
        with a parabola and sets the next point to calculate to the parabola 
        minimum).
        r0 gets replaced with r1, r1 will get replaced by the results of the
        new calculation.
        """
        r0_out = self.ctx.r0.get_outputs_dict()
        r1_out = self.ctx.r1.get_outputs_dict()
        ddE = get_second_derivative(r0_out['output_parameters'],
                                    r1_out['output_parameters'])
        V, E, dE = get_volume_energy_and_derivative(
            r1_out['output_parameters'])
        a, b, c = get_abc(V, E, dE, ddE)

        new_step_data = {
            'V': V,
            'E': E,
            'dE': dE,
            'ddE': ddE,
            'a': a,
            'b': b,
            'c': c
        }
        self.ctx.steps.append(new_step_data)

        # Minimum of a parabola
        new_volume = -b / 2. / a

        # remove older step
        self.ctx.r0 = self.ctx.r1
        scaled_structure = get_structure(self.inputs.structure, new_volume)
        self.ctx.last_structure = scaled_structure

        inputs = generate_scf_input_params(scaled_structure,
                                           str(self.inputs.code),
                                           self.inputs.pseudo_family)

        # Run PW
        future = submit(PwProcess, **inputs)
        # Replace r1
        return ToContext(r1=future)
Exemplo n.º 8
0
    def run_pw(self):
        print "Workchain node identifiers: {}".format(self.calc)
        #Instantiate a JobCalc process and create basic structure
        JobCalc = PwCalculation.process()
        self.ctx.s0 = create_diamond_fcc(Str(self.inputs.element))
        self.ctx.eos_names = []

        calcs = {}
        for label, factor in zip(labels, scale_facs):
            s = rescale(self.ctx.s0, Float(factor))
            inputs = generate_scf_input_params(s, str(self.inputs.code),
                                               self.inputs.pseudo_family)
            print "Running a scf for {} with scale factor {}".format(
                self.inputs.element, factor)
            future = submit(JobCalc, **inputs)
            calcs[label] = future

        # Ask the workflow to continue when the results are ready and store them
        # in the context
        return ToContext(**calcs)
def run_eos_wf(code, pseudo_family, element):
    """Run an equation of state of a bulk crystal structure for the given element."""

    # This will print the pk of the work function
    print('Running run_eos_wf<{}>'.format(Process.current().pid))

    scale_factors = (0.96, 0.98, 1.0, 1.02, 1.04)
    labels = ['c1', 'c2', 'c3', 'c4', 'c5']

    calculations = {}

    # Create an initial bulk crystal structure for the given element, using the calculation function defined earlier
    initial_structure = create_diamond_fcc(element)

    # Loop over the label and scale_factor pairs
    for label, factor in list(zip(labels, scale_factors)):

        # Generated the scaled structure from the initial structure
        structure = rescale(initial_structure, Float(factor))

        # Generate the inputs for the `PwCalculation`
        inputs = generate_scf_input_params(structure, code, pseudo_family)

        # Launch a `PwCalculation` for each scaled structure
        print('Running a scf for {} with scale factor {}'.format(
            element, factor))
        calculations[label] = run(PwCalculation, **inputs)

    # Bundle the individual results from each `PwCalculation` in a single dictionary node.
    # Note: since we are 'creating' new data from existing data, we *have* to go through a `calcfunction`, otherwise
    # the provenance would be lost!
    inputs = {
        label: result['output_parameters']
        for label, result in calculations.items()
    }
    eos = create_eos_dictionary(**inputs)

    # Finally, return the results of this work function
    result = {'initial_structure': initial_structure, 'eos': eos}

    return result
Exemplo n.º 10
0
    def run_eos(self):
        """Run calculations for equation of state."""
        # Create basic structure and attach it as an output
        initial_structure = create_diamond_fcc(self.inputs.element)
        self.out('initial_structure', initial_structure)

        calculations = {}

        for label, factor in zip(labels, scale_facs):

            structure = rescale(initial_structure, Float(factor))
            inputs = generate_scf_input_params(structure, self.inputs.code,
                                               self.inputs.pseudo_family)

            self.report(
                'Running an SCF calculation for {} with scale factor {}'.
                format(self.inputs.element, factor))
            future = self.submit(PwCalculation, **inputs)
            calculations[label] = future

        # Ask the workflow to continue when the results are ready and store them in the context
        return ToContext(**calculations)
    def run_pw(self, ctx):
        
        PwProcess = PwCalculation.process()
        ctx.s0 = create_diamond_fcc(Str(self.inputs.element))

        ctx.eos_names = []
        calcs = {}
 
        for label, factor in zip(labels, scale_facs):
            s = rescale(ctx.s0,Float(factor))
            inputs = generate_scf_input_params(
                s, str(self.inputs.code), str(self.inputs.pseudo_family))
            print "Running a scf for {} with scale factor {}".format(
                self.inputs.element, factor)

            # Launch the code
            future = self.submit(PwProcess, inputs)
            # Store the future
            calcs[label] = future
          
        # Ask the workflow to continue when the results are ready and store them
        # in the context
        return ResultToContext(**calcs)
    def move_next_step(self):
        """Main part of the algorithm.

        Compare the results of two consecutive calculations and use Newton's algorithm on the pressure by fitting the
        results with a parabola and setting the next volume to calculate to the parabola minimum.

        The oldest calculation gets replaced by the most recent and a new calculation is launched that will replace
        the most recent.
        """
        # Computer the new Volume using Newton's algorithm and create the new corresponding structure by scaling it
        new_step_data = get_step_data(self.ctx.r0.outputs.output_parameters,
                                      self.ctx.r1.outputs.output_parameters)
        scaled_structure = get_structure(self.inputs.structure, new_step_data)
        self.ctx.steps.append(new_step_data)

        # Replace the older step with the latest and set the current structure
        self.ctx.r0 = self.ctx.r1
        self.ctx.last_structure = scaled_structure

        inputs = generate_scf_input_params(scaled_structure, self.inputs.code,
                                           self.inputs.pseudo_family)
        future = self.submit(PwCalculation, **inputs)

        return ToContext(r1=future)