openCARP
Doxygen code documentation for the open cardiac electrophysiology simulator openCARP
SF_mesh_io_emi.h
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // openCARP is an open cardiac electrophysiology simulator.
3 //
4 // Copyright (C) 2020 openCARP project
5 //
6 // This program is licensed under the openCARP Academic Public License (APL)
7 // v1.0: You can use and redistribute it and/or modify it in non-commercial
8 // academic environments under the terms of APL as published by the openCARP
9 // project v1.0, or (at your option) any later version. Commercial use requires
10 // a commercial license (info@opencarp.org).
11 //
12 // This program is distributed without any warranty; see the openCARP APL for
13 // more details.
14 //
15 // You should have received a copy of the openCARP APL along with this program
16 // and can find it online: http://www.opencarp.org/license
17 // ----------------------------------------------------------------------------
18 
26 #if WITH_EMI_MODEL
27 
28 #ifndef _SF_MESH_IO_EMI
29 #define _SF_MESH_IO_EMI
30 
31 #include "SF_mesh_io.h"
32 #include "petsc_utils.h"
33 
34 namespace SF {
35 
46 template<class T, class S>
47 inline void insert_points_ptsData_to_dof( const meshdata<T, S> & mesh_original, meshdata<T, S> & mesh,
48  const SF_nbr numbering,
50  hashmap::unordered_map<T,T> & vertex2ptsdata,
51  hashmap::unordered_map<T,T> & dof2ptsData)
52 {
53  MPI_Comm comm = mesh_original.comm;
54 
55  const SF::vector<mesh_int_t> & rnod_original = mesh_original.get_numbering(numbering);
57  for(size_t i=0; i<rnod_original.size(); i++){
58  g2l_orig[rnod_original[i]] = i;
59  }
60 
61  const SF::vector<mesh_int_t> & rnod = mesh.get_numbering(numbering);
64  for(size_t i=0; i<rnod.size(); i++){
65  g2l[rnod[i]] = i;
66  l2g[i] = rnod[i];
67  }
68 
69  mesh_int_t gmax = global_max(rnod, comm);
70  mesh.g_numpts = gmax+1;
71 
72  SF::vector<mesh_real_t> Buffxyz_orig = mesh_original.xyz;
73 
74  mesh.xyz.resize(mesh.l_numpts*3);
75 
77 
78  for(size_t eidx = 0; eidx < mesh.l_numelem; eidx++) {
79  T tag = mesh.tag[eidx];
80 
81  for (int n = mesh.dsp[eidx]; n < mesh.dsp[eidx+1];n++)
82  {
83  T g = l2g[mesh.con[n]];
84  T old_g = dof2vertex[g];
85 
86  const auto local_idx = g2l[g];
87  const auto orig_idx = g2l_orig[old_g];
88 
89  tmesh.xyz[local_idx*3+0] = Buffxyz_orig[orig_idx*3+0];
90  tmesh.xyz[local_idx*3+1] = Buffxyz_orig[orig_idx*3+1];
91  tmesh.xyz[local_idx*3+2] = Buffxyz_orig[orig_idx*3+2];
92  dof2ptsData[g] = vertex2ptsdata[old_g];
93 
94  if (!std::isfinite(tmesh.xyz[local_idx*3+0]) ||
95  !std::isfinite(tmesh.xyz[local_idx*3+1]) ||
96  !std::isfinite(tmesh.xyz[local_idx*3+2]))
97  {
98  printf("NaN detected in coordinates of the EMI mesh after decoupling interfaces on EMI mesh while recording pts data on the EMI mesh, on Tag=%d\n",tag);
99  EXIT(EXIT_FAILURE);
100  }
101  }
102  }
103 
104  mesh = tmesh;
105 }
106 
117 template<class T, class S>
118 inline void insert_points_to_surface_mesh( const meshdata<T, S> & mesh_original, meshdata<T, S> & surfmesh,
119  const SF_nbr numbering,
121  hashmap::unordered_set<int> & extra_tags,
122  SF::vector<mesh_int_t> & elemTag_surface)
123 {
124  MPI_Comm comm = mesh_original.comm;
125 
126  const SF::vector<mesh_int_t> & rnod_original = mesh_original.get_numbering(numbering);
128  for(size_t i=0; i<rnod_original.size(); i++){
129  g2l_orig[rnod_original[i]] = i;
130  }
131 
132  const SF::vector<mesh_int_t> & rnod_surf = surfmesh.get_numbering(numbering);
133 
136  for(size_t i=0; i<rnod_surf.size(); i++){
137  g2l_surf[rnod_surf[i]] = i;
138  l2g_surf[i] = rnod_surf[i];
139  }
140 
141  mesh_int_t gmax = global_max(rnod_surf, comm);
142  surfmesh.g_numpts = gmax+1;
143 
144  SF::vector<mesh_real_t> Buffxyz = mesh_original.xyz;
145 
146  surfmesh.xyz.resize(surfmesh.l_numpts*3);
147 
148  elemTag_surface.resize(surfmesh.l_numelem);
149  for(size_t eidx = 0; eidx < surfmesh.l_numelem; eidx++) {
150  T tag = surfmesh.tag[eidx];
151  elemTag_surface[eidx] = 1; // assigned 1 for for extracellular located on extracellular side
152  if(extra_tags.find(tag) == extra_tags.end())
153  elemTag_surface[eidx] = 2; // assigned 2 for for intracellular located on myocyte
154 
155  for (int n = surfmesh.dsp[eidx]; n < surfmesh.dsp[eidx+1];n++)
156  {
157  T g = l2g_surf[surfmesh.con[n]];
158  T old_g = dof2vertex[g];
159 
160  const auto local_idx = g2l_surf[g];
161  const auto orig_idx = g2l_orig[old_g];
162 
163  surfmesh.xyz[local_idx*3+0] = Buffxyz[orig_idx*3+0];
164  surfmesh.xyz[local_idx*3+1] = Buffxyz[orig_idx*3+1];
165  surfmesh.xyz[local_idx*3+2] = Buffxyz[orig_idx*3+2];
166 
167  if (!std::isfinite(surfmesh.xyz[local_idx*3+0]) ||
168  !std::isfinite(surfmesh.xyz[local_idx*3+1]) ||
169  !std::isfinite(surfmesh.xyz[local_idx*3+2]))
170  {
171  fprintf(stderr, "NaN detected in the surface mesh coordinates! on tag=%d \n", tag);
172  exit(1);
173  }
174  }
175  }
176 }
177 
186 template<class T, class S>
187 inline void insert_points_to_surface_mesh( const meshdata<T, S> & mesh_original, meshdata<T, S> & surfmesh,
188  const SF_nbr numbering,
190 {
191  MPI_Comm comm = mesh_original.comm;
192 
193  const SF::vector<mesh_int_t> & rnod_original = mesh_original.get_numbering(numbering);
195  for(size_t i=0; i<rnod_original.size(); i++){
196  g2l_orig[rnod_original[i]] = i;
197  }
198 
199  const SF::vector<mesh_int_t> & rnod_surf = surfmesh.get_numbering(numbering);
200 
203  for(size_t i=0; i<rnod_surf.size(); i++){
204  g2l_surf[rnod_surf[i]] = i;
205  l2g_surf[i] = rnod_surf[i];
206  }
207 
208  mesh_int_t gmax = global_max(rnod_surf, comm);
209  surfmesh.g_numpts = gmax+1;
210 
211  SF::vector<mesh_real_t> Buffxyz = mesh_original.xyz;
212 
213  surfmesh.xyz.resize(surfmesh.l_numpts*3);
214 
215  for(size_t eidx = 0; eidx < surfmesh.l_numelem; eidx++) {
216  T tag = surfmesh.tag[eidx];
217 
218  for (int n = surfmesh.dsp[eidx]; n < surfmesh.dsp[eidx+1];n++)
219  {
220  T g = l2g_surf[surfmesh.con[n]];
221  T old_g = dof2vertex[g];
222 
223  const auto local_idx = g2l_surf[g];
224  const auto orig_idx = g2l_orig[old_g];
225 
226  surfmesh.xyz[local_idx*3+0] = Buffxyz[orig_idx*3+0];
227  surfmesh.xyz[local_idx*3+1] = Buffxyz[orig_idx*3+1];
228  surfmesh.xyz[local_idx*3+2] = Buffxyz[orig_idx*3+2];
229 
230  if (!std::isfinite(surfmesh.xyz[local_idx*3+0]) ||
231  !std::isfinite(surfmesh.xyz[local_idx*3+1]) ||
232  !std::isfinite(surfmesh.xyz[local_idx*3+2]))
233  {
234  fprintf(stderr, "NaN detected in the surface mesh coordinates! on tag=%d \n", tag);
235  exit(1);
236  }
237  }
238  }
239 }
240 
241 }
242 #endif
243 #endif
int mesh_int_t
Definition: SF_container.h:46
Functions related to mesh IO.
vector< S > xyz
node cooridnates
Definition: SF_container.h:427
MPI_Comm comm
the parallel mesh is defined on a MPI world
Definition: SF_container.h:404
vector< T > tag
element tag
Definition: SF_container.h:417
size_t size() const
The current size of the vector.
Definition: SF_vector.h:104
void resize(size_t n)
Resize a vector.
Definition: SF_vector.h:209
iterator find(const K &key)
Definition: hashmap.hpp:1006
Definition: dense_mat.hpp:34
T global_max(const vector< T > &vec, MPI_Comm comm)
Compute the global maximum of a distributed vector.
Definition: SF_network.h:156
SF_nbr
Enumeration encoding the different supported numberings.
Definition: SF_container.h:200