Best Practices

Using Tab-Completion and the Integrated documentation

TC-Toolbox contains over 1000 functions and more than 200 classes. These functions are available for use in different contexts, as described in the Architecture overview.

In order to know which functions and classes are available for you at a given time and how they can be used, we encourage you to use MATLAB® tab completion and the MATLAB® help.

This is a feature of MATLAB® and the exact functionality can vary depending on the version of MATLAB® and if you use MATLAB® live scripts, classic MATLAB® scripts or the interactive console.

To access tab completion, press the dot (.) key then Tab. Use the up/down arrow keys to scroll through the list.

_images/tab-completion.png

To open the help for a specific function or class, click to place the cursor on the function or object and press the F1 key.

_images/F1.png

The built-in help for parameters of a specific function can be reached by placing the cursor within the parentheses of the function and pressing CTRL + F1.

_images/CTRL_F1.png

Click More Help… to view the corresponding help text.

Note

The MATLAB® script first needs to be run before you can view help text when More Help… is clicked. Once the script is run, the respective object is present in the workspace and the help is available.

Re-use of the Single Equilibrium Calculation State

The Thermo-Calc core keeps an internal state containing the data from previously performed calculations (such as composition of sublattices, previously formed phases, etc.). This is used for start values of future calculations (if not explicitly overwritten) and can strongly influence their convergence and calculation time. It can be useful to save and restore later the core-state in advanced use cases, these include:

  • Improving the convergence speed in case of very complicated equilibria if a similar equilibrium has already been calculated. “Similar” refers here primarily to composition, temperature, and entered phase set. This case can occur, for example, with the Thermo-Calc nickel-based superalloys database, TCNi.

  • Convenient and fast switching between states that have changed a lot (for example regarding suspended phases, numerical settings, etc.)

The mechanism of saving and restoring the state is called bookmarking and is controlled with the two methods bookmark_state() and set_state_to_bookmark(). The following short example shows how to switch between two different states:

import tc_toolbox.*
session = TCToolbox();

calc = session...
        .select_database_and_elements("FEDEMO", ["Fe", "C"])...
        .get_system()...
        .with_single_equilibrium_calculation()...
        .set_condition(ThermodynamicQuantity.temperature(), 2000.0)...
        .set_condition("X(C)", 0.01);

calc.calculate();
bookmark_temp_condition = calc.bookmark_state();

calc.set_phase_to_fixed("BCC", 0.5);
calc.remove_condition(ThermodynamicQuantity.temperature());
bookmark_fixed_phase_condition = calc.bookmark_state();

result_temp = calc.set_state_to_bookmark(bookmark_temp_condition);
disp("Conditions do contain temperature:")
disp(result_temp.get_conditions())
% this calculation had already been performed
disp("Stable phases (do not contain BCC):")
disp(result_temp.get_stable_phases())

result_fixed_phase = calc.set_state_to_bookmark(bookmark_fixed_phase_condition);
disp("Conditions do not contain temperature:")
disp(result_fixed_phase.get_conditions())
% this calculation had **not yet** been performed
disp("Stable phases (do contain BCC):")
disp(calc.calculate().get_stable_phases())

Re-use and Saving Results

Before a calculation is run in MATLAB®, a check is made to see if the exact same calculation has run before, and if that is the case, the result from the calculation can be loaded from disk instead of being re-calculated.

This functionality is always enabled within a script running MATLAB®, but you can make it work the same way when re-running a script, or even when running a completely different script.

You can set up a folder location to re-use results from saved calculations. This folder can be a network folder and shared by many users. This is done using the method set_cache_folder().

import tc_toolbox.*

session = TCToolbox();
session.set_cache_folder("cache")

The calculation is not re-run if there is a previous MATLAB® calculation with the same cache folder and exactly the same settings; the result is instead loaded from disk.

Another possibility is to explicitly save the result to disk and reload it later:

import tc_toolbox.*

session = TCToolbox();
% ... the system and calculator are set up and the calculation is performed
result = calculator.calculate()

result.save_to_disk("./result_dir")

You can then load the result again in another session, for example:

import tc_toolbox.*

session = TCToolbox();
result = session.load_result_from_disk().diffusion("./result_dir")
[x, frac] = result.get_mole_fraction_of_component_at_time("Cr", 1000.0)

Using the TCToolbox class efficiently

Normally you should only create one TCToolbox() variable.

Note

When a TCToolbox() variable is deleted, the Java backend engine process is stopped and all temporary data is deleted. When creating a new TCToolbox() variable, a new Java process is started. This can take several seconds.

If appropriate, it is safe to create a TCToolbox() variable in a loop. Due to the time it takes this only makes sense if the calculation time per iteration is longer than a minute.

To prevent creating a TCToolbox() variable multiple times, you can use the following pattern.

Example:

import tc_toolbox.*

session = tc_toolbox.TCToolbox();
system = session.select_database_and_elements("FEDEMO", ["Fe", "Cr"]).get_system();
calculation = system.with_single_equilibrium_calculation();
calculation.set_condition("T", 1000);

for i = 0:50
    calculate(calculation)
end

function calculate(calculator)
    % you could also pass the `session` or `system` object if more appropriate
    calculator.set_condition("W(Cr)", 0.1);
    % further configuration ...

    result = calculator.calculate();
    % ...
    result.invalidate();  % if the temporary data needs to be cleaned up immediately
end

Parallel Calculations

It is possible to perform parallel calculations with TC-Toolbox using the Parallel Computing ToolboxTM of MATLAB®. This is a separate toolbox that can be purchased for MATLAB®, it is not part of the standard configuration of MATLAB®.

A general pattern that can be applied is shown below. This code snippet shows how to perform single equilibrium calculations for different compositions in parallel. In the same way all other calculators of Thermo-Calc can be used or combined.

Example:

num_processes = 2;
min_cr = 10;  % in wt-%
max_cr = 19;  % in wt-%
delta_cr = 1;  % in wt-%
chunk_size = 5;  % this simple code expects that the Cr-range can be exactly divided into such chunks

if (isempty(gcp('nocreate')))
    parpool("local", num_processes);
end

num_points = 1 + (max_cr - min_cr) / delta_cr;
total_cr_range = linspace(min_cr, max_cr, num_points);
chunked_cr_ranges = num2cell(reshape(total_cr_range, chunk_size, []), 1);

% this requires the Parallel Computing Toolbox(TM), can be run with "for" instead without parallelization
num_chunks = ceil(num_points / chunk_size);
bcc_fraction_results = cell(num_chunks, 1);
parfor chunk_index = 1 : num_chunks
    bcc_fraction_results{chunk_index} = do_perform(chunked_cr_ranges{chunk_index});
end

bcc_phase_fraction = cell2mat(bcc_fraction_results);
% ... use the result in `bcc_phase_fraction`, for example for plotting


function phase_fractions = do_perform(cr_range)
    % this function is running in a subprocess
    import tc_toolbox.step_or_map_diagrams.*
    import tc_toolbox.*

    elements = ["Fe", "Cr", "Ni", "C"];

    session = TCToolbox();

    sys = session.select_database_and_elements("FEDEMO", elements).get_system();

    calc = sys.with_single_equilibrium_calculation();
    calc.set_condition(ThermodynamicQuantity.temperature(), 1100.0); % in K
    calc.set_condition(ThermodynamicQuantity.mass_fraction_of_a_component("C"), 0.1 / 100);
    calc.set_condition(ThermodynamicQuantity.mass_fraction_of_a_component("Ni"), 2.0 / 100);

    phase_fractions = zeros(size(cr_range, 1));
    for cr_index = 1 : size(cr_range, 1)
        cr = cr_range(cr_index);
        calc.set_condition("W(Cr)", cr / 100);
        result = calc.calculate();
        phase_fractions(cr_index) = result.get_value_of("NPM(BCC_A2)");
    end
end

Handling Calculation Engine Crashes

In some cases the Thermo-Calc calculation engine can crash. If batch calculations are performed, this brings down the complete batch. To handle this situation there is an error you can use: UnrecoverableCalculationException().

That error is raised if the calculation server enters a state where no further calculations are possible. You should catch that exception and create a new instance of TCToolbox(), which you use from that point.

Example:

import tc_toolbox.*
import tc_toolbox.diffusion.*

temperatures = linspace(900,1100,10);
session = TCToolbox();
for i = 1:length(temperatures)
    temperature = temperatures(i);
    try
        diffusion_result = session...
                .select_thermodynamic_and_kinetic_databases_with_elements("FEDEMO", "MFEDEMO", ["Fe", "Ni"])...
                .get_system()...
                .with_isothermal_diffusion_calculation()...
                    .set_temperature(temperature)...
                    .set_simulation_time(108000.0)...
                    .add_region(Region("Austenite")...
                        .set_width(1E-4)...
                        .with_grid(CalculatedGrid.linear().set_no_of_points(50))...
                        .with_composition_profile(CompositionProfile()...
                            .add("Ni", ElementProfile.linear(10.0, 50.0))...
                        )...
                    .add_phase("FCC_A1"))...
            .calculate();

        [distance, ni_fraction] = diffusion_result.get_mass_fraction_of_component_at_time("Ni", 108000.0);
        disp("Succeeded!")

    catch e
        if contains(e.message, 'UnrecoverableCalculationException')
            disp('Could not calculate. Creating a new TCToolbox and continuing with next calculation...')
            session = TCToolbox();
        else
            disp('Could not calculate. Using the previous TCToolbox and continuing with next calculation...')
        end
    end
end