Mentions légales du service

Skip to content
Snippets Groups Projects
Commit d3d262e0 authored by ALI Olivier's avatar ALI Olivier :monkey_face:
Browse files

Worked on labels on meshes and on curved cellularized structures.

parent 44ab40eb
No related branches found
No related tags found
No related merge requests found
from copy import deepcopy
import numpy as np
from numpy import linalg as lng
#import matplotlib as mpl
#from matplotlib import pyplot as plt
from cellcomplex.property_topomesh.analysis import compute_topomesh_property
from cellcomplex.property_topomesh.example_topomesh import circle_voronoi_topomesh
from cellcomplex.property_topomesh.io import save_ply_property_topomesh, read_ply_property_topomesh
#from cellcomplex.property_topomesh.utils.matplotlib_tools import mpl_draw_topomesh
from cellcomplex.property_topomesh.io import save_ply_property_topomesh
from bvpy.templates.domains import FaceCellularDomain
from bvpy.utils.visu import plot
from bvpy.utils.io import save
# ##############################################################################
# ##############################################################################
......@@ -36,21 +36,6 @@ def cell_normal(points, cell):
return np.array(nrl).mean(axis=0)
def plot_points(points, vids):
fig = plt.figure()
axe = fig.add_subplot(111, projection='3d')
points = np.array(points)
for vid in vids:
axe.scatter(points[vid, 0],
points[vid, 1],
points[vid, 2],
marker='o',
label=f'{vid}')
plt.legend()
plt.show()
def approx(x, n):
'''Approximates a float to a given order.
......@@ -103,10 +88,10 @@ def read_tissue_text_file(path):
# ##############################################################################
# ##############################################################################
# -- Creating a "tissue-like" property topomesh.
cvmsh = circle_voronoi_topomesh(size = 5,
voxelsize = 1.,
circle_size = 100.,
z_coef = 0)
cvmsh = circle_voronoi_topomesh(size=5,
voxelsize=1.,
circle_size=100.,
z_coef=0)
prop_2_compute = {1: ['borders'],
2: ['oriented_vertices', 'oriented_borders', 'borders'],
......@@ -116,20 +101,30 @@ for deg, names in prop_2_compute.items():
for name in names:
compute_topomesh_property(cvmsh, name, degree=deg)
path = '/Users/oali/Documents/Work/Research/Devlp/bvpy/data/test_flat.ply'
save_ply_property_topomesh(cvmsh, path)
# -- Defining the epithelial cells on the structure
epithelium = {cid: 0 for cid in cvmsh.wisps(2)}
for cid, eids in cvmsh.wisp_property('borders', 2).items():
for eid in eids:
if cvmsh.nb_regions(1, eid) == 1:
epithelium[cid] = 1
break
# -- Getting the vertex positions
points = []
cells = []
labels = []
lbl_2_idx = {}
for idx, (vid, pos) in enumerate(cvmsh.wisp_property('barycenter', 0).items()):
points.append(list(pos))
lbl_2_idx[vid] = idx
# -- Forming the cells with their vertex index (in the list of position vectors)
# -- Writing cells with their vertex index (in the list of position vectors)
for cid, eids in cvmsh.wisp_property('borders', 2).items():
oriented_vids = []
......@@ -152,12 +147,13 @@ for cid, eids in cvmsh.wisp_property('borders', 2).items():
assert(oriented_vids[0] == oriented_vids[-1])
oriented_vids.pop()
cells.append(list(map(lambda x: lbl_2_idx[x], oriented_vids)))
labels.append(epithelium[cid])
# -- Harmonizing the orientation of all cells.
oriented_cells = []
for cell in cells:
if cells.index(cell) == 0:
if cells.index(cell) == 0:
oriented_cells.append(cell)
else:
vids_2_switch = [[idx0, idx1]
......@@ -171,7 +167,8 @@ for cell in cells:
reversed = True
break
if not reversed: oriented_cells.append(cell)
if not reversed:
oriented_cells.append(cell)
cells = oriented_cells
......@@ -179,7 +176,8 @@ cells = oriented_cells
# -- Recording these list in a text file
save_path = '/Users/oali/Documents/Work/Research/Devlp/bvpy/data/tissue_example_flat.txt'
def save_points_and_cells(points, cells):
def save_points_and_cells(points, cells, label=None):
with open(save_path, 'w') as file:
for name, lst in zip(['points', 'cells'], [points, cells]):
......@@ -187,18 +185,20 @@ def save_points_and_cells(points, cells):
for line in lst:
file.write(' '.join([str(elmt) for elmt in line])+'\n')
save_points_and_cells(points, cells)
# ##############################################################################
# ##############################################################################
# -- Instancing the FaceCellularDomain class from the previously computed lists.
from bvpy.templates.domains import FaceCellularDomain
if label is not None:
assert len(label) == len(cells)
file.write(f'{len(label)} cell labels:\n')
for line in label:
file.write(f'{line} \n')
tissue = FaceCellularDomain(points, cells, resolution=.05)
save_points_and_cells(points, cells, labels)
from bvpy.utils.visu import plot
# ##############################################################################
# ##############################################################################
# -- Instancing the FaceCellularDomain class from the lists computed above.
tissue = FaceCellularDomain(points, cells, markers=labels, resolution=.05)
save(tissue, save_path[:-4])
plot(tissue.mesh)
This diff is collapsed.
This diff is collapsed.
220 points:
-2.923961461587178 3.2441482921464946 0.7801906650442335
-2.7456094236265725 -2.466930913813634 0.5622494154255632
-2.091260831771032 -2.6691748529984674 0.477701004255513
-1.9579421531705388 -2.9358177631610896 0.5147433450959479
0.2315931355235309 -2.580002521593032 0.28807894412092694
-0.13632602829219237 -3.5087844064051703 0.5050890744460552
0.7173186125032134 -3.7808861164812573 0.608968001780544
-2.8838191130713775 -1.7752972685010284 0.47520947935894364
-2.6532326649384834 -0.4215171411818072 0.31088453329855875
-2.9627114780816695 -1.7190176426105828 0.4848662020119616
2.731227573538176 -1.8105909716230562 0.44387422628228357
0.7500043080288806 -4.2657412763709175 0.7695288468104114
-0.14082659092836616 -4.48117478335171 0.8156563717900751
-0.3203203397451169 -3.5824425564961655 0.5313886737203897
-1.0403201567910731 -3.191746720750457 0.4718261953270593
-1.196796091387838 -3.2560394469549068 0.5021692598487022
-1.6834371260608716 -2.0309478933794285 0.29266390818872035
-2.157158548068202 -1.4616889149277672 0.28482721573168
-2.016854991444407 -0.869605767367873 0.2134566337769675
-2.9915733363985817 -3.393273874113334 0.8284966672635223
-2.431785945265422 -3.692754666649614 0.7961134127102893
-2.28714203280854 -3.8673459731436557 0.8187323975527314
2.2154458697642148 -1.4592094696531168 0.2963438625217305
0.3597252762014928 -0.08922401821826213 0.029997722720615367
0.830650833139455 -1.2112010199680363 0.11217018231276583
0.8577137185572346 -1.1409366778686378 0.10698853742079084
0.6000190701158943 -2.6422934859793115 0.3112852472903743
1.9443817902712484 -2.7001894279245757 0.46074231069880495
1.536169729835625 -3.2594550854275974 0.5370427074510234
1.0550056094397202 -3.300867712371561 0.49879729182060356
1.5287550198151496 -2.0497065512539865 0.27888224527613925
1.2744340821588838 -1.985991714968799 0.2410136042623432
-3.1655907239683763 3.1655907239683754 0.8137910959216875
-4.4921427842957415 -0.14117127424399922 0.8191417045564249
-3.692829883072662 2.5096445969987378 0.8100904902735202
-3.715390981949324 2.297331233136662 0.7798408245181178
-4.0526783024599755 1.7537505060721321 0.7945470655827411
-1.3755901395749452 2.0329354612866304 0.2567503485435586
-0.7787474294966907 2.277912282058063 0.24678816015077845
-1.6140723989196653 3.1996327701186087 0.5312723291532827
-0.9246951818506421 3.229961307217646 0.4692259182932207
-0.8097470320337649 3.32326454669327 0.48552838360618794
0.8191836643398086 3.4876590172896216 0.5289894382745433
0.12305595225803471 3.2538740952271126 0.44498751235160044
-0.14268925203795246 3.425392172143995 0.4901519280724105
-0.10938339397883559 4.376156771800932 0.7831299214409145
1.3850930956698748 3.208715478415743 0.5092999525678112
2.319840370694236 0.9766207324342953 0.2707029957266941
-2.5454511912044495 3.7455176864580566 0.8300556088735369
-1.7698894472844506 4.089973195119663 0.8073002083099295
-1.9351701540386914 3.9152237382052273 0.7800418711850335
-3.528723525853691 -2.737158539163459 0.8102324804248957
-3.7339557993989794 -2.5375937408729463 0.8255406044069522
2.8870377196019987 -3.2656688341294147 0.7779576605765336
2.761815365452808 -2.132430518139853 0.5004959669992078
2.42091535567397 -2.6741459723887986 0.5377465230250812
3.976835184331636 -1.6972335612012976 0.7673449409701453
3.3462781168214186 -1.3206844203557633 0.5318522732567675
0.9713163444710654 -4.345419530973405 0.8064429722591954
0.684310798608313 -4.320568341221707 0.7825931870355707
2.5275423370673784 -3.7191656078378186 0.8197913556265645
2.0031518303650513 -3.9087261045476094 0.7878415943052144
2.2769198714672574 -3.8500612422730067 0.8123433193919768
-0.41363875003221395 -4.3758409017943505 0.788784079711322
-0.4202648563807767 -4.371282339925716 0.7875063458300178
-0.699582350738323 -4.416989126614023 0.8120528280747472
-1.274616357699903 -1.9819761227045132 0.2373600797348514
-0.04311004051043313 -2.3378587614874347 0.2399816796645089
-0.7886528214962382 -2.552863025844461 0.30170972723525075
-0.016342523747426674 -1.5619430052198642 0.11964953714979
-2.0523999706928 -4.028061743980153 0.8275277537682705
-1.7804306468710116 -4.114332470112569 0.8155984951141207
-0.980539128770731 -4.386679896099403 0.819214505665362
-1.4560257319293468 -4.117836488974934 0.7803302175470518
-1.484597287699294 -4.123627601617147 0.7851001608641529
-1.243323996270323 -4.2795492652770495 0.8072391700979004
-2.77145396716415 -3.5729369252179293 0.8278968262346935
-2.5031656314934794 -3.683296374838931 0.8064463526690181
-1.5237766365387229 -0.7248729311259621 0.13473404410625184
-0.24498576841177402 -0.30128471647566274 0.02275562338699426
-0.8495153372307137 -1.1806020532880177 0.10911471303189035
-0.6108936357493207 -1.146845535606831 0.0928251219101218
-3.58640024598637 2.781897189234916 0.8334408610358602
-3.407714097912152 3.0043041061775035 0.8347597079170833
-4.171807834383529 -1.2281124493847906 0.7747510599498625
-4.437940409027941 -0.7029007078775348 0.8186807895890421
-3.5701982182333936 -0.18914497038891745 0.5225933628074508
-4.426875990463657 -0.3122248071135595 0.8007572467470984
-4.451000406946939 -0.42074341504679597 0.8116706439139827
-3.1844252274621376 -0.6278403313238871 0.4441420051504986
-3.2988236619459865 -0.8973641662301223 0.4869878143227572
-3.949687163460418 2.0124661273245423 0.7996936376937697
-3.784790425120287 2.2383188178086386 0.7889235913705748
-4.07838314525876 1.5650089441492652 0.7796285343014336
-3.5959887067661906 0.48210334032730995 0.5396793768565458
-2.934364244611868 2.0428099081842563 0.5265567585491269
-2.683905563276701 2.956578912545964 0.6505904038828728
-1.9031421144687735 2.8044476223311627 0.4768187454551748
-1.8291565024801038 2.253291295830676 0.35556367258702387
-0.8925420888707429 0.21554197321030727 0.048803616492286615
-1.3684909047307514 -0.01747712308657467 0.09015444390189943
-0.7142051428369964 0.9506631644369824 0.0784617944727868
-1.3004434804538847 1.221962247732215 0.14295469222897433
-0.1379980033535733 4.391167667301262 0.7881922469084587
-1.5262981883270323 4.239456309015172 0.822715768633202
-0.9762727533628694 4.367593229711749 0.8131615528856124
-1.0616795839465991 4.3113880884841596 0.8015264784486681
-1.2532148278726345 4.313593730954234 0.8183347349387566
0.8132610185539921 4.331161960977899 0.7913946249120157
2.6764565326791536 3.4661509678014735 0.783996833533345
1.4134880440643005 3.1592898704201273 0.5000571299919098
2.418514540829085 2.3066847634173935 0.4653265467777987
2.212521067455357 2.94047014784846 0.5576251096608719
1.584816125517805 0.07502154842408987 0.11866956635760992
1.745321494352267 -0.6787642720091159 0.1615781575637076
2.127727110965321 -0.8624825390634896 0.23278280567132376
2.316518076251662 0.5155284433295765 0.24171900096622423
0.390062427995053 -0.030871682283632795 0.030361198145306283
1.300053940131643 0.23820482343697005 0.08665794332925177
-2.9072077112961363 3.2975798565038543 0.7891114186181116
-2.754665337585643 3.551293154382994 0.8192033609646947
-2.2886061645430633 3.8698216847026345 0.8196715244788592
-1.997094746559562 3.9195191300869396 0.7899625958904629
3.1931264056613107 3.1931264056613133 0.8258996825316721
3.3646603104137975 2.966347086647303 0.8163594377446103
2.6550239804385316 2.188519618380753 0.4913377967533264
3.860195652507995 2.282913344972634 0.8160780635999095
3.73012197722529 2.534988278014194 0.824039636887341
3.4285627983639206 2.8034729223468178 0.7980296334571819
3.5332001219920075 2.7406309430671953 0.8119602397562783
4.551694725686819 0.14304276939755378 0.8384862039441741
4.322571394476201 0.9662091808790917 0.7993756615313021
-3.242242793227479 -2.888122814261169 0.7729809733232469
-3.2676644070117087 -2.880833694824958 0.7773101023930052
-3.1528842457687047 -3.1528842457687087 0.8081342089606802
-3.8722509337743665 -2.290042818439223 0.8205079585276821
-3.9440057763183467 -2.0095713159872313 0.7978527257769195
-3.9351286541907564 -2.018492885266642 0.7965983514897559
-4.087612318315574 -1.7688678046617357 0.8062510190515049
-4.164368915545405 -1.4992650632596984 0.7977226994622845
3.565598345261624 -2.7657615810518443 0.8249281675467727
3.977412273106016 -1.721179986722143 0.7703206212133967
3.923510350165916 -1.9991283747643307 0.79076582681433
3.806957597512539 -2.2514284470166066 0.796617837334177
3.6752180611196517 -2.414622648004611 0.7885242350521215
3.667036001201054 -2.492115092980311 0.8004227565727504
1.5496110695507574 -4.304210327686697 0.8451887968502911
1.269571719200521 -4.369894520188944 0.8373369330639637
0.14165576387974654 -4.50755949447946 0.8239743475062279
0.4209004623014769 -4.452661793363217 0.812264392099574
2.8848751993995028 -3.2722485941075243 0.7789852428697712
2.732910253993309 -3.523246669613925 0.80799701756957
1.7961962579973505 -4.1507646478456675 0.8283841419657436
1.9973000160873735 -3.9199219942186847 0.7903455754959323
-4.516728024508566 0.14194389654366704 0.8269336027056876
-4.4584475780054635 0.42144737997537796 0.8141177296387904
-4.347334830219784 -0.9717444645753035 0.8066509576998424
-4.184742440039853 -1.2157800673374284 0.7776313365223052
-4.2496220755331 1.2346293439031917 0.7973733078359801
-4.13638186658373 1.489189105633716 0.788631964276392
-4.32176247963127 0.6844999315519772 0.7829993131855107
-4.280607684561837 0.7325379478079735 0.7726217809349615
-4.2966330309186915 0.9604112697009719 0.7905383542082776
-3.1312148337193335 1.2257639162327407 0.4656061506094458
-2.6806453077347823 1.6970750273587278 0.42702052375306726
-2.561691557564141 1.6868742395924117 0.4002265640001581
-3.2018059184221506 0.7309873299907772 0.4453006053320993
-2.4957634766795116 0.25828354037544216 0.2698224763481523
-2.0621197787962244 0.5426182126886797 0.20129978360861664
-1.970280405129694 0.9090331744156999 0.20668412586373183
-0.7057075280634522 4.455661974228183 0.8244300936903268
-0.4219002472430099 4.463238413275679 0.8155833675142643
1.2724656764803863 4.379855586482166 0.8406844069587333
0.9787721653731011 4.3787749562697815 0.8170112360613679
0.13990766782357622 4.451934176035423 0.8064431070013175
2.9635548620996945 3.3614931533554127 0.8150388004020811
2.6875484019349276 3.4647665223208786 0.7857197614732199
1.8173928984398968 4.072691566468359 0.8080606662825845
-0.33024786004017603 2.1080398541033043 0.20101729912059432
0.18729695688866504 2.4902749234918224 0.26785155759380835
-0.20743145200083685 1.1689434585744032 0.08398250386421842
0.09573632605869463 1.0491511972379368 0.07034059270405395
3.27796609742927 -0.9053375386008702 0.47643666128475937
2.7806915335694704 -0.5141493557377789 0.33862387319078247
2.8698287078185083 0.031925688808344066 0.3475546893171724
3.4835765551065245 0.3522430810728789 0.5081451241949908
4.114962038583597 -0.33484457470516 0.7026441105916569
3.0542353063757006 1.4945227022693266 0.4870830995587415
3.053202309549797 1.4872276870614 0.4859568670406754
3.57781754748919 0.7412674429781807 0.5516625996391786
4.307426035073525 0.9799270331975094 0.7955162518563801
4.33162504628007 1.2584534092369926 0.8244168668222529
4.274037823096053 1.5387482994837438 0.834615395705007
3.917587216642919 2.000423819682863 0.7898532286622818
4.491522181359862 0.7113872268999238 0.8364028776017004
4.570023826593949 0.4319944407655692 0.8504299234392733
3.16241123094975 -3.1624112309497465 0.812294060490622
3.3948192682206964 -2.99293578457616 0.829145361858704
4.4393254201256225 -0.139511421705878 0.8031066242282601
4.26826384484386 -0.3695550377731951 0.7565424297641234
4.380616682570783 -0.9791838399756251 0.8172701444275112
0.6960318369407998 4.39457206474704 0.8049726397213982
0.4217325352902404 4.461464206138218 0.8148902794674251
2.526846455494433 3.71814164919813 0.819645666805871
1.544977369898884 4.29133973177467 0.8406932623770689
1.7819674535299637 4.117883820763792 0.8170360007251379
1.2076882458622742 1.078569778975467 0.11975481791072157
0.6957756949192173 1.2934462631468255 0.10389575489738177
1.7450791362547156 1.3500422444960398 0.20984759362898792
1.7619728651013238 1.927921107886479 0.2868131532463147
1.1281234880864095 2.334959223542988 0.2862600116285005
0.8295222367211841 2.2208216735498034 0.24227947295431287
4.134520611354514 1.789166835701551 0.8226141330895783
3.9214691903980214 1.998088351916107 0.7906886002073145
4.371383400826033 -0.692359113383798 0.7978879775079433
4.28755044251587 -0.40529284440279373 0.7629809955064738
4.169272152473522 -1.5010303371756941 0.7995177312270454
4.312252304013306 -1.2528251073199486 0.8178466760507257
2.05752228387434 4.038114849642734 0.8312700019394869
2.3157620208058587 3.9157397299567984 0.8368090356403438
61 cells:
37 98 165 169 102
54 144 143 142 141 56 57 10
125 128 124 123 175 176 109 112 111
5 6 29 26 4
160 161 94 86 87 33 154 155
95 96 0 32 83 82 34 35
47 187 189 185 184 116
3 20 21 70 71 74 73 15
131 194 195 130 198 199 186 185 189 190
113 114 25 23 117 118
5 13 64 63 12 148 149 59 11 6
207 211 179 178 180 181
2 1 132 134 19 76 77 20 3
9 137 136 138 139 84 90
39 40 41 106 107 104 49 50
209 210 211 207 206 208
26 31 24 69 67 4
85 88 87 86 89 90 84 157 156
27 30 31 26 29 28
38 40 39 97 98 37
4 67 68 14 13 5
182 183 184 185 186
17 18 78 80 66 16
55 53 196 197 140 145 144 54
97 96 95 164 165 98
116 184 183 115 114 113
116 113 118 206 208 47
188 193 213 212 192 191 190 189 187
125 128 129 127 126 193 188
110 112 109 203 219 218 177 46
78 100 99 79 81 80
94 166 167 8 89 86
65 64 13 14 15 73 75 72
57 182 186 199 215 214 200 217 216 56
46 177 205 204 172 173 108 42
187 188 125 111 209 208 47
7 1 132 133 51 52 135 137 9
2 16 66 68 14 15 3
178 179 43 44 41 40 38
45 103 171 170 105 106 41 44
167 168 100 78 18 8
108 201 202 174 45 44 43 42
7 9 90 89 8 18 17
69 81 79 23 25 24
79 23 117 181 180 101 99
111 112 110 210 209
163 166 94 161 162 158 159 93
164 163 166 167 168 169 165
7 17 16 2 1
24 31 30 22 115 114 25
100 168 169 102 101 99
101 180 178 38 37 102
55 54 10 22 30 27
28 61 62 60 151 150 53 55 27
92 91 36 93 163 164 95 35
0 96 97 39 50 122 121 48 120 119
117 181 207 206 118
42 43 179 211 210 110 46
57 182 183 115 22 10
67 68 66 80 81 69
29 6 11 58 147 146 152 153 61 28
61 cell labels:
0
1
1
0
1
1
0
1
1
0
1
0
1
1
1
0
0
1
0
0
0
0
0
1
0
0
0
1
1
1
0
0
1
1
1
0
1
0
0
1
0
1
0
0
0
0
1
0
0
0
0
0
0
1
1
1
0
0
0
0
1
This diff is collapsed.
......@@ -167,6 +167,7 @@ def normal(domain, scale=1, interior=None, degree=1, name='normal'):
return u
def get_boundary_facets(mesh):
"""Selects the boundary elements of a given mesh.
......@@ -223,13 +224,20 @@ def get_boundary_vertex(mesh):
return bnd_vertex
def boundary_normal(mesh):
def boundary_normal(domain, scale=1, degree=1, name='normal'):
"""Computes the normal vector field on the boundary of a mesh.
Parameters
----------
mesh : :class:`Mesh<dolfin.cpp.mesh.Mesh>`
The mesh on which the boundary normals should be computed.
domain : subclass of :class:`Domain<bvpy.domains.AbstracDomain>`
The meshed surface on which we want to compute the normal field.
scale : float, optional
The amplitude we want to set to this field (the default is 1).
degree : int, optional
The interpolation degree to use to compute the vector space
on the border (the default is 1).
name : str, optional
the label we want to attach to the normal field.
Returns
-------
......@@ -237,6 +245,11 @@ def boundary_normal(mesh):
a list of 3D vector defined on the outermost vertices of a mesh.
"""
if domain.mesh is not None:
mesh = domain.mesh
else:
print('WARNING - (geometry.py - l.84): no mesh on the domain.')
mesh.init()
bnd_facets = get_boundary_facets(mesh)
facets_index = [f.index() for f in bnd_facets]
......@@ -248,13 +261,15 @@ def boundary_normal(mesh):
for f in fe.facets(vtx)
if f.index() in facets_index])
norm = np.sum(norm, axis=0)
norm = norm / np.linalg.norm(norm)
norm = scale * norm / np.linalg.norm(norm)
normals[vtx.index()] = norm
V = fe.VectorFunctionSpace(mesh, 'P', 1, dim=3)
V = fe.VectorFunctionSpace(mesh, 'P', degree, dim=3)
u = fe.Function(V)
d2v = fe.dof_to_vertex_map(V)
u.vector().set_local(normals.flatten()[d2v])
u.rename(name, 'label')
return u
# geometry.py ends here
......@@ -105,7 +105,7 @@ def create_expression(source, functionspace=None, degree=None, **kwargs):
class FenicsFunctionConverter(object):
"""Enables conversion of Fenics objects (???) into other formats.
"""Enables conversion of fenics Functions into other formats.
Parameters
----------
......
import fenics as fe
from bvpy import BVP
def save(bvp, filename):
def save(data, filename):
"""Save a fenics mesh or function as pvd or xml.
Parameters
----------
bvp : BVP
the simulation to save.
data : BVP or Domain
the simulation or the domain to save.
filename : str
the path and the name of the recording file.
......@@ -21,7 +22,10 @@ def save(bvp, filename):
filename += '.xdmf'
with fe.XDMFFile(fe.MPI.comm_world, filename) as f:
f.write(bvp.solution)
if isinstance(data, BVP):
f.write(data.solution)
else:
f.write(data.mesh)
def read_tissue_text_file(path):
......@@ -41,15 +45,25 @@ def read_tissue_text_file(path):
'''
points = []
cells = []
labels = []
with open(path, 'r') as file:
content = file.readlines()
point_nbr = int(content[0][:-8])
cell_nbr = int(content[point_nbr+1][:-9])
for line in content[1: point_nbr+1]:
points.append([float(coord) for coord in line.split(' ')])
for line in content[point_nbr+2:]:
for line in content[point_nbr+2:point_nbr+cell_nbr+2]:
cells.append([int(pidx) for pidx in line.split(' ')])
return points, cells
if content[point_nbr+cell_nbr+2][-8:-2] == 'labels':
for line in content[point_nbr+cell_nbr+3:]:
labels.append(int(line))
if len(labels) == 0:
return points, cells
else:
return points, cells, labels
......@@ -64,10 +64,10 @@ class AbstractVform(ABC):
bterm = Zero()
for ind, t in enumerate(self._bterm):
if isinstance(t[1], int):
bterm += fe.dot(t[0],v)*self.ds(t[1])
bterm += fe.dot(t[0], v) * self.ds(t[1])
elif isinstance(t[1], str):
Boundary(t[1])._domain.mark(self.ds.subdomain_data(), ind+1)
bterm += fe.dot(t[0],v)*self.ds(ind+1)
bterm += fe.dot(t[0], v) * self.ds(ind+1)
return bterm
......
......@@ -19,7 +19,7 @@
"from bvpy.utils.io import read_tissue_text_file\n",
"\n",
"path = '../data/tissue_example_flat.txt'\n",
"points, cells = read_tissue_text_file(path)\n",
"points, cells, labels = read_tissue_text_file(path)\n",
"\n",
"# Definition of the domain of interest.\n",
"from bvpy.templates.domains import FaceCellularDomain\n",
......@@ -41,6 +41,14 @@
"plot(tissue.mesh)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Loading the structure with a normal force field\n",
"Let's load the flat tissue-inspired structure with a constant force field normal to its surface, similar to the one used in tutorial #4 about thin pressurized elastic shell."
]
},
{
"cell_type": "code",
"execution_count": null,
......@@ -62,52 +70,122 @@
{
"cell_type": "code",
"execution_count": null,
<<<<<<< HEAD
=======
"metadata": {},
"outputs": [],
"source": [
"type(drchlt)"
"# Define the source term as the force field applied everywhere on the domain\n",
"from bvpy.domains.geometry import normal\n",
"\n",
"pressure = 1\n",
"p_force = normal(tissue, scale=pressure, name='pressure_force_field', interior=[0, 0, -1])"
]
},
{
"cell_type": "code",
"execution_count": null,
>>>>>>> develop
"metadata": {},
"outputs": [],
"source": [
"# Define the source term as the force field applied everywhere on the domain\n",
"from bvpy.domains.geometry import normal\n",
"# Define the variational form\n",
"from bvpy.templates.vforms import LinearElasticForm\n",
"\n",
"pressure = 1\n",
"p_force = normal(tissue, scale=pressure, name='pressure_force_field', interior=[0, 0, -1])"
"young = 1000 * pressure\n",
"\n",
"elastic_equilibrium = LinearElasticForm(source=p_force, young=young)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Set the linear elastic\n",
"from bvpy import BVP\n",
"\n",
"pressurized_elastic_tissue_prblm = BVP(domain=tissue, vform=elastic_equilibrium, bc=drchlt)\n",
"\n",
"# Solve the problem\n",
"pressurized_elastic_tissue_prblm.solve()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Solution visualization\n",
"sol = pressurized_elastic_tissue_prblm.solution\n",
"\n",
"plot(sol)"
]
},
{
"cell_type": "code",
"execution_count": null,
<<<<<<< HEAD
=======
"metadata": {},
"outputs": [],
"source": [
"p_force.vector().get_local().reshape(-1,3)"
"# Save the solution to be used by a third party pipeline\n",
"from bvpy.utils.io import save\n",
"\n",
"path = '../data/tutorial_results/solution_tuto5_1.xdmf'\n",
"\n",
"save(pressurized_elastic_tissue_prblm, path)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Loading the structure with a tangent force field\n",
"Let's now consider a fully 2D problem where the 2D tissue-inspired structure is loaded on its border by a force field locally normal to its border and embedded within the same plane as the structure."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# -- Generate a new instance of the same tissue\n",
"tissue_2 = FaceCellularDomain(points, cells, resolution=.1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Define the source term as the force field applied everywhere on the domain\n",
"from bvpy.domains.geometry import boundary_normal\n",
"\n",
"boundary_deformation = boundary_normal(tissue_2,\n",
" scale=5e-2,\n",
" name='imposed deformation')\n",
"\n",
"\n",
"# Define the correspondning boundary conditions\n",
"from bvpy.boundary_conditions import dirichlet\n",
"\n",
"\n",
"drchlt = dirichlet(boundary_deformation, boundary='all')"
]
},
{
"cell_type": "code",
"execution_count": null,
>>>>>>> develop
"metadata": {},
"outputs": [],
"source": [
"# Define the variational form\n",
"from bvpy.templates.vforms import LinearElasticForm\n",
"\n",
"young = 1000 * pressure\n",
"young = 1000\n",
"\n",
"elastic_equilibrium = LinearElasticForm(source=p_force, young=young)"
"elastic_equilibrium = LinearElasticForm(young=young)"
]
},
{
......@@ -119,10 +197,10 @@
"# Set the linear elastic\n",
"from bvpy import BVP\n",
"\n",
"pressurized_elastic_tissue_prblm = BVP(domain=tissue, vform=elastic_equilibrium, bc=drchlt)\n",
"stretched_elastic_tissue_prblm = BVP(domain=tissue_2, vform=elastic_equilibrium, bc=drchlt)\n",
"\n",
"# Solve the problem\n",
"pressurized_elastic_tissue_prblm.solve()"
"stretched_elastic_tissue_prblm.solve()"
]
},
{
......@@ -132,9 +210,9 @@
"outputs": [],
"source": [
"# Solution visualization\n",
"sol = pressurized_elastic_tissue_prblm.solution\n",
"sol_2 = stretched_elastic_tissue_prblm.solution\n",
"\n",
"plot(sol)"
"plot(sol_2)"
]
},
{
......@@ -146,9 +224,128 @@
"# Save the solution to be used by a third party pipeline\n",
"from bvpy.utils.io import save\n",
"\n",
"path = 'solution.xdmf'\n",
"path = '../data/tutorial_results/solution_tuto5_2.xdmf'\n",
"\n",
"save(pressurized_elastic_tissue_prblm, path)"
"save(stretched_elastic_tissue_prblm, path)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Heterogeneous tissue\n",
"Let's now consider that our structure represents a multicellular tissue where cells do not feature the same mechanical properties. For instance the Young's modulus of the outermost cells will be assumed higher than the one of inner cells."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# -- Generate a new instance of the same tissue this time with markers associated to cells.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import fenics as fe\n",
"\n",
"tissue_3 = FaceCellularDomain(points, cells, markers=labels, resolution=.1)\n",
"\n",
"young_moduli = [3000 if tissue_3.cdata[cell.index()] == 1 else 1000 for cell in fe.cells(tissue_3.mesh)]\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for cell in fe.cells(tissue_3.mesh):\n",
" print(tissue_3.cdata[cell.index()])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import fenics as fe\n",
"\n",
"from bvpy.utils.interface import create_expression\n",
"from bvpy.domains.geometry import get_boundary_facets\n",
"\n",
"\n",
"# -- useful functions\n",
"def get_boundary_cells(mesh):\n",
" \"\"\"Finds the epidermal cells within a tissue.\n",
" \"\"\"\n",
" boundary_facets = get_boundary_facets(mesh)\n",
" \n",
" return [cell for cell in fe.cells(mesh) \n",
" if any([facet in boundary_facets\n",
" for facet in fe.facets(cell)])]\n",
"\n",
"\n",
"def young_hetero(pos, mesh):\n",
" \"\"\"Gives a specific value to epidermal cells\n",
" \"\"\"\n",
" for cell in fe.cells(pos):\n",
" if cell in boundary_cells(mesh):\n",
" return 3000\n",
" else:\n",
" return 1000\n",
"\n",
"\n",
"\n",
"fspace = fe.function.functionspace.FunctionSpace(tissue, 'P', 1)\n",
"\n",
"yng_modulus = create_expression(young_hetero, fspace, degree=1)\n",
"\n",
"elastic_equilibrium = LinearElasticForm(source=p_force, young=yng_modulus)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"mesh = tissue.mesh\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \n",
"get_boundary_cells(mesh) "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Define the variational form\n",
"from bvpy.templates.vforms import LinearElasticForm\n",
"\n",
"young = 1000 * pressure\n",
"\n",
"elastic_equilibrium = LinearElasticForm(source=p_force, young=young)"
]
}
],
......@@ -168,7 +365,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.7"
"version": "3.7.9"
},
"latex_envs": {
"LaTeX_envs_menu_present": true,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment