public bool Check(string sourceCode)
        {
            var status = parser.TryParseProgram(sourceCode, out var prog, out var internalerror, out var position);


            if (!status)
            {
                _eventAggregator.PublishOnUIThreadAsync(new UpdateSolverStatusMessage(internalerror, SolverStatus.Error));
            }
            else
            {
                if (prog.ClassDefinitions.Count == 1)
                {
                    var translator      = new ModelTranslatorV1();
                    var printer         = new ModelicaTreePrinter();
                    var pretty          = new ModelicaPrettyPrinter();
                    var instancePrinter = new InstancePrinter();
                    var flattening      = new Flattening();

                    var        astText    = printer.Transform(prog);
                    var        prettyTest = pretty.Transform(prog);
                    DAEProblem model      = null;

                    string prettyflat = "";

                    try
                    {
                        var flatModel = flattening.Transform(prog.ClassDefinitions.First());
                        prettyflat = instancePrinter.Transform(flatModel);
                        //model = translator.Translate(flatModel);
                    }
                    catch (Exception e)
                    {
                        _eventAggregator.PublishOnUIThreadAsync(new UpdateSolverStatusMessage($"{e.Message}", SolverStatus.Error));
                        return(false);
                    }


                    _eventAggregator.PublishOnUIThreadAsync(new UpdateModelAnalysisMessage()
                    {
                        SyntaxTree = astText, FlattenedModel = prettyflat, CalculationModel = model
                    });
                    _eventAggregator.PublishOnUIThreadAsync(new UpdateSolverStatusMessage("Model OK", SolverStatus.OK));
                }
                else
                {
                    throw new InvalidOperationException("Multiple class definitions detected. Flattening can only resolve one class.");
                }
            }

            return(status);
        }
Beispiel #2
0
        public DAEProblem Translate(ClassDefinition model)
        {
            var problem = new DAEProblem();

            problem.Name = model.ID;

            foreach (var element in model.Elements)
            {
                Handle(problem, element);
            }

            return(problem);
        }
Beispiel #3
0
        static void LoktaVolterraHardoded()
        {
            var logger     = new NoLogger();
            var model      = new DAEProblem();
            var integrator = new ExplicitEuler();

            integrator.StepSize = 0.1;
            integrator.EndTime  = 200;

            var N1  = new Variable("N1", 5);
            var N2  = new Variable("N2", 10);
            var dN1 = new Variable("dN1dt", 0);
            var dN2 = new Variable("dN2dt", 0);
            var e1  = new Variable("e1", 0.09);
            var g1  = new Variable("g1", 0.01);
            var e2  = new Variable("e2", 0.04);
            var g2  = new Variable("g2", 0.01);

            var eq1 = new Equation(N1 * (e1 - g1 * N2) - dN1);
            var eq2 = new Equation(-N2 * (e2 - g2 * N1) - dN2);


            model.AlgebraicVariables.Add(N1);
            model.AlgebraicVariables.Add(N2);
            model.DifferentialVariables.Add(dN1);
            model.DifferentialVariables.Add(dN2);
            model.Equations.Add(eq1);
            model.Equations.Add(eq2);
            model.Mapping.Add(dN1, N1);
            model.Mapping.Add(dN2, N2);
            model.Initialize(new NoLogger());

            var results = integrator.Integrate(model, logger);

            using (var sw = new StreamWriter(Environment.CurrentDirectory + "\\results.csv"))
            {
                sw.WriteLine("time;" + string.Join("; ", model.AlgebraicVariables.Select(v => v.Name)));

                foreach (var result in results)
                {
                    sw.WriteLine(result.ToString());
                }
            }
        }
Beispiel #4
0
        public DAEProblem Translate(Instance model)
        {
            var problem = new DAEProblem();

            problem.Name = model.ID;

            problem.Parameters.Add(new Variable("pi", Math.PI));

            foreach (var element in model.Parts)
            {
                Handle(problem, element);
            }
            foreach (var element in model.Equations)
            {
                Handle(problem, element);
            }

            return(problem);
        }
