private SteadyStateModel GetSteadyStateModel( List <ElementNode> elements, List <ConnectionNode> rootConnections, Object modelParameters) { Dictionary <string, ElementEntry> elementEntries = new Dictionary <string, ElementEntry>(); int nodeIndicies = 0; SteadyStateModel model = new SteadyStateModel(); foreach (var element in elements) { //get Object from element.Definition Object obj = BuildObject(element.Definition); //get Element description( nodes and parameters) if (!elementsMap.ContainsKey(obj.Name)) { errors.Add(new ErrorMessage($"Не существует элемента {obj.Name}", element.Line, element.Position)); continue; } ElementDescription description = elementsMap[obj.Name]; Dictionary <string, Pin> elementPins = new Dictionary <string, Pin>(); var keys = description.GetNodes(); for (int i = 0; i < keys.Count; i++) { string key = keys.ElementAt(i); Pin pin = description.CreatePin(key, nodeIndicies); elementPins.Add(key, pin); model.AddPin(pin); nodeIndicies++; } //create element entry elementEntries.Add(element.Id, new ElementEntry(description, obj, elementPins)); bool valid = description.Validate(ref obj, ref errors); if (valid) { try { if (description.Validate(ref obj, ref errors)) { ISteadyStateElement modelElement = description.CreateSteadyStateElement(obj, elementPins); if (modelElement is null) { errors.Add(new ErrorMessage($"Element {obj.Name} cannot be used in steady state model", element.Line, element.Position)); } else { model.AddElement(modelElement); } } } catch (MissingValueException exc) { errors.Add(new ErrorMessage($"Missing parameter {exc.Key} in element {obj.Name}", element.Line, element.Position)); } catch (Exception exc) { errors.Add(new ErrorMessage($"Ошибка при создании элемента {obj.Name}: {exc.Message}", element.Line, element.Position)); } } } //resolve connections between elements List <Connection> connections = new List <Connection>(); foreach (var connection in rootConnections) { try { if (!elementEntries.ContainsKey(connection.Element1)) { errors.Add(new ErrorMessage($"Non existing element {connection.Element1} in connection", connection.Line, connection.Position)); continue; } if (!elementEntries.ContainsKey(connection.Element2)) { errors.Add(new ErrorMessage($"Non existing element {connection.Element2} in connection", connection.Line, connection.Position)); continue; } ElementEntry entry1 = elementEntries[connection.Element1]; ElementEntry entry2 = elementEntries[connection.Element2]; ElementDescription element1 = entry1.GetDescription(); ElementDescription element2 = entry2.GetDescription(); if (!element1.ContainsNode(connection.Node1)) { errors.Add(new ErrorMessage($"Non existing pin {connection.Node1} in element {connection.Element1}", connection.Line, connection.Position)); continue; } if (!element2.ContainsNode(connection.Node2)) { errors.Add(new ErrorMessage($"Non existing element {connection.Node2} in element {connection.Element2}", connection.Line, connection.Position)); continue; } ElementDescription.NodeType node1 = element1.GetNodeType(connection.Node1); ElementDescription.NodeType node2 = element2.GetNodeType(connection.Node2); if (node1 != node2) { errors.Add(new ErrorMessage($"Pins in connection ({connection.Element1}.{connection.Node1},{connection.Element2}.{connection.Node2}) have different types", connection.Line, connection.Position)); continue; } connections.Add(new Connection(entry1.GetPin(connection.Node1), entry2.GetPin(connection.Node2))); } catch (Exception exc) { throw exc; } } foreach (Connection connection in connections) { model.AddElement(connection.CreateSteadyStateElement()); } try { Object solver = (Object)Convert(modelParameters.GetValue("solver"), Constant.Type.Object); switch (solver.Name) { case "newton": FloatValue fAbsTol = Convert(solver.GetValue("fAbsTol"), Constant.Type.Float) as FloatValue; IntValue iterations = Convert(solver.GetValue("iterations"), Constant.Type.Int) as IntValue; FloatValue alpha = Convert(solver.GetValue("alpha"), Constant.Type.Float) as FloatValue; model.SetSolver(new SteadyStateNewtonSolver(fAbsTol.Value, iterations.Value, alpha.Value)); break; default: errors.Add(new ErrorMessage("Unknown solver in steadystate model")); return(null); } FloatValue baseFrequency = (FloatValue)Convert(modelParameters.GetValue("baseFrequency"), Constant.Type.Float); model.SetBaseFrequency(baseFrequency.Value); } catch (MissingValueException exc) { errors.Add(new ErrorMessage($"Отсутствует аргумент {exc.Key} в определении модели.")); return(null); } catch (Exception exc) { errors.Add(new ErrorMessage($"Exception: {exc.Message}")); return(null); } return(model); }
private Transient.TransientModel GetTransientModel( List <ElementNode> elements, List <ConnectionNode> rootConnections, Object modelParameters) { Dictionary <string, ElementEntry> elementEntries = new Dictionary <string, ElementEntry>(); int nodeIndicies = 0; Transient.TransientModel model = new Transient.TransientModel(); foreach (var element in elements) { //get Object from element.Definition Object obj = BuildObject(element.Definition); if (!elementsMap.ContainsKey(obj.Name)) { errors.Add(new ErrorMessage($"Не существует элемента {obj.Name}", element.Line, element.Position)); continue; } //get Element description( nodes and parameters) ElementDescription description = elementsMap[obj.Name]; Dictionary <string, Pin> elementPins = new Dictionary <string, Pin>(); var keys = description.GetNodes(); for (int i = 0; i < keys.Count; i++) { string key = keys.ElementAt(i); Pin pin = description.CreatePin(key, nodeIndicies); elementPins.Add(key, pin); model.AddPin(pin); nodeIndicies++; } //create element entry elementEntries.Add(element.Id, new ElementEntry(description, obj, elementPins)); bool valid = description.Validate(ref obj, ref errors); if (valid) { try { if (description.Validate(ref obj, ref errors)) { ITransientElement modelElement = description.CreateTransientElement(obj, elementPins); if (modelElement is null) { errors.Add(new ErrorMessage($"Элемент {obj.Name} не может использоваться для расчёта переходных процессов", element.Line, element.Position)); } else { model.AddElement(modelElement); } } } catch (MissingValueException exc) { errors.Add(new ErrorMessage($"Отсутствует параметр {exc.Key} в элементе {obj.Name}", element.Line, element.Position)); } catch (Exception) { errors.Add(new ErrorMessage($"Ошибка при создании элемента {obj.Name}", element.Line, element.Position)); } } } //resolve connections between elements List <Connection> connections = new List <Connection>(); foreach (var connection in rootConnections) { try { if (!elementEntries.ContainsKey(connection.Element1)) { errors.Add(new ErrorMessage($"Non existing element {connection.Element1} in connection", connection.Line, connection.Position)); continue; } if (!elementEntries.ContainsKey(connection.Element2)) { errors.Add(new ErrorMessage($"Non existing element {connection.Element2} in connection", connection.Line, connection.Position)); continue; } ElementEntry entry1 = elementEntries[connection.Element1]; ElementEntry entry2 = elementEntries[connection.Element2]; ElementDescription element1 = entry1.GetDescription(); ElementDescription element2 = entry2.GetDescription(); if (!element1.ContainsNode(connection.Node1)) { errors.Add(new ErrorMessage($"Non existing pin {connection.Node1} in element {connection.Element1}", connection.Line, connection.Position)); continue; } if (!element2.ContainsNode(connection.Node2)) { errors.Add(new ErrorMessage($"Non existing element {connection.Node2} in element {connection.Element2}", connection.Line, connection.Position)); continue; } ElementDescription.NodeType node1 = element1.GetNodeType(connection.Node1); ElementDescription.NodeType node2 = element2.GetNodeType(connection.Node2); if (node1 != node2) { errors.Add(new ErrorMessage($"Pins in connection ({connection.Element1}.{connection.Node1},{connection.Element2}.{connection.Node2}) have different types", connection.Line, connection.Position)); continue; } connections.Add(new Connection(entry1.GetPin(connection.Node1), entry2.GetPin(connection.Node2))); } catch (Exception exc) { throw exc; } } foreach (Connection connection in connections) { model.AddElement(connection.CreateTransientElement()); } try { Object solver = (Object)Convert(modelParameters.GetValue("solver"), Constant.Type.Object); switch (solver.Name) { case "radauIIA5": { FloatValue fAbsTol = Convert(solver.GetValue("fAbsTol"), Constant.Type.Float) as FloatValue; IntValue iterations = Convert(solver.GetValue("iterations"), Constant.Type.Int) as IntValue; FloatValue alpha = Convert(solver.GetValue("alpha"), Constant.Type.Float) as FloatValue; FloatValue step = Convert(solver.GetValue("step"), Constant.Type.Float) as FloatValue; model.SetSolver(new Equations.DAE.Implicit.RADAUIIA5(fAbsTol.Value, iterations.Value, alpha.Value, step.Value)); } break; case "radauIIA3": { FloatValue fAbsTol = Convert(solver.GetValue("fAbsTol"), Constant.Type.Float) as FloatValue; IntValue iterations = Convert(solver.GetValue("iterations"), Constant.Type.Int) as IntValue; FloatValue alpha = Convert(solver.GetValue("alpha"), Constant.Type.Float) as FloatValue; FloatValue step = Convert(solver.GetValue("step"), Constant.Type.Float) as FloatValue; model.SetSolver(new Equations.DAE.Implicit.RADAUIIA3(fAbsTol.Value, iterations.Value, alpha.Value, step.Value)); } break; case "bdf1": { FloatValue fAbsTol = Convert(solver.GetValue("fAbsTol"), Constant.Type.Float) as FloatValue; IntValue iterations = Convert(solver.GetValue("iterations"), Constant.Type.Int) as IntValue; FloatValue alpha = Convert(solver.GetValue("alpha"), Constant.Type.Float) as FloatValue; FloatValue step = Convert(solver.GetValue("step"), Constant.Type.Float) as FloatValue; model.SetSolver(new Equations.DAE.Implicit.BDF1(fAbsTol.Value, iterations.Value, alpha.Value, step.Value)); } break; default: errors.Add(new ErrorMessage("Unknown solver in transient model")); return(null); } FloatValue t0 = Convert(modelParameters.GetValue("t0"), Constant.Type.Float) as FloatValue; FloatValue t1 = Convert(modelParameters.GetValue("t1"), Constant.Type.Float) as FloatValue; model.SetT0(t0.Value); model.SetT1(t1.Value); } catch (MissingValueException exc) { errors.Add(new ErrorMessage($"Отсутствует аргумент {exc.Key} в определении модели.")); return(null); } catch (Exception exc) { errors.Add(new ErrorMessage($"Exception: {exc.Message}")); return(null); } return(model); }