<jupyter_start><jupyter_text>Introduction<jupyter_code>#r "BoSSSpad.dll"
using System;
using System.Collections.Generic;
using System.Linq;
using ilPSP;
using ilPSP.Utils;
using BoSSS.Platform;
using BoSSS.Platform.LinAlg;
using BoSSS.Foundation;
using BoSSS.Foundation.XDG;
using BoSSS.Foundation.Grid;
using BoSSS.Foundation.Grid.Classic;
using BoSSS.Foundation.Grid.RefElements;
using BoSSS.Foundation.IO;
using BoSSS.Solution;
using BoSSS.Solution.Control;
using BoSSS.Solution.GridImport;
using BoSSS.Solution.Statistic;
using BoSSS.Solution.Utils;
using BoSSS.Solution.AdvancedSolvers;
using BoSSS.Solution.Gnuplot;
using BoSSS.Application.BoSSSpad;
using BoSSS.Application.XNSE_Solver;
using static BoSSS.Application.BoSSSpad.BoSSSshell;
Init();<jupyter_output><empty_output><jupyter_text>Note: 
- Setting Boundary values and initial values is similar; 
- For most solvers, inital and boundary values are set the same way;
- We will use the incompressible solver as an example:<jupyter_code>using BoSSS.Application.XNSE_Solver;<jupyter_output><empty_output><jupyter_text>Create a control object:<jupyter_code>var C = new XNSE_Control();<jupyter_output><empty_output><jupyter_text>1 From Formulas
If the Formula is simple enough to be represented by C\ code,
it can be embedded in the control file.

However, the code bust be put into a string, since it is not 
possible to serialize classes/objects from the notebook
into a control object:<jupyter_code>string code =  
 "static class MyInitialValue {" // class must be static!
 
    // Warning: static constants are allowed,
    // but any changes outside of the current text box in BoSSSpad
    // will not be recorded for the code that is passed to the solver.
+ " public static double alpha = 0.7;"
 
    // a method, which should be used for an initial value,
    // must be static!
+ " public static double VelocityX(double[] X, double t) {"
+ "    double x = X[0];"
+ "    double y = X[1];"
+ "   return Math.Sin(x*y*alpha);"
+ " }"  
+ "}";
var fo = new BoSSS.Solution.Control.Formula("MyInitialValue.VelocityX", 
                                             true, code);<jupyter_output><empty_output><jupyter_text>Use the BoSSSpad-intrinsic **GetFormulaObject** to set tie inital value:<jupyter_code>C.AddInitialValue("VelocityX", fo);
/// Deprecated:
/// Note: such a declaration is very restrictive;
/// \code{GetFormulaObject} works only for 
/// \begin{itemize}
/// \item a static class
/// \item no dependence on any external parameters
/// \end{itemize}
/// E.g. the following code would only change the behavior in BoSSSpad,
/// but not the code that is passed to the solver:
//Deprecated:
//MyInitialValue.alpha = 0.5;
//MyInitialValue.VelocityX(new double[]{ 0.5, 0.5 }, 0.0);
C.InitialValues["VelocityX"].Evaluate(new double[]{ 0.5, 0.5 }, 0.0)<jupyter_output><empty_output><jupyter_text>2 Advanced functions

Some more advanced mathematical functions, e.g.
Jacobian elliptic functions $\text{sn}(u|m)$, $\text{cn}(u|m)$ and $\text{dn}(u|m)$
are available throug the GNU Scientific Library, for which BoSSS provides
bindings, see e.g.
**BoSSS.Platform.GSL.gsl\_sf\_elljac\_e** 
 2.1 From MATLAB code
Asssume e.g. the following MATLAB code; obviously, this could  
also be implemented in C\, we yust use something smple for demonstration:<jupyter_code>string[] MatlabCode = new string[] {
@"[n,d2] =  size(X_values);",
@"u=zeros(2,n);",
@"for k=1:n",
@"X=[X_values(k,1),X_values(k,2)];",
@"",
@"u_x_main     = -(-sqrt(X(1).^ 2 + X(2).^ 2) / 0.3e1 + 0.4e1 / 0.3e1 * (X(1).^ 2 + X(2).^ 2) ^ (-0.1e1 / 0.2e1)) * sin(atan2(X(2), X(1)));",
@"u_y_main     = (-sqrt(X(1).^ 2 + X(2).^ 2) / 0.3e1 + 0.4e1 / 0.3e1 * (X(1).^ 2 + X(2).^ 2) ^ (-0.1e1 / 0.2e1)) * cos(atan2(X(2), X(1)));",
@"",   
@"u(1,k)=u_x_main;",
@"u(2,k)=u_y_main;",
@"end" };<jupyter_output><empty_output><jupyter_text>We can evaluate this code in **BoSSS** using the MATLAB connector;
We encapsulate it in a **ScalarFunction** which allows 
**vectorized** evaluation 
(multiple evaluatiuons in one function call) e
of some function.

