@mat3ra/wode 2025.10.1-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc +17 -0
- package/LICENSE.md +15 -0
- package/README.md +164 -0
- package/assets/subworkflows/deepmd/deepmd.yml +31 -0
- package/assets/subworkflows/deepmd/espresso_cp_md.yml +16 -0
- package/assets/subworkflows/espresso/average_electrostatic_potential_find_minima.yml +27 -0
- package/assets/subworkflows/espresso/average_electrostatic_potential_via_band_structure.yml +67 -0
- package/assets/subworkflows/espresso/band_gap.yml +21 -0
- package/assets/subworkflows/espresso/band_gap_hse_dos.yml +30 -0
- package/assets/subworkflows/espresso/band_structure.yml +26 -0
- package/assets/subworkflows/espresso/band_structure_dos.yml +34 -0
- package/assets/subworkflows/espresso/band_structure_hse.yml +30 -0
- package/assets/subworkflows/espresso/band_structure_magn.yml +31 -0
- package/assets/subworkflows/espresso/band_structure_soc.yml +30 -0
- package/assets/subworkflows/espresso/dielectric_tensor.yml +35 -0
- package/assets/subworkflows/espresso/dos.yml +24 -0
- package/assets/subworkflows/espresso/electronic_density_mesh.yml +19 -0
- package/assets/subworkflows/espresso/esm.yml +14 -0
- package/assets/subworkflows/espresso/esm_relax.yml +14 -0
- package/assets/subworkflows/espresso/espresso_extract_kpoints.yml +16 -0
- package/assets/subworkflows/espresso/espresso_xml_get_qpt_irr.yml +12 -0
- package/assets/subworkflows/espresso/fixed_cell_relaxation.yml +16 -0
- package/assets/subworkflows/espresso/gw_band_structure_band_gap_full_frequency.yml +22 -0
- package/assets/subworkflows/espresso/gw_band_structure_band_gap_plasmon_pole.yml +22 -0
- package/assets/subworkflows/espresso/hubbard_u_hp.yml +21 -0
- package/assets/subworkflows/espresso/kpoint_convergence.yml +86 -0
- package/assets/subworkflows/espresso/neb.yml +16 -0
- package/assets/subworkflows/espresso/ph_init_qpoints.yml +14 -0
- package/assets/subworkflows/espresso/ph_single_irr_qpt.yml +14 -0
- package/assets/subworkflows/espresso/phonon_dispersions.yml +29 -0
- package/assets/subworkflows/espresso/phonon_dos.yml +29 -0
- package/assets/subworkflows/espresso/phonon_dos_dispersion.yml +34 -0
- package/assets/subworkflows/espresso/phonon_reduce.yml +29 -0
- package/assets/subworkflows/espresso/post_processor.yml +14 -0
- package/assets/subworkflows/espresso/pre_processor.yml +14 -0
- package/assets/subworkflows/espresso/pw_scf.yml +16 -0
- package/assets/subworkflows/espresso/recalculate_bands.yml +19 -0
- package/assets/subworkflows/espresso/surface_energy.yml +16 -0
- package/assets/subworkflows/espresso/total_energy.yml +16 -0
- package/assets/subworkflows/espresso/valence_band_offset_calc_from_previous_esp_vbm.yml +35 -0
- package/assets/subworkflows/espresso/variable_cell_relaxation.yml +18 -0
- package/assets/subworkflows/espresso/zero_point_energy.yml +19 -0
- package/assets/subworkflows/jupyterLab/jupyter_notebook.yml +17 -0
- package/assets/subworkflows/nwchem/total_energy.yml +16 -0
- package/assets/subworkflows/python/ml/classification_tail.yml +56 -0
- package/assets/subworkflows/python/ml/clustering_tail.yml +62 -0
- package/assets/subworkflows/python/ml/regression_tail.yml +56 -0
- package/assets/subworkflows/python/ml/train_head.yml +61 -0
- package/assets/subworkflows/python/python_script.yml +14 -0
- package/assets/subworkflows/shell/batch_espresso_pwscf.yml +14 -0
- package/assets/subworkflows/shell/hello_world.yml +14 -0
- package/assets/subworkflows/vasp/band_gap.yml +21 -0
- package/assets/subworkflows/vasp/band_structure.yml +21 -0
- package/assets/subworkflows/vasp/band_structure_dos.yml +23 -0
- package/assets/subworkflows/vasp/dos.yml +18 -0
- package/assets/subworkflows/vasp/fixed_cell_relaxation.yml +16 -0
- package/assets/subworkflows/vasp/initial_final_total_energies.yml +25 -0
- package/assets/subworkflows/vasp/kpoint_convergence.yml +89 -0
- package/assets/subworkflows/vasp/neb_subworkflow.yml +16 -0
- package/assets/subworkflows/vasp/prepare_images.yml +16 -0
- package/assets/subworkflows/vasp/recalculate_bands.yml +16 -0
- package/assets/subworkflows/vasp/surface_energy.yml +18 -0
- package/assets/subworkflows/vasp/total_energy.yml +16 -0
- package/assets/subworkflows/vasp/variable_cell_relaxation.yml +18 -0
- package/assets/subworkflows/vasp/zero_point_energy.yml +16 -0
- package/assets/workflows/deepmd/deepmd_md.yml +6 -0
- package/assets/workflows/espresso/band_gap.yml +4 -0
- package/assets/workflows/espresso/band_gap_dos_hse.yml +4 -0
- package/assets/workflows/espresso/band_structure.yml +4 -0
- package/assets/workflows/espresso/band_structure_dos.yml +4 -0
- package/assets/workflows/espresso/band_structure_hse.yml +14 -0
- package/assets/workflows/espresso/band_structure_magn.yml +7 -0
- package/assets/workflows/espresso/band_structure_soc.yml +7 -0
- package/assets/workflows/espresso/dielectric_tensor.yml +4 -0
- package/assets/workflows/espresso/dos.yml +4 -0
- package/assets/workflows/espresso/electronic_density_mesh.yml +4 -0
- package/assets/workflows/espresso/esm.yml +4 -0
- package/assets/workflows/espresso/esm_relax.yml +4 -0
- package/assets/workflows/espresso/fixed_cell_relaxation.yml +4 -0
- package/assets/workflows/espresso/gw_band_structure_band_gap_full_frequency.yml +4 -0
- package/assets/workflows/espresso/gw_band_structure_band_gap_plasmon_pole.yml +4 -0
- package/assets/workflows/espresso/hubbard_u_hp.yml +7 -0
- package/assets/workflows/espresso/kpoint_convergence.yml +4 -0
- package/assets/workflows/espresso/neb.yml +4 -0
- package/assets/workflows/espresso/phonon_dispersions.yml +4 -0
- package/assets/workflows/espresso/phonon_dos.yml +4 -0
- package/assets/workflows/espresso/phonon_dos_dispersion.yml +4 -0
- package/assets/workflows/espresso/phonon_map.yml +28 -0
- package/assets/workflows/espresso/recalculate_bands.yml +4 -0
- package/assets/workflows/espresso/surface_energy.yml +4 -0
- package/assets/workflows/espresso/total_energy.yml +4 -0
- package/assets/workflows/espresso/valence_band_offset.yml +171 -0
- package/assets/workflows/espresso/variable_cell_relaxation.yml +4 -0
- package/assets/workflows/espresso/zero_point_energy.yml +4 -0
- package/assets/workflows/jupyterLab/jupyter_notebook.yml +4 -0
- package/assets/workflows/nwchem/total_energy.yml +4 -0
- package/assets/workflows/python/ml/classification_workflow.yml +9 -0
- package/assets/workflows/python/ml/clustering_workflow.yml +9 -0
- package/assets/workflows/python/ml/regression_workflow.yml +9 -0
- package/assets/workflows/python/python_script.yml +4 -0
- package/assets/workflows/shell/batch_espresso_pwscf.yml +4 -0
- package/assets/workflows/shell/hello_world.yml +4 -0
- package/assets/workflows/vasp/band_gap.yml +4 -0
- package/assets/workflows/vasp/band_structure.yml +4 -0
- package/assets/workflows/vasp/band_structure_dos.yml +4 -0
- package/assets/workflows/vasp/dos.yml +4 -0
- package/assets/workflows/vasp/fixed_cell_relaxation.yml +4 -0
- package/assets/workflows/vasp/kpoint_convergence.yml +4 -0
- package/assets/workflows/vasp/neb.yml +8 -0
- package/assets/workflows/vasp/recalculate_bands.yml +4 -0
- package/assets/workflows/vasp/surface_energy.yml +4 -0
- package/assets/workflows/vasp/total_energy.yml +4 -0
- package/assets/workflows/vasp/variable_cell_relaxation.yml +4 -0
- package/assets/workflows/vasp/zero_point_energy.yml +4 -0
- package/build_workflows.js +65 -0
- package/dist/context/context.js +49 -0
- package/dist/context/mixins/ApplicationContextMixin.js +19 -0
- package/dist/context/mixins/JobContextMixin.js +39 -0
- package/dist/context/mixins/MaterialContextMixin.js +40 -0
- package/dist/context/mixins/MaterialsContextMixin.js +19 -0
- package/dist/context/mixins/MaterialsSetContextMixin.js +25 -0
- package/dist/context/mixins/MethodDataContextMixin.js +48 -0
- package/dist/context/mixins/WorkflowContextMixin.js +28 -0
- package/dist/context/providers/BoundaryConditionsFormDataProvider.js +86 -0
- package/dist/context/providers/CollinearMagnetizationContextProvider.js +113 -0
- package/dist/context/providers/HubbardContextProviderLegacy.js +81 -0
- package/dist/context/providers/HubbardJContextProvider.js +74 -0
- package/dist/context/providers/HubbardUContextProvider.js +77 -0
- package/dist/context/providers/HubbardVContextProvider.js +104 -0
- package/dist/context/providers/IonDynamicsContextProvider.js +62 -0
- package/dist/context/providers/MLSettingsContextProvider.js +52 -0
- package/dist/context/providers/MLTrainTestSplitContextProvider.js +48 -0
- package/dist/context/providers/NEBFormDataProvider.js +38 -0
- package/dist/context/providers/NonCollinearMagnetizationContextProvider.js +253 -0
- package/dist/context/providers/PlanewaveCutoffsContextProvider.js +67 -0
- package/dist/context/providers/PointsGridFormDataProvider.js +272 -0
- package/dist/context/providers/PointsPathFormDataProvider.js +155 -0
- package/dist/context/providers/by_application/ExecutableContextProvider.js +17 -0
- package/dist/context/providers/by_application/espresso/QENEBContextProvider.js +60 -0
- package/dist/context/providers/by_application/espresso/QEPWXContextProvider.js +149 -0
- package/dist/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js +84 -0
- package/dist/context/providers/by_application/vasp/VASPContextProvider.js +64 -0
- package/dist/context/providers/by_application/vasp/VASPNEBContextProvider.js +56 -0
- package/dist/context/providers/settings.js +37 -0
- package/dist/context/providers.js +199 -0
- package/dist/enums.js +65 -0
- package/dist/index.js +64 -0
- package/dist/patch.js +19 -0
- package/dist/subworkflows/convergence/factory.js +35 -0
- package/dist/subworkflows/convergence/non_uniform_kgrid.js +31 -0
- package/dist/subworkflows/convergence/parameter.js +70 -0
- package/dist/subworkflows/convergence/uniform_kgrid.js +26 -0
- package/dist/subworkflows/convergence.js +189 -0
- package/dist/subworkflows/create.js +285 -0
- package/dist/subworkflows/dynamic/espresso/getQpointIrrep.js +34 -0
- package/dist/subworkflows/dynamic/index.js +19 -0
- package/dist/subworkflows/dynamic/surfaceEnergy.js +67 -0
- package/dist/subworkflows/index.js +19 -0
- package/dist/subworkflows/subworkflow.js +279 -0
- package/dist/units/assertion.js +37 -0
- package/dist/units/assignment.js +42 -0
- package/dist/units/base.js +91 -0
- package/dist/units/builders/AssertionUnitConfigBuilder.js +34 -0
- package/dist/units/builders/AssignmentUnitConfigBuilder.js +41 -0
- package/dist/units/builders/ExecutionUnitConfigBuilder.js +67 -0
- package/dist/units/builders/IOUnitConfigBuilder.js +54 -0
- package/dist/units/builders/UnitConfigBuilder.js +79 -0
- package/dist/units/builders/index.js +18 -0
- package/dist/units/condition.js +52 -0
- package/dist/units/execution.js +222 -0
- package/dist/units/factory.js +53 -0
- package/dist/units/index.js +82 -0
- package/dist/units/io.js +148 -0
- package/dist/units/map.js +38 -0
- package/dist/units/processing.js +41 -0
- package/dist/units/reduce.js +24 -0
- package/dist/units/subworkflow.js +23 -0
- package/dist/utils.js +92 -0
- package/dist/workflows/create.js +312 -0
- package/dist/workflows/default.js +41 -0
- package/dist/workflows/index.js +108 -0
- package/dist/workflows/relaxation.js +37 -0
- package/dist/workflows/workflow.js +303 -0
- package/package.json +94 -0
- package/src/context/context.js +47 -0
- package/src/context/mixins/ApplicationContextMixin.js +19 -0
- package/src/context/mixins/JobContextMixin.js +36 -0
- package/src/context/mixins/MaterialContextMixin.js +41 -0
- package/src/context/mixins/MaterialsContextMixin.js +18 -0
- package/src/context/mixins/MaterialsSetContextMixin.js +24 -0
- package/src/context/mixins/MethodDataContextMixin.js +48 -0
- package/src/context/mixins/WorkflowContextMixin.js +25 -0
- package/src/context/providers/BoundaryConditionsFormDataProvider.js +80 -0
- package/src/context/providers/CollinearMagnetizationContextProvider.js +117 -0
- package/src/context/providers/HubbardContextProviderLegacy.js +75 -0
- package/src/context/providers/HubbardJContextProvider.js +73 -0
- package/src/context/providers/HubbardUContextProvider.js +100 -0
- package/src/context/providers/HubbardVContextProvider.js +111 -0
- package/src/context/providers/IonDynamicsContextProvider.js +56 -0
- package/src/context/providers/MLSettingsContextProvider.js +48 -0
- package/src/context/providers/MLTrainTestSplitContextProvider.js +45 -0
- package/src/context/providers/NEBFormDataProvider.js +32 -0
- package/src/context/providers/NonCollinearMagnetizationContextProvider.js +269 -0
- package/src/context/providers/PlanewaveCutoffsContextProvider.js +68 -0
- package/src/context/providers/PointsGridFormDataProvider.js +285 -0
- package/src/context/providers/PointsPathFormDataProvider.js +165 -0
- package/src/context/providers/by_application/ExecutableContextProvider.js +10 -0
- package/src/context/providers/by_application/espresso/QENEBContextProvider.js +56 -0
- package/src/context/providers/by_application/espresso/QEPWXContextProvider.js +166 -0
- package/src/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js +86 -0
- package/src/context/providers/by_application/vasp/VASPContextProvider.js +56 -0
- package/src/context/providers/by_application/vasp/VASPNEBContextProvider.js +46 -0
- package/src/context/providers/settings.js +38 -0
- package/src/context/providers.js +140 -0
- package/src/enums.js +65 -0
- package/src/index.js +17 -0
- package/src/patch.js +12 -0
- package/src/subworkflows/convergence/factory.js +14 -0
- package/src/subworkflows/convergence/non_uniform_kgrid.js +28 -0
- package/src/subworkflows/convergence/parameter.js +58 -0
- package/src/subworkflows/convergence/uniform_kgrid.js +22 -0
- package/src/subworkflows/convergence.js +196 -0
- package/src/subworkflows/create.js +201 -0
- package/src/subworkflows/dynamic/espresso/getQpointIrrep.js +35 -0
- package/src/subworkflows/dynamic/index.js +8 -0
- package/src/subworkflows/dynamic/surfaceEnergy.js +124 -0
- package/src/subworkflows/index.js +2 -0
- package/src/subworkflows/subworkflow.js +329 -0
- package/src/units/assertion.js +29 -0
- package/src/units/assignment.js +34 -0
- package/src/units/base.js +97 -0
- package/src/units/builders/AssertionUnitConfigBuilder.js +28 -0
- package/src/units/builders/AssignmentUnitConfigBuilder.js +36 -0
- package/src/units/builders/ExecutionUnitConfigBuilder.js +59 -0
- package/src/units/builders/IOUnitConfigBuilder.js +53 -0
- package/src/units/builders/UnitConfigBuilder.js +86 -0
- package/src/units/builders/index.js +15 -0
- package/src/units/condition.js +47 -0
- package/src/units/execution.js +263 -0
- package/src/units/factory.js +53 -0
- package/src/units/index.js +25 -0
- package/src/units/io.js +163 -0
- package/src/units/map.js +33 -0
- package/src/units/processing.js +39 -0
- package/src/units/reduce.js +17 -0
- package/src/units/subworkflow.js +15 -0
- package/src/utils.js +73 -0
- package/src/workflows/create.js +222 -0
- package/src/workflows/default.js +39 -0
- package/src/workflows/index.js +99 -0
- package/src/workflows/relaxation.js +41 -0
- package/src/workflows/workflow.js +351 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import ApplicationRegistry from "@exabyte-io/ade.js/dist/js/ApplicationRegistry";
|
|
2
|
+
import {
|
|
3
|
+
default_methods as MethodConfigs,
|
|
4
|
+
default_models as ModelConfigs,
|
|
5
|
+
MethodFactory,
|
|
6
|
+
ModelFactory,
|
|
7
|
+
} from "@exabyte-io/mode.js";
|
|
8
|
+
import { workflowSubforkflowMapByApplication } from "@mat3ra/standata";
|
|
9
|
+
import _ from "lodash";
|
|
10
|
+
|
|
11
|
+
import { UnitFactory } from "../units";
|
|
12
|
+
import { builders } from "../units/builders";
|
|
13
|
+
import { applyConfig } from "../utils";
|
|
14
|
+
import { dynamicSubworkflowsByApp, getSurfaceEnergySubworkflowUnits } from "./dynamic";
|
|
15
|
+
import { Subworkflow } from "./subworkflow";
|
|
16
|
+
|
|
17
|
+
// NOTE: DFTModel => DFTModelConfig, configs should have the same name as the model/method class + "Config" at the end
|
|
18
|
+
function _getConfigFromModelOrMethodName(name, kind) {
|
|
19
|
+
const configs = kind === "Model" ? ModelConfigs : MethodConfigs;
|
|
20
|
+
if (!configs[`${name}Config`]) {
|
|
21
|
+
// eslint-disable-next-line no-param-reassign
|
|
22
|
+
name = `Unknown${kind}`;
|
|
23
|
+
}
|
|
24
|
+
return configs[`${name}Config`];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @summary Create model from subworkflow data
|
|
29
|
+
* @param config {Object} model config
|
|
30
|
+
* @param modelFactoryCls {any} model factory to use
|
|
31
|
+
* @returns {DFTModel|Model}
|
|
32
|
+
*/
|
|
33
|
+
function createModel({ config, modelFactoryCls }) {
|
|
34
|
+
const { name, config: modelConfig = {} } = config;
|
|
35
|
+
const defaultConfig = _getConfigFromModelOrMethodName(name, "Model");
|
|
36
|
+
return modelFactoryCls.create({ ...defaultConfig, ...modelConfig });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @summary Create method from subworkflow data
|
|
41
|
+
* @param config {Object} method configuration
|
|
42
|
+
* @param methodFactoryCls {any}
|
|
43
|
+
* @returns {{method, setSearchText}}
|
|
44
|
+
*/
|
|
45
|
+
function createMethod({ config, methodFactoryCls }) {
|
|
46
|
+
const { name, setSearchText = null, config: methodConfig = {} } = config;
|
|
47
|
+
const defaultConfig = _getConfigFromModelOrMethodName(name, "Method");
|
|
48
|
+
const method = methodFactoryCls.create({ ...defaultConfig, ...methodConfig });
|
|
49
|
+
return { method, setSearchText };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @summary Create top-level objects used in subworkflow initialization
|
|
54
|
+
* @param subworkflowData {Object} subworkflow data
|
|
55
|
+
* @param AppRegistry
|
|
56
|
+
* @param modelFactoryCls {any} model factory class
|
|
57
|
+
* @param methodFactoryCls {any} method factory class
|
|
58
|
+
* @returns {{application: *, method: *, model: (DFTModel|Model), setSearchText: String|null}}
|
|
59
|
+
*/
|
|
60
|
+
function createTopLevel({ subworkflowData, modelFactoryCls, methodFactoryCls, AppRegistry }) {
|
|
61
|
+
const { application: appConfig, model: modelConfig, method: methodConfig } = subworkflowData;
|
|
62
|
+
const application = AppRegistry.createApplication(appConfig);
|
|
63
|
+
const model = createModel({ config: modelConfig, modelFactoryCls });
|
|
64
|
+
const { method, setSearchText } = createMethod({ config: methodConfig, methodFactoryCls });
|
|
65
|
+
return {
|
|
66
|
+
application,
|
|
67
|
+
model,
|
|
68
|
+
method,
|
|
69
|
+
setSearchText,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* @summary Create workflow unit from JSON configuration
|
|
75
|
+
* Supports applying functions to the builder prior to building via "functions"
|
|
76
|
+
* Supports applying attributes to the builder after building via "attributes"
|
|
77
|
+
* @param config {Object} unit config
|
|
78
|
+
* @param application {*} application
|
|
79
|
+
* @param unitBuilders {Object} workflow unit builders
|
|
80
|
+
* @param unitFactoryCls {*} workflow unit class factory
|
|
81
|
+
* @returns {*|{head: boolean, preProcessors: [], postProcessors: [], name: *, flowchartId: *, type: *, results: [], monitors: []}}
|
|
82
|
+
*/
|
|
83
|
+
export function createUnit({ config, application, unitBuilders, unitFactoryCls }) {
|
|
84
|
+
const { type, config: unitConfig } = config;
|
|
85
|
+
if (type === "executionBuilder") {
|
|
86
|
+
const { name, execName, flavorName, flowchartId } = unitConfig;
|
|
87
|
+
const builder = new unitBuilders.ExecutionUnitConfigBuilder(
|
|
88
|
+
name,
|
|
89
|
+
application,
|
|
90
|
+
execName,
|
|
91
|
+
flavorName,
|
|
92
|
+
flowchartId,
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
// config should contain "functions" and "attributes"
|
|
96
|
+
const cfg = applyConfig({ obj: builder, config, callBuild: true });
|
|
97
|
+
return unitFactoryCls.create(cfg);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return unitFactoryCls.create({ type, ...unitConfig });
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @summary Dynamically create subworkflow units
|
|
105
|
+
* @param dynamicSubworkflow {String} name of unit creation function
|
|
106
|
+
* @param units {Array} configured units to provide to dynamic unit creation
|
|
107
|
+
* @param unitBuilders {Object} unit configuration builders
|
|
108
|
+
* @param unitFactoryCls {*} unit factory class
|
|
109
|
+
* @param application {*} application (optional)
|
|
110
|
+
* @returns {*}
|
|
111
|
+
*/
|
|
112
|
+
function createDynamicUnits({
|
|
113
|
+
dynamicSubworkflow,
|
|
114
|
+
units,
|
|
115
|
+
unitBuilders,
|
|
116
|
+
unitFactoryCls,
|
|
117
|
+
application = null,
|
|
118
|
+
}) {
|
|
119
|
+
const { name, subfolder } = dynamicSubworkflow;
|
|
120
|
+
const func = subfolder && _.get(dynamicSubworkflowsByApp, `${subfolder}.${name}`, () => {});
|
|
121
|
+
switch (name) {
|
|
122
|
+
case "surfaceEnergy":
|
|
123
|
+
// eslint-disable-next-line no-case-declarations
|
|
124
|
+
const [scfUnit] = units;
|
|
125
|
+
return getSurfaceEnergySubworkflowUnits({ scfUnit, unitBuilders });
|
|
126
|
+
case "getQpointIrrep":
|
|
127
|
+
return func({ unitBuilders, unitFactoryCls, application });
|
|
128
|
+
default:
|
|
129
|
+
throw new Error(`dynamicSubworkflow=${name} not recognized`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function createSubworkflow({
|
|
134
|
+
subworkflowData,
|
|
135
|
+
AppRegistry = ApplicationRegistry,
|
|
136
|
+
modelFactoryCls = ModelFactory,
|
|
137
|
+
methodFactoryCls = MethodFactory,
|
|
138
|
+
subworkflowCls = Subworkflow,
|
|
139
|
+
unitFactoryCls = UnitFactory,
|
|
140
|
+
unitBuilders = builders,
|
|
141
|
+
}) {
|
|
142
|
+
const { application, model, method, setSearchText } = createTopLevel({
|
|
143
|
+
subworkflowData,
|
|
144
|
+
AppRegistry,
|
|
145
|
+
modelFactoryCls,
|
|
146
|
+
methodFactoryCls,
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
let units = [];
|
|
150
|
+
const { name, units: unitConfigs, config = {}, dynamicSubworkflow = null } = subworkflowData;
|
|
151
|
+
unitConfigs.forEach((_config) => {
|
|
152
|
+
units.push(
|
|
153
|
+
createUnit({
|
|
154
|
+
config: _config,
|
|
155
|
+
application,
|
|
156
|
+
unitBuilders,
|
|
157
|
+
unitFactoryCls,
|
|
158
|
+
}),
|
|
159
|
+
);
|
|
160
|
+
});
|
|
161
|
+
if (dynamicSubworkflow) {
|
|
162
|
+
units = createDynamicUnits({
|
|
163
|
+
dynamicSubworkflow,
|
|
164
|
+
units,
|
|
165
|
+
unitBuilders,
|
|
166
|
+
unitFactoryCls,
|
|
167
|
+
application,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const { functions = {}, attributes = {}, ...cfg } = config;
|
|
172
|
+
let subworkflow = subworkflowCls.fromArguments(application, model, method, name, units, cfg);
|
|
173
|
+
subworkflow = applyConfig({ obj: subworkflow, config: { functions, attributes } });
|
|
174
|
+
if (setSearchText) subworkflow.model.method.setSearchText(setSearchText);
|
|
175
|
+
return subworkflow;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* @summary Convenience wrapper around createSubworkflow to create by app name and swf name
|
|
180
|
+
* @param appName {String} application name
|
|
181
|
+
* @param swfName {String} subworkflow name (snake_case.yml)
|
|
182
|
+
* @param workflowSubworkflowMapByApplication {Object} object containing all workflow/subworkflow map by application
|
|
183
|
+
* @param swArgs {Object} classes for instantiation
|
|
184
|
+
* @returns {*} subworkflow object
|
|
185
|
+
*/
|
|
186
|
+
function createSubworkflowByName({
|
|
187
|
+
appName,
|
|
188
|
+
swfName,
|
|
189
|
+
workflowSubworkflowMapByApplication = workflowSubforkflowMapByApplication,
|
|
190
|
+
...swArgs
|
|
191
|
+
}) {
|
|
192
|
+
const { subworkflows } = workflowSubworkflowMapByApplication;
|
|
193
|
+
const { [appName]: allSubworkflowData } = subworkflows;
|
|
194
|
+
const { [swfName]: subworkflowData } = allSubworkflowData;
|
|
195
|
+
return createSubworkflow({
|
|
196
|
+
subworkflowData,
|
|
197
|
+
...swArgs,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export { createSubworkflow, createSubworkflowByName };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { UNIT_TYPES } from "../../../enums";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @summary Get QptIrr units used in phonon map calculations
|
|
5
|
+
* @param unitBuilders {Object} unit builders
|
|
6
|
+
* @param unitFactoryCls {*} unit factory class
|
|
7
|
+
* @param application {*} application instance
|
|
8
|
+
* @returns {[{head: boolean, preProcessors: [], postProcessors: [], name: *, flowchartId: *, type: *, results: [], monitors: []},*]}
|
|
9
|
+
*/
|
|
10
|
+
function getQpointIrrep({ unitBuilders, unitFactoryCls, application }) {
|
|
11
|
+
const { ExecutionUnitConfigBuilder } = unitBuilders;
|
|
12
|
+
|
|
13
|
+
const pythonUnit = new ExecutionUnitConfigBuilder(
|
|
14
|
+
"python",
|
|
15
|
+
application,
|
|
16
|
+
"python",
|
|
17
|
+
"espresso_xml_get_qpt_irr",
|
|
18
|
+
).build();
|
|
19
|
+
|
|
20
|
+
const assignmentUnit = unitFactoryCls.create({
|
|
21
|
+
type: UNIT_TYPES.assignment,
|
|
22
|
+
input: [
|
|
23
|
+
{
|
|
24
|
+
scope: pythonUnit.flowchartId,
|
|
25
|
+
name: "STDOUT",
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
operand: "Q_POINTS",
|
|
29
|
+
value: "json.loads(STDOUT)",
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
return [pythonUnit, assignmentUnit];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export { getQpointIrrep };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { getQpointIrrep } from "./espresso/getQpointIrrep";
|
|
2
|
+
import { getSurfaceEnergySubworkflowUnits } from "./surfaceEnergy";
|
|
3
|
+
|
|
4
|
+
const dynamicSubworkflowsByApp = {
|
|
5
|
+
espresso: { getQpointIrrep },
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export { getSurfaceEnergySubworkflowUnits, dynamicSubworkflowsByApp };
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { Utils } from "@mat3ra/utils";
|
|
2
|
+
|
|
3
|
+
function getIOUnitEndpointOptions(query, projection = "{}") {
|
|
4
|
+
return {
|
|
5
|
+
params: {
|
|
6
|
+
query,
|
|
7
|
+
projection,
|
|
8
|
+
},
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function getAssignmentUnitInput(unit, name) {
|
|
13
|
+
return [
|
|
14
|
+
{
|
|
15
|
+
name,
|
|
16
|
+
scope: unit.flowchartId,
|
|
17
|
+
},
|
|
18
|
+
];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function getSurfaceEnergySubworkflowUnits({ scfUnit, unitBuilders }) {
|
|
22
|
+
const { IOUnitConfigBuilder, AssignmentUnitConfigBuilder, AssertionUnitConfigBuilder } =
|
|
23
|
+
unitBuilders;
|
|
24
|
+
|
|
25
|
+
let input, endpointOptions;
|
|
26
|
+
endpointOptions = getIOUnitEndpointOptions("{'_id': MATERIAL_ID}");
|
|
27
|
+
const getSlabUnit = new IOUnitConfigBuilder("io-slab", "materials", endpointOptions).build();
|
|
28
|
+
|
|
29
|
+
input = getAssignmentUnitInput(getSlabUnit, "DATA");
|
|
30
|
+
const setSlabUnit = new AssignmentUnitConfigBuilder("slab", "SLAB", "DATA[0]", input).build();
|
|
31
|
+
|
|
32
|
+
endpointOptions = getIOUnitEndpointOptions("{'_id': SLAB.metadata.bulkId}");
|
|
33
|
+
const getBulkUnit = new IOUnitConfigBuilder("io-bulk", "materials", endpointOptions).build();
|
|
34
|
+
|
|
35
|
+
const BULKValue = "DATA[0] if DATA else None";
|
|
36
|
+
input = getAssignmentUnitInput(getBulkUnit, "DATA");
|
|
37
|
+
const setBulkUnit = new AssignmentUnitConfigBuilder("bulk", "BULK", BULKValue, input).build();
|
|
38
|
+
|
|
39
|
+
const assertBulkUnit = new AssertionUnitConfigBuilder(
|
|
40
|
+
"assert-bulk",
|
|
41
|
+
"BULK != None",
|
|
42
|
+
"Bulk material does not exist!",
|
|
43
|
+
).build();
|
|
44
|
+
|
|
45
|
+
const query = Utils.str.removeNewLinesAndExtraSpaces(`{
|
|
46
|
+
'exabyteId': BULK.exabyteId,
|
|
47
|
+
'data.name': 'total_energy',
|
|
48
|
+
'group': {'$regex': ''.join((SUBWORKFLOW.application.shortName, ':'))}
|
|
49
|
+
}`);
|
|
50
|
+
// Do not confuse `sort` with `$sort`. `sort` is used in meteor collections and `$sort` is used in Mongo queries.
|
|
51
|
+
const projection = "{'sort': {'precision.value': -1}, 'limit': 1}";
|
|
52
|
+
endpointOptions = getIOUnitEndpointOptions(query, projection);
|
|
53
|
+
const getEBulkUnit = new IOUnitConfigBuilder(
|
|
54
|
+
"io-e-bulk",
|
|
55
|
+
"refined-properties",
|
|
56
|
+
endpointOptions,
|
|
57
|
+
).build();
|
|
58
|
+
|
|
59
|
+
input = getAssignmentUnitInput(getEBulkUnit, "DATA");
|
|
60
|
+
const EBULKValue = "DATA[0].data.value if DATA else None";
|
|
61
|
+
const setEBulkUnit = new AssignmentUnitConfigBuilder(
|
|
62
|
+
"e-bulk",
|
|
63
|
+
"E_BULK",
|
|
64
|
+
EBULKValue,
|
|
65
|
+
input,
|
|
66
|
+
).build();
|
|
67
|
+
|
|
68
|
+
const assertEBulkUnit = new AssertionUnitConfigBuilder(
|
|
69
|
+
"assert-e-bulk",
|
|
70
|
+
"E_BULK != None",
|
|
71
|
+
"E_BULK does not exist!",
|
|
72
|
+
).build();
|
|
73
|
+
|
|
74
|
+
const AValue = "np.linalg.norm(np.cross(SLAB.lattice.vectors.a, SLAB.lattice.vectors.b))";
|
|
75
|
+
const setSurfaceUnit = new AssignmentUnitConfigBuilder("surface", "A", AValue).build();
|
|
76
|
+
|
|
77
|
+
const setNBulkUnit = new AssignmentUnitConfigBuilder(
|
|
78
|
+
"n-bulk",
|
|
79
|
+
"N_BULK",
|
|
80
|
+
"len(BULK.basis.elements)",
|
|
81
|
+
).build();
|
|
82
|
+
const setNSlabUnit = new AssignmentUnitConfigBuilder(
|
|
83
|
+
"n-slab",
|
|
84
|
+
"N_SLAB",
|
|
85
|
+
"len(SLAB.basis.elements)",
|
|
86
|
+
).build();
|
|
87
|
+
|
|
88
|
+
input = getAssignmentUnitInput(scfUnit, "total_energy");
|
|
89
|
+
const setESlabUnit = new AssignmentUnitConfigBuilder(
|
|
90
|
+
"e-slab",
|
|
91
|
+
"E_SLAB",
|
|
92
|
+
"total_energy",
|
|
93
|
+
input,
|
|
94
|
+
).build();
|
|
95
|
+
|
|
96
|
+
const results = [{ name: "surface_energy" }];
|
|
97
|
+
const SEValue = "1 / (2 * A) * (E_SLAB - E_BULK * (N_SLAB/N_BULK))";
|
|
98
|
+
const surfaceEnergyUnit = new AssignmentUnitConfigBuilder(
|
|
99
|
+
"surface-energy",
|
|
100
|
+
"SURFACE_ENERGY",
|
|
101
|
+
SEValue,
|
|
102
|
+
[],
|
|
103
|
+
results,
|
|
104
|
+
).build();
|
|
105
|
+
|
|
106
|
+
return [
|
|
107
|
+
getSlabUnit,
|
|
108
|
+
setSlabUnit,
|
|
109
|
+
getBulkUnit,
|
|
110
|
+
setBulkUnit,
|
|
111
|
+
assertBulkUnit,
|
|
112
|
+
getEBulkUnit,
|
|
113
|
+
setEBulkUnit,
|
|
114
|
+
assertEBulkUnit,
|
|
115
|
+
setSurfaceUnit,
|
|
116
|
+
setNBulkUnit,
|
|
117
|
+
setNSlabUnit,
|
|
118
|
+
scfUnit,
|
|
119
|
+
setESlabUnit,
|
|
120
|
+
surfaceEnergyUnit,
|
|
121
|
+
];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export { getSurfaceEnergySubworkflowUnits };
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import { Application } from "@exabyte-io/ade.js";
|
|
2
|
+
import { Model, ModelFactory } from "@exabyte-io/mode.js";
|
|
3
|
+
import {
|
|
4
|
+
ContextAndRenderFieldsMixin,
|
|
5
|
+
NamedDefaultableRepetitionImportantSettingsInMemoryEntity,
|
|
6
|
+
} from "@mat3ra/code/dist/js/entity";
|
|
7
|
+
import { Utils } from "@mat3ra/utils";
|
|
8
|
+
import lodash from "lodash";
|
|
9
|
+
import { mix } from "mixwith";
|
|
10
|
+
import _ from "underscore";
|
|
11
|
+
|
|
12
|
+
import { UNIT_TYPES } from "../enums";
|
|
13
|
+
import { UnitFactory } from "../units";
|
|
14
|
+
import { setNextLinks, setUnitsHead } from "../utils";
|
|
15
|
+
import { ConvergenceMixin } from "./convergence";
|
|
16
|
+
|
|
17
|
+
/* eslint max-classes-per-file:0 */
|
|
18
|
+
|
|
19
|
+
class BaseSubworkflow extends mix(NamedDefaultableRepetitionImportantSettingsInMemoryEntity).with(
|
|
20
|
+
ConvergenceMixin,
|
|
21
|
+
ContextAndRenderFieldsMixin,
|
|
22
|
+
) {}
|
|
23
|
+
|
|
24
|
+
export class Subworkflow extends BaseSubworkflow {
|
|
25
|
+
static usePredefinedIds = false;
|
|
26
|
+
|
|
27
|
+
constructor(config) {
|
|
28
|
+
super(config);
|
|
29
|
+
this._Application = Application;
|
|
30
|
+
this._ModelFactory = ModelFactory;
|
|
31
|
+
this._UnitFactory = UnitFactory;
|
|
32
|
+
this.initialize();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
initialize() {
|
|
36
|
+
this._application = new this._Application(this.prop("application"));
|
|
37
|
+
this._model = this._ModelFactory.create({
|
|
38
|
+
...this.prop("model"),
|
|
39
|
+
application: this.prop("application"),
|
|
40
|
+
});
|
|
41
|
+
this._units = setNextLinks(setUnitsHead(this.prop("units", [])), this.id).map((cfg) =>
|
|
42
|
+
this._UnitFactory.create(
|
|
43
|
+
Object.assign(cfg, { application: this.application.toJSON() }),
|
|
44
|
+
),
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
static generateSubworkflowId(...args) {
|
|
49
|
+
args[0] = `subworkflow-${args[0]}`;
|
|
50
|
+
if (this.usePredefinedIds) return Utils.uuid.getUUIDFromNamespace(...args);
|
|
51
|
+
return Utils.uuid.getUUID();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static get defaultConfig() {
|
|
55
|
+
const defaultName = "New Subworkflow";
|
|
56
|
+
return {
|
|
57
|
+
_id: this.generateSubworkflowId(defaultName),
|
|
58
|
+
name: defaultName,
|
|
59
|
+
application: Application.defaultConfig,
|
|
60
|
+
model: Model.defaultConfig,
|
|
61
|
+
properties: [],
|
|
62
|
+
units: [],
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/*
|
|
67
|
+
* @returns {SubworkflowUnit}
|
|
68
|
+
*/
|
|
69
|
+
getAsUnit() {
|
|
70
|
+
return this._UnitFactory.create({
|
|
71
|
+
type: UNIT_TYPES.subworkflow,
|
|
72
|
+
_id: this.id,
|
|
73
|
+
name: this.name,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/*
|
|
78
|
+
* @summary Used to generate initial application tree, therefore omit setting application.
|
|
79
|
+
*/
|
|
80
|
+
static fromArguments(
|
|
81
|
+
application,
|
|
82
|
+
model,
|
|
83
|
+
method,
|
|
84
|
+
name,
|
|
85
|
+
units = [],
|
|
86
|
+
config = {},
|
|
87
|
+
Cls = Subworkflow,
|
|
88
|
+
) {
|
|
89
|
+
return new Cls({
|
|
90
|
+
...config,
|
|
91
|
+
_id: Cls.generateSubworkflowId(name),
|
|
92
|
+
name,
|
|
93
|
+
application: application.toJSON(),
|
|
94
|
+
properties: lodash.sortedUniq(
|
|
95
|
+
lodash.flatten(units.filter((x) => x.resultNames).map((x) => x.resultNames)),
|
|
96
|
+
),
|
|
97
|
+
model: {
|
|
98
|
+
...model.toJSON(),
|
|
99
|
+
method: method.toJSON(),
|
|
100
|
+
},
|
|
101
|
+
units: units.map((unit) => (unit.toJSON ? unit.toJSON() : unit)),
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
get application() {
|
|
106
|
+
return this._application;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
setApplication(application) {
|
|
110
|
+
// TODO: adjust the logic above to take into account whether units need re-rendering after version change etc.
|
|
111
|
+
// reset units if application name changes
|
|
112
|
+
const previousApplicationName = this.application.name;
|
|
113
|
+
this._application = application;
|
|
114
|
+
|
|
115
|
+
if (previousApplicationName !== application.name) {
|
|
116
|
+
// TODO: figure out how to set a default unit per new application instead of removing all
|
|
117
|
+
this.setUnits([]);
|
|
118
|
+
} else {
|
|
119
|
+
// propagate new application version to all units
|
|
120
|
+
this.units
|
|
121
|
+
.filter((unit) => typeof unit.setApplication === "function")
|
|
122
|
+
.forEach((unit) => unit.setApplication(application, true));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
this.setProp("application", application.toJSON());
|
|
126
|
+
// set model to the default one for the application selected
|
|
127
|
+
this.setModel(
|
|
128
|
+
this._ModelFactory.createFromApplication({
|
|
129
|
+
application: this.prop("application"),
|
|
130
|
+
}),
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
get model() {
|
|
135
|
+
return this._model;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
setModel(model) {
|
|
139
|
+
this._model = model;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
get units() {
|
|
143
|
+
return this._units;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
setUnits(units) {
|
|
147
|
+
this._units = units;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
toJSON(exclude = []) {
|
|
151
|
+
return {
|
|
152
|
+
...super.toJSON(exclude),
|
|
153
|
+
model: this.model.toJSON(),
|
|
154
|
+
units: this.units.map((x) => x.toJSON()),
|
|
155
|
+
...(this.compute ? { compute: this.compute } : {}), // {"compute": null } won't pass esse validation
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
get contextProviders() {
|
|
160
|
+
const unitsWithContextProviders = this.units.filter(
|
|
161
|
+
(u) => u.allContextProviders && u.allContextProviders.length,
|
|
162
|
+
);
|
|
163
|
+
const allContextProviders = _.flatten(
|
|
164
|
+
unitsWithContextProviders.map((u) => u.allContextProviders),
|
|
165
|
+
);
|
|
166
|
+
const subworkflowContextProviders = allContextProviders.filter(
|
|
167
|
+
(p) => p.isSubworkflowContextProvider,
|
|
168
|
+
);
|
|
169
|
+
return _.uniq(subworkflowContextProviders, (p) => p.name);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Extracts a reduced version of the entity config to be stored inside redux state.
|
|
174
|
+
* This is used to track changes to context, monitors, properties, etc. when multiple materials are in state.
|
|
175
|
+
*/
|
|
176
|
+
extractReducedExternalDependentConfig() {
|
|
177
|
+
return {
|
|
178
|
+
id: this.id,
|
|
179
|
+
context: this.context || {},
|
|
180
|
+
units: this.units.map((unit) => unit.extractReducedExternalDependentConfig()),
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Applies the reduced config obtained from extractReducedExternalDependentConfig on the entity.
|
|
186
|
+
*/
|
|
187
|
+
applyReducedExternalDependentConfig(config) {
|
|
188
|
+
this.context = config.context || {};
|
|
189
|
+
this.units.forEach((unit) => {
|
|
190
|
+
const unitConfig = (config.units || []).find((c) => c.id === unit.flowchartId);
|
|
191
|
+
unit.applyReducedExternalDependentConfig(unitConfig || {});
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
get contextFromAssignmentUnits() {
|
|
196
|
+
const ctx = {};
|
|
197
|
+
this.units
|
|
198
|
+
.filter((u) => u.type === UNIT_TYPES.assignment)
|
|
199
|
+
.forEach((u) => {
|
|
200
|
+
ctx[u.operand] = u.value;
|
|
201
|
+
});
|
|
202
|
+
return ctx;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
render(context = {}) {
|
|
206
|
+
const ctx = {
|
|
207
|
+
...context,
|
|
208
|
+
application: this.application,
|
|
209
|
+
methodData: this.model.method.data,
|
|
210
|
+
model: this.model.toJSON(),
|
|
211
|
+
// context below is assembled from context providers and passed to units to override theirs
|
|
212
|
+
...this.context,
|
|
213
|
+
subworkflowContext: this.contextFromAssignmentUnits,
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
this.units.forEach((u) => u.render(ctx));
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* TODO: reuse workflow function instead
|
|
221
|
+
* @param unit {Unit}
|
|
222
|
+
* @param head {Boolean}
|
|
223
|
+
* @param index {Number}
|
|
224
|
+
*/
|
|
225
|
+
addUnit(unit, index = -1) {
|
|
226
|
+
const { units } = this;
|
|
227
|
+
if (units.length === 0) {
|
|
228
|
+
unit.head = true;
|
|
229
|
+
this.setUnits([unit]);
|
|
230
|
+
} else {
|
|
231
|
+
if (index >= 0) units.splice(index, 0, unit);
|
|
232
|
+
else units.push(unit);
|
|
233
|
+
this.setUnits(setNextLinks(setUnitsHead(units)));
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
removeUnit(flowchartId) {
|
|
238
|
+
const previousUnit = this.units.find((x) => x.next === flowchartId);
|
|
239
|
+
if (previousUnit) previousUnit.unsetProp("next");
|
|
240
|
+
// TODO: remove the setNextLinks and setUnitsHead and handle the logic via flowchart designer
|
|
241
|
+
this.setUnits(
|
|
242
|
+
setNextLinks(setUnitsHead(this.units.filter((x) => x.flowchartId !== flowchartId))),
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
get properties() {
|
|
247
|
+
return lodash.flatten(this.units.map((x) => x.resultNames));
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
getUnit(flowchartId) {
|
|
251
|
+
return this.units.find((x) => x.flowchartId === flowchartId);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
unitIndex(flowchartId) {
|
|
255
|
+
return lodash.findIndex(this.units, (unit) => {
|
|
256
|
+
return unit.flowchartId === flowchartId;
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
replaceUnit(index, unit) {
|
|
261
|
+
this.units[index] = unit;
|
|
262
|
+
this.setUnits(setNextLinks(setUnitsHead(this.units)));
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// eslint-disable-next-line class-methods-use-this
|
|
266
|
+
get scopeVariables() {
|
|
267
|
+
return ["N_k", "N_k_nonuniform"];
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// eslint-disable-next-line class-methods-use-this
|
|
271
|
+
get scalarResults() {
|
|
272
|
+
return ["total_energy", "pressure"];
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
get isMultiMaterial() {
|
|
276
|
+
return this.prop("isMultiMaterial", false);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
get isDraft() {
|
|
280
|
+
return this.prop("isDraft", false);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
setIsDraft(bool) {
|
|
284
|
+
return this.setProp("isDraft", bool);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
get methodData() {
|
|
288
|
+
return this.model.method.data;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* @summary Calculates hash of the subworkflow. Meaningful fields are units, app and model.
|
|
293
|
+
* units must be sorted topologically before hashing (already sorted).
|
|
294
|
+
*/
|
|
295
|
+
calculateHash() {
|
|
296
|
+
const config = this.toJSON();
|
|
297
|
+
const meaningfulFields = {
|
|
298
|
+
application: Utils.specific.removeTimestampableKeysFromConfig(config.application),
|
|
299
|
+
model: this._calculateModelHash(),
|
|
300
|
+
units: _.map(this.units, (u) => u.calculateHash()).join(),
|
|
301
|
+
};
|
|
302
|
+
return Utils.hash.calculateHashFromObject(meaningfulFields);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
_calculateModelHash() {
|
|
306
|
+
const { model } = this.toJSON();
|
|
307
|
+
// ignore empty data object
|
|
308
|
+
if (this.model.method.omitInHashCalculation) delete model.method.data;
|
|
309
|
+
return Utils.hash.calculateHashFromObject(model);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
findUnitById(id) {
|
|
313
|
+
// TODO: come back and refactor after converting flowchartId to id
|
|
314
|
+
return this.units.find((u) => u.flowchartId === id);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
findUnitKeyById(id) {
|
|
318
|
+
const index = this.units.findIndex((u) => u.flowchartId === id);
|
|
319
|
+
return `units.${index}`;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
findUnitWithTag(tag) {
|
|
323
|
+
return this.units.find((unit) => unit.tags.includes(tag));
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
get hasConvergence() {
|
|
327
|
+
return !!this.convergenceParam && !!this.convergenceResult && !!this.convergenceSeries;
|
|
328
|
+
}
|
|
329
|
+
}
|