示例#1
0
        public void removeClot(int node_id)
        {
            VascularNode nd  = this.vascular_system.Find(x => x.id == node_id);
            Thread       thr = this.node2thread[nd];

            thr.removeClot(nd);
        }
        public BoundaryCondition(VascularNode _core_node, double start_time)
        {
            core_node = _core_node;
            //Only 1 neughbour is possible for terminal node
            neighbour_node = _core_node.neighbours[0];

            current_time  = start_time;
            previous_time = current_time - TIMEGAP;
            v_sign        = new int[2];
            DefineSign();
        }
示例#3
0
        public override void removeClot(VascularNode nd)
        {
            int clt_id = clotes.FindIndex(x => x.c_nd == nd);

            if (clt_id != -1)
            {
                Clot clt = clotes[clt_id];
                clt.tgr_degree = 0.0;
                clotes[clt_id] = clt;
            }
        }
示例#4
0
        public override bool setFFRClot(VascularNode nd, float FFR_degree)
        {
            int nd_id = 0;

            for (int i = 0; i < nodes.GetLength(0); i++)
            {
                if (nodes[i] == nd)
                {
                    nd_id = i; break;
                }
            }

            if (clotes.FindIndex(x => x.c_nd == nd) == -1)
            {
                FFRClot clt = new FFRClot(current_time, GlobalDefs.FRICTION_C);

                clt.nd = new List <VascularNode>();
                int L = 2;
                if (nd_id - L - 1 >= 0)
                {
                    clt.proximal_nd = nodes[nd_id - L - 1];
                }
                else
                {
                    return(false);
                }

                if (nd_id + L + 1 < nodes.GetLength(0))
                {
                    clt.distal_nd = nodes[nd_id + L + 1];
                }
                else
                {
                    return(false);
                }

                for (int i = -L; i < L + 1; i++)
                {
                    if (nd_id + i >= 0 && nd_id + i < nodes.GetLength(0))
                    {
                        clt.nd.Add(nodes[nd_id + i]);
                    }
                }

                clt.thread_id = nd_id;
                clt.init();
                ffr_clotes.Add(clt);
                return(true);
            }

            return(false);
        }
示例#5
0
        public bool setCloth(int node_id, float degree)
        {
            VascularNode nd = this.vascular_system.Find(x => x.id == node_id);

            try {
                Thread thr = this.node2thread[nd];

                foreach (var child in nd.neighbours)
                {
                    var th = this.node2thread[child];
                }

                return(thr.setClot(nd, degree));
                // return (thr.setFFRClot(nd, degree));
            } catch (Exception) {
                return(false);
            }
        }
示例#6
0
        public bool update_clot(double curr_time, double heart_period)
        {
            double dt = curr_time - last_time;

            last_time = curr_time;

            p_pressure_acc += proximal_nd.pressure * dt;
            d_pressure_acc += distal_nd.pressure * dt;
            av_flux_acc    += proximal_nd.velocity * proximal_nd.lumen_sq * dt;

            if (curr_time % heart_period <= dt)
            {
                proximal_pressure = p_pressure_acc / heart_period;
                p_pressure_acc    = 0;
                distal_pressure   = d_pressure_acc / heart_period;
                d_pressure_acc    = 0;

                av_flux     = Math.Abs(av_flux_acc);
                av_flux_acc = 0;

                if (proximal_pressure < distal_pressure)
                {
                    VascularNode tmp   = proximal_nd;
                    double       tmp_p = proximal_pressure;
                    proximal_nd       = distal_nd;
                    distal_nd         = tmp;
                    proximal_pressure = distal_pressure;
                    distal_pressure   = tmp_p;
                }

                curr_ffr       = distal_pressure / proximal_pressure;
                effective_visc = effective_visc * (1 + 4 * (curr_ffr - tg_ffr));

                //(1 - tg_ffr) / length / alpha / Math.PI * proximal_pressure / av_flux;


                return(true);
            }

            return(false);
        }
示例#7
0
        public Knot(VascularNode _core_node, double start_time)
        {
            core_node = _core_node;
            nodes     = (VascularNode[])core_node.neighbours.ToArray().Clone();

            int L = nodes.GetLength(0);

            velocity = new double[L];
            pressure = new double[L];
            lumen_sq = new double[L];

            for (int i = 0; i < core_node.neighbours.Count; i++)
            {
                lumen_sq[i] = core_node.neighbours[i].lumen_sq_0;
            }

            DefineSigns();

            current_time  = start_time;
            previous_time = current_time - 1e-3;
        }
示例#8
0
        public override bool setClot(VascularNode nd, float degree)
        {
            int nd_id = 0;

            for (int i = 0; i < nodes.GetLength(0); i++)
            {
                if (nodes[i] == nd)
                {
                    nd_id = i; break;
                }
            }

            if (clotes.FindIndex(x => x.c_nd == nd) == -1)
            {
                Clot clt = new Clot();
                clt.c_nd = nd;

                clt.normal_lumen = new List <double>();
                clt.nd           = new List <VascularNode>();

                int L = 2;

                for (int i = -L; i < L + 1; i++)
                {
                    if (nd_id + i >= 0 && nd_id + i < nodes.GetLength(0))
                    {
                        clt.nd.Add(nodes[nd_id + i]);
                        clt.normal_lumen.Add(lumen_sq_0[nd_id + i]);
                    }
                }

                clt.tgr_degree  = degree;
                clt.curr_degree = 0;
                clt.thread_id   = nd_id;
                clotes.Add(clt);
                return(true);
            }

            return(false);
        }
示例#9
0
 public virtual void removeClot(VascularNode nd)
 {
 }
示例#10
0
 public virtual bool setFFRClot(VascularNode nd, float FFR_degree)
 {
     return(false);
 }
示例#11
0
        public void defineNodeDirVectors(int[] initial_set, out getFloatValueDelegate getProximaDst, out setFloatValueDelegate setProximaDst)
        {
            float curr_value = 0;
            List <VascularNode> curr_front;

            curr_front = new List <VascularNode>();
            List <VascularNode> tmp_curr_front = new List <VascularNode>();

            foreach (var id in initial_set)
            {
                curr_front.Add(vascular_system[0]);
            }

            getFloatValueDelegate get_del;
            setFloatValueDelegate set_del;

            VascularNode.newFloatValueLayer(out get_del, out set_del);
            foreach (var n in curr_front)
            {
                set_del(n, curr_value);
            }

            while (true)
            {
                foreach (var n in curr_front)
                {
                    foreach (var ng in n.neighbours)
                    {
                        if (get_del(ng) > curr_value)
                        {
                            set_del(ng, curr_value);
                            tmp_curr_front.Add(ng);
                        }
                    }
                }
                if (curr_front.Count == 0)
                {
                    break;
                }

                curr_front = new List <VascularNode>(tmp_curr_front);
                tmp_curr_front.Clear();
                curr_value += 1.0f;
            }

            foreach (var n in vascular_system)
            {
                if (n.neighbours.Count < 3)
                {
                    //Console.WriteLine(n.id);
                    //if (n.id == 1717)
                    //{
                    //    Console.WriteLine("1");
                    //}
                    //Console.WriteLine(get_del(n.neighbours.First()));
                    //Console.WriteLine(get_del(n));
                    if (n.neighbours.Last().position < n.neighbours.First().position)
                    {
                        n.neighbours.Reverse();
                    }
                    n.defDirVector();
                }
            }

            getProximaDst = get_del;
            setProximaDst = set_del;
        }
示例#12
0
        static public bool LoadTopologyFromString(string text, out VascularNet r_vnet)
        {
            ILoadVascularNet vnet = new VascularNet();

            System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.CreateSpecificCulture("en-US");

            string[] readText = text.Split(new[] { '\r', '\n' });

            Regex regex = new Regex(@"^name:\s*(\w+)$", RegexOptions.IgnoreCase);
            int   i     = 0;

            while (!regex.IsMatch(readText[i]))
            {
                i++;
                if (i >= readText.Length)
                {
                    throw new TopReadingException("No correct name of vascular system in found\n");
                }
            }

            Match name_match = regex.Match(readText[i]);

            vnet.name = name_match.Groups[1].Value;



            Regex regex_1 = new Regex(@"^Coordinates:\s*$", RegexOptions.IgnoreCase);
            Regex regex_2 = new Regex(@"^Bonds:\s*$", RegexOptions.IgnoreCase);

            List <List <int> > bonds_index = new List <List <int> >();
            int node_count        = 0;
            int bond_string_count = 0;

            while (true)
            {
                i++;

                if (regex_1.IsMatch(readText[i]))
                {
                    while (true)
                    {
                        i++;
                        if (i >= readText.Length)
                        {
                            break;
                        }


                        //regex = new Regex(@"^\s*(\d+)\s+X:(-*\d+.\d+)\s+Y:(-*\d+.\d+)\s+Z:(-*\d+.\d+)\s+R:(-*\d+.\d+)\s+C:(\d+.\d+)$", RegexOptions.IgnoreCase);
                        regex = new Regex(@"^\s*(\d+)\s+L:(-*\d+.\d+)\s+R:(-*\d+.\d+)\s+E:(-*\d+.\d+)\s+T:(-*\d+)$", RegexOptions.IgnoreCase);
                        Match node_match = regex.Match(readText[i]);

                        if (node_match.Groups.Count < 4)
                        {
                            //regex = new Regex(@"^\s*(\d+)\s+X:(-*\d+.\d+)\s+Y:(-*\d+.\d+)\s+Z:(-*\d+.\d+)\s+R:(-*\d+.\d+)$", RegexOptions.IgnoreCase);
                            regex      = new Regex(@"^\s*(\d+)\s+L:(-*\d+.\d+)\s+R:(-*\d+.\d+)$", RegexOptions.IgnoreCase);
                            node_match = regex.Match(readText[i]);
                            if (node_match.Groups.Count < 4)
                            {
                                break;
                            }
                        }


                        int id = int.Parse(node_match.Groups[1].Value);
                        //convert to meter from millimeter
                        Vector1 position   = new Vector1(double.Parse(node_match.Groups[2].Value) * 1e-3);
                        double  rad        = double.Parse(node_match.Groups[3].Value);
                        double  elasticity = double.Parse(node_match.Groups[4].Value) * 1e6;
                        int     nodetype   = int.Parse(node_match.Groups[5].Value);

                        vnet.vascular_system.Add(new VascularNode(id, position, rad * 1e-3, elasticity, nodetype));
                        node_count++;
                    }
                }
                else
                if (regex_2.IsMatch(readText[i]))
                {
                    while (true)
                    {
                        i++;
                        if (i >= readText.Length)
                        {
                            break;
                        }

                        regex = new Regex(@"(\d+)\s*", RegexOptions.IgnoreCase);
                        MatchCollection node_match = regex.Matches(readText[i]);
                        if (node_match.Count < 2)
                        {
                            break;
                        }


                        int id = int.Parse(node_match[0].Value);
                        bonds_index.Add(new List <int>());
                        bonds_index[bonds_index.Count - 1].Add(id);

                        for (int n = 1; n < node_match.Count; n++)
                        {
                            bonds_index[bonds_index.Count - 1].Add(int.Parse(node_match[n].Value));
                        }

                        bond_string_count++;
                    }
                }

                if (i >= readText.Length - 1)
                {
                    foreach (var str in bonds_index)
                    {
                        VascularNode nd = vnet.vascular_system.Find(x => x.id == str[0]);
                        for (int s = 1; s < str.Count; s++)
                        {
                            nd.addNeighbours(new VascularNode[] { vnet.vascular_system.Find(x => x.id == str[s]) });
                        }
                    }

                    break;
                }
            }
            r_vnet = (VascularNet)vnet;
            return(false);
        }
