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(); }
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; } }
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); }
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); } }
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); }
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; }
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); }
public virtual void removeClot(VascularNode nd) { }
public virtual bool setFFRClot(VascularNode nd, float FFR_degree) { return(false); }
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; }
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); }
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); }
public bool excludeNeighbour(VascularNode neighbour) { return(neighbours.Remove(neighbour)); }
public void addNeighbour(VascularNode neighbour) { neighbours.Remove(neighbour); neighbours.Add(neighbour); }
static public int NumOfNeigbours(VascularNode node) { return(node.neighbours.Count); }
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; } } }