|
svZeroDSolver
|
Below are details on the steps required to implement a new block in svZeroDSolver. To help with defining the block matrices, you can use the Jacobian Generator.
Note: The best way to implement a new block is to look at examples of existing block classes. See the ValveTanh class for an example.
BlockType in src/model/BlockType.hblock_factory_map in src/model/Model.cppblock_factory_map, the dictionary key should match the string specifying the type of block in the .json configuration/input file, and the dictionary value should match the class constructor name for the block.BlockClass in src/model/BlockType.h
Block. Define a constructor of the form: MyNewBlock is the name of the new classblock_type and block_class are the same as what was added in Step 1 above.Param_1, ... , Param_N.InputParameter, which specifies whether it is optional, an array, a scalar, a function, and its default value.Param_1, ... , Param_N must be the same as the parameter names within the block definition in the .json configuration/input file.
setup_dofs(DOFHandler &dofhandler) function.num_equations is the number of governing equations for the new block.internal_var_names is a list of strings that specify names for variables that are internal to the block, i.e. all variables for the block apart from the flow and pressure at the block's inlets and outlets.
TripletsContributions num_triplets{*, *, *} object.F, E and dC_dy matrices respectively.
update_constant function and may also contain update_time and update_solution functions. These functions implement the governing equations for the block. Details are in Steps 3-4 below.
enum ParamId object that relates the parameter indices to their names.ParamId object should match the order in the constructor.
Use the Jacobian Generator to calculate matrix contributions symbolically.
y = [P_in, Q_in, P_out, Q_out, InternalVariable_1, ..., InternalVariable_N]. InternalVariable* refers to any variable in the governing equations that are not the inlet and outlet flow and pressure. These are the same as those discussed above in the function setup_dofs.ydot = dP_in/dt, dQ_in/dt, ...].
E(t)*ydot + F(t)*y + C(y,ydot,t) = 0.y is the local state vector mentioned above.ydot is the time-derivative of the local state vector.E and F are matrices of size number_of_equations*size_of_state_vector.C is a vector of length number_of_equations.E and F contain terms of the governing equation that multiply the respective components of ydot and y respectively.C contains all non-linear and constant terms in the equation.C with respect to y and ydot. These will be stored in the block's dC_dy and dC_dydot matrices, both of which are size number_of_equations*size_of_state_vector.
Assume a block has the following non-linear governing equations:







![$[P_{in}, Q_{in}, P_{out}, Q_{out}, I_{1}]$](form_160.png)
F matrix are F[0,0] = b, F[1,2] = g and F[1,4] = h.E matrix are E[0,1] = a and E[1,2] = e.C vector are C[0] = c*(dP_in/dt)*Q_in + d and C[1] = f*Q_out*Q_out.dC_dy matrix are dC_dy[0,1] = c*(dP_in/dt) and dC_dy[1,3] = 2*f*Q_out.dC_dydot matrix are dC_dydot[0,0] = c*Q_in.F, 2 contributions to E, and 2 constributions to dC_dy. So the class will have a member TripletsContributions num_triplets{3, 2, 2}.
update_constant, update_time and update_solution functions (which can be output by the Jacobian Generator).update_constant.update_time.update_solution.update_time and update_solution functions.
E, F, dC_dy and dC_dydot are populated using the following syntax: current_block_equation_id goes from 0 to number_of_equations-1 (for the current block) and current_block_variable_ids goes from 0 to size_of_state_vector-1 for the current block.
update_solution as:
C with respect to each state variable y and ydot must also be provided. These go into dC_dy and dC_dydot matrices.dC_dy matrix contribution can be specified using the following syntax: a is the derivative of the non-linear term in the equation with ID current_block_equation_id with respect to the local state variable with ID current_block_variable_id.current_block_equation_id = 0.P_in, set current_block_variable_id = 0, and for the derivative of this term with respect to P_out, set current_block_variable_id = 2.ydot state variables, i.e. for the derivative of the term with respect to dP_in/dt, set current_block_variable_id = 0.
MyNewBlock.h and MyNewBlock.cpp to src/model/CMakeLists.txt