示例#13
0
        public void defineNet(getFloatValueDelegate getProximalDistance, setFloatValueDelegate setProximalDistance, List <ClotNode> ClotNodes)
        {
            int count_id = vascular_system.Count;

            foreach (var n in vascular_system)
            {
                n.defDirVector();
            }


            // this we should get from import
            List <VascularNode> knot_nodes = getSubsystem(x => x.nodetype == 1);
            List <VascularNode> term_nodes = getSubsystem(x => x.nodetype == 2);

            for (int i = 0; i < ClotNodes.Count; i++)
            {
                ClotNodes[i].Node = vascular_system.Find(x => x.id == ClotNodes[i].Node_id);
            }
            foreach (var node in ClotNodes)
            {
                node.Node.nodetype = 3;
            }
            foreach (var node in vascular_system)
            {
                if (node.nodetype == 3)
                {
                    foreach (var nnode in node.neighbours)
                    {
                        if (nnode.nodetype <= 1)
                        {
                            node.nodetype = 4;
                            term_nodes.Add(node);
                        }
                    }
                }
            }

            // remove connections between clot boundary and the clot (terminal definition)
            foreach (var node in vascular_system)
            {
                if (node.nodetype >= 3)
                {
                    List <VascularNode> dellist = new List <VascularNode>();
                    foreach (var nnode in node.neighbours)
                    {
                        if (nnode.nodetype == 4)
                        {
                            //term_nodes.Add(node);
                            dellist.Add(nnode);
                        }
                    }
                    foreach (var nnode in dellist)
                    {
                        node.excludeNeighbour(nnode);
                        nnode.excludeNeighbour(node);
                    }
                }
            }


            //List<int> list = new List<int>();
            //foreach (var node in ClotNodes)
            //{
            //    list.Add(node.Clot_id);
            //}
            //list = list.Distinct().ToList();

            ////List<ClotNode> clotboundary = new List<ClotNode>();
            //foreach (int clotid in list)
            //{
            //    List<ClotNode> listnodes = new List<ClotNode>();
            //    foreach (var node in ClotNodes)
            //    {
            //        if (node.Clot_id == clotid)
            //            listnodes.Add(node);
            //    }

            //    List<VascularNode> Node1 = getSubsystem(x => x.id == listnodes[0].Node_id);
            //    List<VascularNode> Node2 = getSubsystem(x => x.id == listnodes[listnodes.Count - 1].Node_id);

            //    //clotboundary.Add(listnodes[0]);
            //    //clotboundary.Add(listnodes[listnodes.Count - 1]);
            //}



            knots  = new List <Knot>();
            bounds = new List <BoundaryCondition>();

            foreach (var tn in term_nodes)
            {
                bounds.Add(new BoundaryCondition(tn, 0));   // Just abstract BC, which do nothing
            }

            foreach (var kn in knot_nodes)
            {
                knots.Add(new Knot(kn, 0)); // Just abstract knot, which do nothing and don't pass the solution through itself
            }

            //foreach (var kn in knot_nodes)
            //{
            //    List<VascularNode> b_nodes = new List<VascularNode>();
            //    List<VascularNode> n_nodes = new List<VascularNode>(kn.neighbours);

            //    // change this part to switch roles for temp nodes

            //    foreach (var n in n_nodes)
            //    {
            //        Vector1 pos = kn.position - (kn.position - n.position) * 0.001;
            //        double r = Math.Sqrt(n.lumen_sq_0 / Math.PI);
            //        VascularNode b_n = new VascularNode(count_id, pos, r);
            //        b_n.neighbours.Add(kn);
            //        b_n.neighbours.Add(n);
            //        setProximalDistance(b_n, (getProximalDistance(kn) + getProximalDistance(n)) / 2);
            //        kn.neighbours.Remove(n);// do we need to remove neighbours?
            //        n.neighbours.Remove(kn);
            //        kn.addNeighbour(b_n);
            //        n.addNeighbour(b_n);
            //        b_nodes.Add(b_n);
            //        count_id++;
            //    }
            //    knots.Add(new Knot(kn, 0)); // Just abstract knot, which do nothing and don't pass the solution through itself
            //}

            List <string> writeText = new List <string>();

            threads     = new List <Thread>            ();
            node2thread = new Dictionary <VascularNode, Thread>();

            getBoolValueDelegate isProcessed;
            setBoolValueDelegate setProcessed;

            VascularNode.newBoolValueLayer(out isProcessed, out setProcessed);

            VascularNode curr_node;

            //VascularNode next_node;

            foreach (var kn in knots)
            {
                setProcessed(kn.core_node, true);
            }

            // Define threads starting from bounds
            foreach (var bc in bounds)
            {
                curr_node = bc.core_node;
                List <VascularNode> protothread = new List <VascularNode>();

                while (true)
                {
                    protothread.Add(curr_node);
                    setProcessed(curr_node, true);
                    try
                    {
                        curr_node = curr_node.neighbours.First(x => (!isProcessed(x)));
                    }
                    catch
                    {
                        break;
                    }
                }
                if (protothread.Count > 1)
                {
                    //if(getProximalDistance(protothread.First()) > getProximalDistance(protothread.Last()))
                    if (protothread[1].position > protothread.Last().position)
                    {
                        protothread.Reverse();
                    }
                    threads.Add(new Thread(protothread));
                    foreach (var n in protothread)
                    {
                        node2thread.Add(n, threads.Last());
                    }
                }
            }

            // Define threads starting from knots
            foreach (var kn in knots)
            {
                foreach (var start in kn.nodes)
                {
                    curr_node = start;
                    List <VascularNode> protothread = new List <VascularNode>();
                    while (true)
                    {
                        protothread.Add(curr_node);
                        setProcessed(curr_node, true);
                        try
                        {
                            curr_node = curr_node.neighbours.First(x => (!isProcessed(x)));
                        }
                        catch
                        {
                            break;
                        }
                    }
                    if (protothread.Count > 1)
                    {
                        //if(getProximalDistance(protothread.First()) > getProximalDistance(protothread.Last()))
                        if (protothread[1].position > protothread.Last().position)
                        {
                            protothread.Reverse();
                        }
                        threads.Add(new Thread(protothread));
                        foreach (var n in protothread)
                        {
                            node2thread.Add(n, threads.Last());
                        }
                    }
                }
            }

            VascularNode.terminateBoolValueLayer(ref isProcessed);
        }
