Пример #1
0
        public PressureOutletRCR(BoundaryCondition BC, GetBetaFunction getElsticBeta, double _R1, double _R2, double _C)
            : base(BC.core_node, BC.current_time)
        {
            // Windkessel params, R2 is parallel to C //
            R1 = _R1;
            R2 = _R2;
            C  = _C;
            ////////////////////////////////////////////

            //tx_ij - i - time moment, j - space point, 1 - current moment (core node), 0 -previous moment (previus point)/
            U_tx_10 = 0;
            U_tx_01 = 0;
            P_tx_10 = GlobalDefs.DIASTOLIC_PRESSURE;
            P_tx_01 = GlobalDefs.DIASTOLIC_PRESSURE;
            P_tx_11 = GlobalDefs.DIASTOLIC_PRESSURE;
            A_tx_01 = core_node.lumen_sq_0;
            A_tx_10 = core_node.lumen_sq_0;
            Q_t_1   = 0;
            Q_t_0   = 0;
            ///////////////////////////////////////////

            beta_1        = GlobalDefs.getBoileauBeta(core_node.radius, core_node.elasticity) / core_node.lumen_sq_0;
            chrt_function = delegate(double A_tx_11)
            {
                double chrt_frw_right = Q_t_1 / A_tx_11 + 4 * Math.Pow(A_tx_11, 0.25f) * Math.Sqrt(beta_1 / 2.0f / GlobalDefs.BLOOD_DENSITY);
                return(chrt_frw_left - chrt_frw_right);
            };

            DefineSign();
        }
Пример #2
0
        public InletFlux(BoundaryCondition BC, TableFunction _flux, GetBetaFunction getElasticBeta)
            : base(BC.core_node, BC.current_time)
        {
            this.previous_velocity = 0;

            base_flux_on_time = _flux;
            flux_on_time      = _flux;


            // Artery lumen of terminal and previous nodes are set the same
            core_node.lumen_sq_0 = neighbour_node.lumen_sq_0;
            core_node.lumen_sq   = core_node.lumen_sq_0;


            double R0 = Math.Sqrt(core_node.lumen_sq_0 / Math.PI);


            beta_1        = getElasticBeta(R0, core_node.elasticity) / core_node.lumen_sq_0;
            flux_function = delegate(double A)
            {
                return(A * chrt_back + 4 * Math.Pow(A, 1.25f) * Math.Sqrt(beta_1 / 2.0 / GlobalDefs.BLOOD_DENSITY) - flux_on_time(current_time));
            };

            this.chrt_back = -4 * Math.Pow(core_node.lumen_sq_0, 0.25f) * Math.Sqrt(beta_1 / 2.0f / GlobalDefs.BLOOD_DENSITY);
        }
Пример #3
0
        public InletPressure(BoundaryCondition BC, TableFunction _pressure, GetBetaFunction getElasticBeta)
            : base(BC.core_node, BC.current_time)
        {
            pressure_on_time = _pressure;

            double R0 = Math.Sqrt(core_node.lumen_sq_0 / Math.PI);

            beta_1 = getElasticBeta(R0, core_node.elasticity) / core_node.lumen_sq_0;


            core_node.lumen_sq_0 = neighbour_node.lumen_sq_0;
            core_node.lumen_sq   = neighbour_node.lumen_sq_0;

            chrt = 4 * Math.Pow(core_node.lumen_sq_0, 0.25f) * Math.Sqrt(beta_1 / 2.0f / GlobalDefs.BLOOD_DENSITY);
        }
Пример #4
0
        public WaveTransmissive(BoundaryCondition BC, GetBetaFunction getElsticBeta)
            : base(BC.core_node, BC.current_time)
        {
            //tx_ij - i - time moment, j - space point, 1 - current moment (core node), 0 -previous moment (previus point)/
            Q_tx_10 = 0;
            Q_tx_01 = 0;
            P_tx_10 = GlobalDefs.DIASTOLIC_PRESSURE;
            P_tx_01 = GlobalDefs.DIASTOLIC_PRESSURE;
            P_tx_11 = GlobalDefs.DIASTOLIC_PRESSURE;
            Q_t_1   = 0;
            Q_t_1   = 0;
            ///////////////////////////////////////////

            beta_1 = GlobalDefs.getBoileauBeta(core_node.radius, core_node.elasticity) / core_node.lumen_sq_0;

            chrt_function = delegate(double A_tx_11)
            {
                double chrt_frw_right = Q_t_1 / A_tx_11 + 4 * Math.Pow(A_tx_11, 0.25f) * Math.Sqrt(beta_1 / 2.0f / GlobalDefs.BLOOD_DENSITY);
                return(chrt_frw_left - chrt_frw_right);
            };


            DefineSign();
        }