Beispiel #5
0
        void Handle(DAEProblem problem, object value)
        {
            switch (value)
            {
            case Instance i:
            {
                var vari = new Variable(i.ID, 0.0);

                var compClause = i.Source as ComponentClause;

                bool isParameter = false;
                if (compClause != null)
                {
                    if (compClause.Variability == VariabilityPrefix.Parameter)
                    {
                        isParameter = true;
                    }
                }

                if (i.Value != null)
                {
                    //problem.Equations.Add(new Equation(vari - i.Value.Evaluate()));
                    vari.SetValue(i.Value.Evaluate());
                    isParameter = true;
                }


                var initial = i.Parts.FirstOrDefault(p => p.ID == "start");
                if (initial != null && initial.Value != null)
                {
                    vari.SetValue(initial.Value.Evaluate());
                }

                if (isParameter)
                {
                    problem.Parameters.Add(vari);
                }
                else
                {
                    problem.AlgebraicVariables.Add(vari);
                }
            }
            break;

            case ComponentClause c:
                foreach (var decl in c.Declarations)
                {
                    decl.Clause = c;
                    Handle(problem, decl);
                }
                break;

            case ComponentDeclaration e:
            {
                var vari = new Variable(e.ID, 0.0);

                if (e.Modification != null)
                {
                    foreach (var mod in e.Modification.Modifications)
                    {
                        if (mod.Reference.ToString().ToLower() == "start")
                        {
                            vari.SetValue(mod.Modification.Value.Evaluate());
                        }
                    }
                }

                if (e.Modification != null && e.Modification.Value != null)
                {
                    vari.SetValue(e.Modification.Value.Evaluate());
                    e.Clause.Variability = VariabilityPrefix.Parameter;
                }

                if (e.Clause.Variability == VariabilityPrefix.Parameter)
                {
                    problem.Parameters.Add(vari);
                }
                else
                {
                    problem.AlgebraicVariables.Add(vari);
                }
            }
            break;

            case EquationSection e:
                foreach (var eq in e.Equations)
                {
                    Handle(problem, eq);
                }
                break;

            case SimpleEquation e:
                var left     = HandleExpression(problem, e.Left);
                var right    = HandleExpression(problem, e.Right);
                var residual = right - left;
                problem.Equations.Add(new Equation(residual));
                break;
            }
        }