示例#14
0
 public bool excludeNeighbour(VascularNode neighbour)
 {
     return(neighbours.Remove(neighbour));
 }
示例#15
0
 public void addNeighbour(VascularNode neighbour)
 {
     neighbours.Remove(neighbour);
     neighbours.Add(neighbour);
 }
示例#16
0
 static public int NumOfNeigbours(VascularNode node)
 {
     return(node.neighbours.Count);
 }
示例#17
0
        public void setOutletBC(int start_point_id, List <BodyPartInlet> parts, float Q_total, float C_total, float R_total)
        {
            Dictionary <int, List <VascularNode> > outlet_groups = new Dictionary <int, List <VascularNode> >();

            List <VascularNode> reference_points = new List <VascularNode>();

            foreach (var p in parts)
            {
                reference_points.AddRange(p.inlet);
            }

            List <VascularNode> front_0 = new List <VascularNode>();
            List <VascularNode> front_1 = new List <VascularNode>();

            getFloatValueDelegate get_dist;
            setFloatValueDelegate set_dist;

            getFloatValueDelegate get_group;
            setFloatValueDelegate set_group;

            VascularNode.newFloatValueLayer(out get_dist, out set_dist);
            VascularNode.newFloatValueLayer(out get_group, out set_group);

            VascularNode start_point = v_net.vascular_system.Find(x => x.id == start_point_id);

            front_0.Add(start_point);
            set_dist(start_point, 0);

            /*  Q_total = 0;
             * for (int i = 0; i < parts.Count; i++)
             *        Q_total += (float)parts[i].inlet_flux.Sum();*/

            while (true)
            {
                foreach (var n in front_0)
                {
                    if (reference_points.Contains(n) && (!outlet_groups.ContainsKey(n.id)))
                    {
                        outlet_groups.Add(n.id, new List <VascularNode>());
                        set_group(n, n.id);
                    }

                    foreach (var nn in n.neighbours)
                    {
                        if (get_dist(nn) > get_dist(n))
                        {
                            set_dist(nn, get_dist(n) + 1);
                            if (!front_1.Contains(nn))
                            {
                                front_1.Add(nn);
                                set_group(nn, get_group(n));
                                if (outlet_groups.ContainsKey((int)get_group(n)))
                                {
                                    outlet_groups[(int)get_group(n)].Add(nn);
                                }
                            }
                        }
                    }
                }

                front_1 = front_1.Distinct().ToList();
                front_0 = new List <VascularNode>(front_1);
                front_1.Clear();

                if (front_0.Count == 0)
                {
                    break;
                }
            }

            foreach (var part in parts)
            {
                foreach (var root in part.inlet)
                {
                    if (outlet_groups.ContainsKey(root.id))
                    {
                        foreach (var n in outlet_groups[root.id])
                        {
                            if (n.neighbours.Count == 1)
                            {
                                part.outlet.Add(v_net.bounds.Find(x => x.core_node == n));
                            }
                        }
                    }
                }
            }

            for (int i = 0; i < parts.Count; i++)
            {
                double outlet_cube_summ = 0;
                double inlet_cube_summ  = 0;
                foreach (var on in parts[i].outlet)
                {
                    outlet_cube_summ += Math.Pow(on.core_node.radius, 3);
                }

                foreach (var inp_n in parts[i].inlet)
                {
                    inlet_cube_summ += Math.Pow(inp_n.radius, 3);
                }

                Console.WriteLine(parts[i].name + "    inlet/outlet: " + inlet_cube_summ / outlet_cube_summ);
            }

            for (int i = 0; i < parts.Count; i++)
            {
                double a_cube_outlet  = 0;
                double tot_inlet_flux = 0;

                for (int j = 0; j < parts[i].outlet.Count; j++)
                {
                    a_cube_outlet += Math.Pow(parts[i].outlet[j].core_node.radius, 3);
                }


                for (int j = 0; j < parts[i].inlet_flux.Count; j++)
                {
                    tot_inlet_flux += parts[i].inlet_flux[j];
                }

                double R_part = (Q_total / tot_inlet_flux) * R_total;

                foreach (PressureOutletRCR bc in parts[i].outlet)
                {
                    double Rt = a_cube_outlet / Math.Pow(bc.core_node.radius, 3) * R_part;
                    // inv_tot_R += 1.0 / Rt;
                    double R2 = Rt - bc.R1;
                    if (R2 < 0)
                    {
                        R2    = 0.1;
                        bc.R1 = Rt - R2;
                    }

                    bc.R2 = R2;
                    bc.C  = C_total * R_total / Rt;
                }
            }
        }