Пример #5
0
        public ViscoElasticKnot(Knot _knot, GetBetaFunction getElasticBeta)
            : base(_knot.core_node, _knot.current_time)
        {
            int L = nodes.GetLength(0);

            lumen_sq_old             = new double[L];
            chrt_func                = new MDFunction[L];
            energy_conservation_func = new MDFunction[L - 1];
            funcs = new MDFunction[2 * L];

            wall_thickhess = new double[L];
            lumen_sq_0     = new double[L];

            beta_1        = new double[L];
            chrt_b        = new double[L];
            chrt_f        = new double[L];
            c_dst         = new double[L];
            dep_matrix    = new bool[2 * L, 2 * L];
            prev_velocity = new double[L];
#if FAST
            nl_system = new NewtonSolver(2 * L);
#endif

            for (int i = 0; i < L; i++)
            {
                for (int j = 0; j < L; j++)
                {
                    dep_matrix[i, j] = false;
                }
            }

            for (int i = 0; i < L; i++)
            {
                double R0 = Math.Sqrt(nodes[i].lumen_sq_0 / Math.PI);
                beta_1[i]         = getElasticBeta(R0, nodes[i].elasticity) / nodes[i].lumen_sq_0;
                wall_thickhess[i] = GlobalDefs.getBoileauWallThickness(R0, nodes[i].elasticity);
                lumen_sq_0[i]     = nodes[i].lumen_sq_0;
                prev_velocity[i]  = nodes[i].velocity;
                chrt_b[i]         = 0;
                chrt_f[i]         = 0;
                c_dst[i]          = Math.Pow(nodes[i].lumen_sq_0, 0.25f) * Math.Sqrt(beta_1[i] / 2.0f / GlobalDefs.BLOOD_DENSITY);
                lumen_sq_old[i]   = lumen_sq_0[i];
            }

            for (int i = 0; i < L; i++)
            {
                pressure[i] = GlobalDefs.DIASTOLIC_PRESSURE;
            }



            int count = 0;
            unsafe
            {
                for (int i = 0; i < L; i++)
                {
                    int I = i;
#if FAST
                    MDFunction_del f1_del = delegate(double *args)
                    {
                        double v = args[0 + I * 2];
                        double l = args[1 + I * 2];

                        if (v > 0)
                        {
                            return(Math.Abs(v) + 4 * (Math.Sqrt(Math.Sqrt(l)) * Math.Sqrt(beta_1[I] / 2.0f / GlobalDefs.BLOOD_DENSITY) - c_dst[I]) - chrt_f[I]);
                        }
                        else
                        {
                            return(Math.Abs(v) - 4 * (Math.Sqrt(Math.Sqrt(l)) * Math.Sqrt(beta_1[I] / 2.0f / GlobalDefs.BLOOD_DENSITY) - c_dst[I]) - chrt_b[I]);
                        }
                    };
                    baseMDFunction f1 = new delegateMDFunc(f1_del);
                    nl_system.addFunc(f1);
                    nl_system.setDetMatrixEl(count, 2 * I, true);
                    nl_system.setDetMatrixEl(count, 2 * I + 1, true);
#endif
                    chrt_func[i] = delegate(double[] args) //v1,l1; v2,l2 ...
                    {
                        double v = args[0 + I * 2];
                        double l = args[1 + I * 2];

                        if (v > 0)
                        {
                            return(Math.Abs(v) + 4 * (Math.Pow(l, 0.25f) * Math.Sqrt(beta_1[I] / 2.0f / GlobalDefs.BLOOD_DENSITY) - c_dst[I]) - chrt_f[I]);
                        }
                        else
                        {
                            return(Math.Abs(v) - 4 * (Math.Pow(l, 0.25f) * Math.Sqrt(beta_1[I] / 2.0f / GlobalDefs.BLOOD_DENSITY) - c_dst[I]) - chrt_b[I]);
                        }
                    };


                    funcs[count]                 = chrt_func[i];
                    dep_matrix[count, 2 * I]     = true;
                    dep_matrix[count, 2 * I + 1] = true;

                    count++;
                }
            }

            unsafe
            {
#if FAST
                MDFunction_del f1_del = delegate(double *args)
                {
                    double summ_flux = 0;
                    for (int i = 0; i < L; i++)
                    {
                        summ_flux += args[0 + i * 2] * args[1 + i * 2];
                    }

                    return(summ_flux);
                };
                baseMDFunction f1 = new delegateMDFunc(f1_del);
                nl_system.addFunc(f1);

                for (int i = 0; i < 2 * L; i++)
                {
                    nl_system.setDetMatrixEl(count, i, true);
                }
#endif

                mass_conservation_func = delegate(double[] args)
                {
                    double summ_flux = 0;
                    for (int i = 0; i < L; i++)
                    {
                        double v = args[0 + i * 2];
                        double l = args[1 + i * 2];

                        summ_flux += v * l;
                    }
                    return(summ_flux);
                };


                funcs[count] = mass_conservation_func;
                for (int i = 0; i < 2 * L; i++)
                {
                    dep_matrix[count, i] = true;
                }
            };

            count++;

            unsafe
            {
                for (int i = 1; i < L; i++)
                {
                    int I = i;
#if FAST
                    MDFunction_del f1_del = delegate(double *args)
                    {
                        double v0 = args[0];
                        double p0 = calcPressureV(0, args[1]);

                        double v = args[0 + I * 2];
                        double p = calcPressureV(I, args[1 + 2 * I]);

                        return(GlobalDefs.BLOOD_DENSITY * (v0 * v0 - v * v) / 2 + p0 - p);
                    };
                    baseMDFunction f1 = new delegateMDFunc(f1_del);
                    nl_system.addFunc(f1);
                    nl_system.setDetMatrixEl(count, 0, true);
                    nl_system.setDetMatrixEl(count, 1, true);
                    nl_system.setDetMatrixEl(count, 2 * I, true);
                    nl_system.setDetMatrixEl(count, 2 * I + 1, true);
#endif

                    energy_conservation_func[i - 1] = delegate(double[] args)
                    {
                        double v0 = args[0];
                        double p0 = calcPressureV(0, args[1]);

                        double v = args[0 + I * 2];
                        double p = calcPressureV(I, args[1 + 2 * I]);

                        return(GlobalDefs.BLOOD_DENSITY * (v0 * v0 - v * v) / 2 + p0 - p);
                    };


                    funcs[count] = energy_conservation_func[I - 1];

                    dep_matrix[count, 0]         = true;
                    dep_matrix[count, 1]         = true;
                    dep_matrix[count, 2 * I]     = true;
                    dep_matrix[count, 2 * I + 1] = true;

                    count++;
                }

#if FAST
                us_init_X   = (double *)Marshal.AllocHGlobal(2 * L * sizeof(double));
                us_solution = (double *)Marshal.AllocHGlobal(2 * L * sizeof(double));
                for (int i = 0; i < 2 * L; i += 2)
                {
                    us_init_X[i]     = nodes[i / 2].velocity * v_sign[i / 2];
                    us_init_X[i + 1] = nodes[i / 2].lumen_sq;
                    nl_system.setDxVectorEl(i, 1e-12f);
                    nl_system.setDxVectorEl(i + 1, 1e-12f);
                }
#endif
            }

            dX = new double[2 * L];
            for (int i = 0; i < 2 * L; i += 2)
            {
                dX[i]     = 1e-12f;
                dX[i + 1] = 1e-12f;
            }
        }