Beispiel #6
0
        Expression HandleExpression(DAEProblem problem, ModelicaExpression expr)
        {
            switch (expr)
            {
            case BinaryExpression b:
            {
                switch (b.Operator)
                {
                case BinaryOperator.Add:
                    return(HandleExpression(problem, b.Left) + HandleExpression(problem, b.Right));

                case BinaryOperator.Subtract:
                    return(HandleExpression(problem, b.Left) - HandleExpression(problem, b.Right));

                case BinaryOperator.Multiply:
                    return(HandleExpression(problem, b.Left) * HandleExpression(problem, b.Right));

                case BinaryOperator.Divide:
                    return(HandleExpression(problem, b.Left) / HandleExpression(problem, b.Right));

                case BinaryOperator.Power:
                    return(Sym.Pow(HandleExpression(problem, b.Left), HandleExpression(problem, b.Right)));
                }
            }
            break;

            case UnaryExpression u:
            {
                switch (u.Operator)
                {
                case UnaryOperator.Negate:
                    return(-HandleExpression(problem, u.Child));

                case UnaryOperator.Parentheses:
                    return(Sym.Par(HandleExpression(problem, u.Child)));

                case UnaryOperator.TimeDerivative:
                    var y = HandleExpression(problem, u.Child) as Variable;
                    if (y == null)
                    {
                        throw new InvalidOperationException("Cannot handle expressions inside der operator yet.");
                    }

                    var dery = new Variable("der(" + y.Name + ")", 0);

                    var existingVar = problem.DifferentialVariables.FirstOrDefault(v => v.Name == dery.Name);
                    if (existingVar == null)
                    {
                        problem.DifferentialVariables.Add(dery);
                        problem.Mapping.Add(dery, y);
                        return(dery);
                    }
                    else
                    {
                        return(existingVar);
                    }

                default:
                    throw new InvalidOperationException("Unknown unary operator " + u.Operator.ToString());
                }
            }

            case BuiltinFunction u:
            {
                switch (u.Type)
                {
                case BuiltinFunctionType.Sin:
                    return(Sym.Sin(HandleExpression(problem, u.Child)));

                case BuiltinFunctionType.Cos:
                    return(Sym.Cos(HandleExpression(problem, u.Child)));

                case BuiltinFunctionType.Tan:
                    return(Sym.Tan(HandleExpression(problem, u.Child)));

                case BuiltinFunctionType.Log:
                    return(Sym.Ln(HandleExpression(problem, u.Child)));

                case BuiltinFunctionType.Exp:
                    return(Sym.Exp(HandleExpression(problem, u.Child)));

                case BuiltinFunctionType.Sqrt:
                    return(Sym.Sqrt(HandleExpression(problem, u.Child)));

                default:
                    throw new InvalidOperationException("Unknown built-in fucntion " + u.Type.ToString());
                }
            }

            case DoubleLiteral l:
                return(new Variable(l.Value.ToString(), l.Value));

            case Reference r:
            {
                var vari = problem.ResolveReference(r.ToString());
                if (vari != null)
                {
                    return(vari);
                }
                else
                {
                    throw new NullReferenceException("Variable " + r.ToString() + " not defined.");
                }
            }

            default:
                throw new InvalidOperationException("Unknown expression " + expr.ToString());
            }
            return(null);
        }
        public bool Simulate(string sourceCode)
        {
            var status = parser.TryParseProgram(sourceCode, out var prog, out var error, out var position);

            if (status)
            {
                var translator = new ModelTranslatorV1();
                var flattening = new Flattening();

                var ast = prog.ClassDefinitions.Last();

                var instance = flattening.Transform(ast);

                DAEProblem model = null;

                try
                {
                    model = translator.Translate(instance);
                }
                catch (Exception e)
                {
                    _eventAggregator.PublishOnUIThreadAsync(new UpdateSolverStatusMessage($"{e.Message}", SolverStatus.Error));
                }



                var integrator = createIntegratorFromAnnotation(ast);

                integrator.StepSize     = 0.1;
                integrator.EndTime      = 1;
                integrator.OnIteration += (i) => OnIteration(integrator, i);

                updateIntegratorSettings(ast, integrator);

                var logger = new NoLogger();

                try
                {
                    integrator.Discretize(model);
                    model.Initialize(logger);
                }
                catch (Exception e)
                {
                    _eventAggregator.PublishOnUIThreadAsync(new UpdateSolverStatusMessage($"{e.Message}", SolverStatus.Error));
                    return(false);
                }


                if (model.SystemToSolve.NumberOfEquations != model.SystemToSolve.NumberOfVariables)
                {
                    _eventAggregator.PublishOnUIThreadAsync(new UpdateSolverStatusMessage($"System not square! V={model.SystemToSolve.NumberOfVariables}, E={model.SystemToSolve.NumberOfEquations}", SolverStatus.Error));
                    return(false);
                }

                Stopwatch w = new Stopwatch();
                _eventAggregator.PublishOnUIThreadAsync(new UpdateSolverStatusMessage("Integration started", SolverStatus.Busy));

                try
                {
                    w.Start();
                    var results = integrator.Integrate(model, logger);
                    w.Stop();
                    Console.WriteLine("Integration took " + w.ElapsedMilliseconds + "ms");
                    _eventAggregator.PublishOnUIThreadAsync(new UpdateModelResultMessage()
                    {
                        ModelName = model.Name, AlgebraicStates = model.AlgebraicVariables, DifferentialStates = model.DifferentialVariables, TimeSteps = results
                    });
                    _eventAggregator.PublishOnUIThreadAsync(new UpdateSolverStatusMessage($"Integration finished ({w.ElapsedMilliseconds} ms)", SolverStatus.OK));
                }
                catch (Exception e)
                {
                    _eventAggregator.PublishOnUIThreadAsync(new UpdateSolverStatusMessage($"{e.Message}", SolverStatus.Error));
                    return(false);
                }
            }
            else
            {
                _eventAggregator.PublishOnUIThreadAsync(new UpdateSolverStatusMessage(error, SolverStatus.Error));
            }


            return(true);
        }