Beispiel #1
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;
            }
        }
Beispiel #2
0
 public delegateMDFunc(MDFunction_del _md_func_del)
 {
     md_func_del = _md_func_del;
 }