Пример #6
0
        public ElasticThread(Thread _protothread, GetBetaFunction getElsticBeta)
            : base(_protothread.nodes.ToList())
        {
            int L = nodes.GetLength(0);

            beta_1         = new double[L];
            lumen_sq_0     = new double[L];
            wall_thickhess = new double[L];
            viscosity      = new double[L];
            g_energy       = new double[L];


            for (int i = 0; i < L; i++)
            {
                double R0 = Math.Sqrt(nodes[i].lumen_sq_0 / Math.PI);
                beta = getElsticBeta(R0, nodes[i].elasticity);

                beta_1[i]         = beta / nodes[i].lumen_sq_0;
                wall_thickhess[i] = GlobalDefs.getBoileauWallThickness(R0, nodes[i].elasticity);
                lumen_sq_0[i]     = nodes[i].lumen_sq_0;
                lumen_sq[i]       = nodes[i].lumen_sq_0;
                pressure[i]       = GlobalDefs.DIASTOLIC_PRESSURE;
                //g_energy[i] = Vector1.Dot(nodes[i].position - GlobalDefs.ZERO_POINT, GlobalDefs.DOWN) * GlobalDefs.GRAVITY;
                g_energy[i]  = 0;
                viscosity[i] = GlobalDefs.BLOOD_VISC;
            }
#if FAST
            unsafe
            {
                double *dZ = (double *)Marshal.AllocHGlobal((L - 1) * sizeof(double));
                for (int i = 0; i < L - 1; i++)
                {
                    dZ[i] = Vector3.Distance(nodes[i + 1].position, nodes[i].position);
                }


                thread_solver = new McCormackThread(L, dZ, GlobalDefs.BLOOD_DENSITY, GlobalDefs.BLOOD_VISC, GlobalDefs.FRICTION_C);

                for (int i = 0; i < L; i++)
                {
                    int I = i;

                    _1DFunction_del pressure_func_del = delegate(double x)
                    {
                        return(calcPressure(x, I));
                    };

                    delegate1DFunc f = new delegate1DFunc(pressure_func_del);

                    thread_solver.addFunc(f, i);
                }

                fixed(double *g_ptr = &g_energy[0])
                {
                    //thread_solver.setGravity(g_ptr);
                }
            }
#endif

            clotes     = new List <Clot>();
            ffr_clotes = new List <FFRClot>();
        }