This is much more efficient, since there will be significant overhead
for calling MATLAB (starting MATLAB, checking the license, 
transfering data, etc.).<jupyter_code>using ilPSP.Connectors.Matlab;
ScalarFunction VelocityXInitial = 
delegate(MultidimensionalArray input, MultidimensionalArray output) {
    int N          = input.GetLength(0); // number of points which we evaluate 
    //                                      at once.
    var output_vec = MultidimensionalArray.Create(2, N); // the MATLAB code
    //                        returns an entire vector.
    using(var bmc = new BatchmodeConnector()) {
       bmc.PutMatrix(input,"X_values");
 
       foreach(var line in MatlabCode) {
           bmc.Cmd(line);   
       }
 
       bmc.GetMatrix(output_vec, "u");
 
       bmc.Execute(); // Note: 'Execute' has to be *after* 'GetMatrix'
   }
   output.Set(output_vec.ExtractSubArrayShallow(0,-1)); // extract row 0 from 
   //                       'output_vec' and store it in 'output'
};<jupyter_output><empty_output><jupyter_text>We test our implementation:<jupyter_code>var inputTest = MultidimensionalArray.Create(3,2); // set some test values for input
inputTest.SetColumn(0, GenericBlas.Linspace(1,2,3));
inputTest.SetColumn(1, GenericBlas.Linspace(2,3,3));
 
var outputTest = MultidimensionalArray.Create(3); // allocate memory for output
VelocityXInitial(inputTest, outputTest);<jupyter_output><empty_output><jupyter_text>We recive the following velocity values for our input coordinates:<jupyter_code>outputTest.To1DArray()<jupyter_output><empty_output><jupyter_text>Projecting the MATLAB function to a DG field

As for a standard calculation, we create a mesh, save it to some database
and set the mesh in the control object.<jupyter_code>var nodes        = GenericBlas.Linspace(1,2,11);
GridCommons grid = Grid2D.Cartesian2DGrid(nodes,nodes);
var db = CreateTempDatabase();
db.SaveGrid(ref grid);
C.SetGrid(grid);<jupyter_output><empty_output><jupyter_text>We create a DG field for the $x$-velocity on our grid:<jupyter_code>var gdata = new GridData(grid);
var b = new Basis(gdata, 3); // use DG degree 2
var VelX = new SinglePhaseField(b,"VelocityX"); // important: name the DG field
//                                 equal to initial value name<jupyter_output><empty_output><jupyter_text>Finally, we are able to project the MATLAB function onto the DG field:<jupyter_code>//VelX.ProjectField(VelocityXInitial);<jupyter_output><empty_output><jupyter_text>One might want to check the data visually, so it can be exported
in the usual fashion<jupyter_code>//Tecplot("initial",0.0,2,VelX);<jupyter_output><empty_output><jupyter_text>Storing the initial value in the database and linking it in the control object
 The DG field with the initial value can be stored in the database.
this will create a dummy session.<jupyter_code>BoSSSshell.WorkflowMgm.Init("TestProject");
var InitalValueTS = db.SaveTimestep(VelX); // further fields an be 
//                                                  appended
BoSSSshell.WorkflowMgm.Sessions
/// Now, we can use this timestep as a restart-value for the simulation:
C.SetRestart(InitalValueTS);<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1211708645336964, 'fraction_numerical': 0.01484002722940776, 'mean_word_length': 3.926894701542589, 'pattern_counts': {'":': 0, '<': 57, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 7, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '14', 'dir': 'jupyter-structured-clean-dedup', 'id': '10138', 'license': 'Apache-2.0', 'n_tokens_mistral': 2522, 'n_tokens_neox': 2478, 'n_words': 680, 'path': 'doc/handbook/InitialValues/InitialValues.ipynb', 'repo_name': 'FDYdarmstadt/BoSSS', 'size': '7345'}