33 #define ELEC_STIFFNESS 1
63 int rank; MPI_Comm_rank(mesh.
comm, &rank);
69 fd = fopen(file,
"r");
73 fgets(buf,
sizeof(buf), fd);
77 int dpn_candidate;
char rest[4];
78 if (sscanf(buf,
"%d %3s", &dpn_candidate, rest) == 1 && (dpn_candidate == 1 || dpn_candidate == 3)) {
82 dpn = (sscanf(buf,
"%f %f %f", v, v+1, v+2) == 3) ? 3 : 1;
83 fseek(fd, 0, SEEK_SET);
87 MPI_Bcast(&dpn, 1, MPI_INT, 0, mesh.
comm);
92 if (rank == 0) fclose(fd);
94 if (nrd != (
size_t)(mesh.
g_numelem * dpn)) {
95 log_msg(0, 4, 0,
"%s error: %s scale file has wrong size (expected %zu elements * dpn=%d); skipping",
120 const char* msg_start)
123 printf(
"\n%s", msg_start);
126 printf(
"gregion[%d], ", *reg);
133 printf(
"\nVolume: %g", vol);
137 printf(
", fib: (%g, %g, %g), she: (%g, %g, %g), G: (%g, %g, %g)",
138 fib.
x, fib.
y, fib.
z, she.x, she.y, she.z, eVals[0]*1e3, eVals[1]*1e3, eVals[2]*1e3);
148 if(is_bath ==
false) {
151 evals[0] = emat.
InVal[0], evals[1] = emat.
InVal[1], evals[2] = emat.
InVal[2];
155 evals[0] = emat.
ExVal[0], evals[1] = emat.
ExVal[1], evals[2] = emat.
ExVal[2];
183 double gl = evals[0], gt = evals[1], gn = evals[2];
190 cond[0][0] += gt, cond[1][1] += gt, cond[2][2] += gt;
205 for(
int i=0; i<npts; i++){
206 if(pts[i].x!=pts[i].x or pts[i].y!=pts[i].y or pts[i].z!=pts[i].z){
207 printf(
" eidx = %d print_points ( %g %g %g ) \n", eidx, pts[i].x, pts[i].y, pts[i].z);
237 eVals[0] *= s; eVals[1] *= s; eVals[2] *= s;
240 double s = material.
el_scale[3*eidx];
241 eVals[0] *= s; eVals[1] *= s; eVals[2] *= s;
243 eVals[0] *= material.
el_scale[3*eidx];
244 eVals[1] *= material.
el_scale[3*eidx + 1];
245 eVals[2] *= material.
el_scale[3*eidx + 2];
264 buff.
assign(ndof, ndof, 0.0);
270 bool have_nan =
false;
273 for(
int iidx=0; iidx < nint; iidx++)
283 memcpy(Jbuff.
data(), J, 9*
sizeof(
double));
284 std::string j_name =
"J_" + std::to_string(iidx);
285 Jbuff.
disp(j_name.c_str());
290 double dx = w[iidx] * detj;
293 for (
int k = 0; k < ndof; k++) {
295 double skx = gshape[1][k], sky = gshape[2][k], skz = gshape[3][k];
296 double cx = cond[0][0] * skx + cond[0][1] * sky + cond[0][2] * skz;
297 double cy = cond[1][0] * skx + cond[1][1] * sky + cond[1][2] * skz;
298 double cz = cond[2][0] * skx + cond[2][1] * sky + cond[2][2] * skz;
300 for (
int l = 0; l < ndof; l++) {
302 double slx = gshape[1][l], sly = gshape[2][l], slz = gshape[3][l];
303 double val = - (cx*slx + cy * sly + cz * slz) * dx;
306 if(val != val) have_nan =
true;
313 printf(
"\n vol: %g \n\n", vol);
314 buff.
disp(
"Element Matrix:");
338 buff.
assign(ndof, ndof, 0.0);
343 bool have_nan =
false;
350 for(
int iidx=0; iidx < nint; iidx++)
358 double dx = w[iidx] * detj;
361 for (
int k = 0; k < ndof; k++) {
362 double sk = shape[0][k];
363 for (
int l = 0; l < ndof; l++) {
364 double sl = shape[0][l];
365 double val = sk * sl * dx;
368 if(val != val) have_nan =
true;
374 printf(
"\n vol: %g \n\n", vol);
375 buff.
disp(
"Mass Matrix:");
opencarp::local_index_t mesh_int_t
opencarp::real_t SF_real
Global scalar type.
size_t read_ascii(FILE *fd)
virtual void release_ptr(S *&p)=0
virtual T lsize() const =0
void assign(const dmat< S > &m)
copy a mtrix.
void set_size(const short irows, const short icols)
set the matrix dimensions
void disp(const char *name)
Comfort class. Provides getter functions to access the mesh member variables more comfortably.
Point fiber() const
Get element fiber direction.
void integration_points(const short order, Point *ip, double *w, int &nint) const
elem_t type() const
Getter function for the element type.
const T & global_node(short nidx) const
Access the connectivity information.
size_t global_element_index() const
Get currently selected element index.
size_t element_index() const
Get currently selected element index.
bool has_sheet() const
Check if a sheet direction is present.
T num_nodes() const
Getter function for the number of nodes.
Point sheet() const
Get element sheet direction.
size_t g_numelem
global number of elements
MPI_Comm comm
the parallel mesh is defined on a MPI world
Container for a PETSc VecScatter.
size_t size() const
The current size of the vector.
void assign(InputIterator s, InputIterator e)
Assign a memory range.
void operator()(const SF::element_view< mesh_int_t, mesh_real_t > &elem, SF::dmat< double > &buff)
compute the element matrix for a given element.
void dpn(mesh_int_t &row_dpn, mesh_int_t &col_dpn)
return (by reference) the row and column dimensions
void dpn(mesh_int_t &row_dpn, mesh_int_t &col_dpn)
return (by reference) the row and column dimensions
void operator()(const SF::element_view< mesh_int_t, mesh_real_t > &elem, SF::dmat< double > &buff)
compute the element matrix for a given element.
void shape_deriv(const double *iJ, const dmat< double > &rshape, const int ndof, dmat< double > &shape)
Compute shape derivatives for an element, based on the shape derivatives of the associated reference ...
double inner_prod(const Point &a, const Point &b)
void outer_prod(const Point &a, const Point &b, const double s, double *buff, const bool add=false)
void jacobian_matrix(const dmat< double > &rshape, const int npts, const Point *pts, double *J)
Compute Jacobian matrix from the real element to the reference element.
void init_vector(SF::abstract_vector< T, S > **vec)
void get_transformed_pts(const element_view< T, S > &view, Point *loc_pts, Point &trsf_fibre, bool orthogonal=true)
void reference_shape(const elem_t type, const Point ip, dmat< double > &rshape)
Compute shape function and its derivatives on a reference element.
@ NBR_ELEM_REF
The element numbering of the reference mesh (the one stored on HD).
@ NBR_REF
The nodal numbering of the reference mesh (the one stored on HD).
void invert_jacobian_matrix(const elem_t type, double *J, double &detJ)
void print_element_info(const SF::element_view< mesh_int_t, mesh_real_t > &elem, const int *reg, const double vol, const double *eVals, const char *msg_start)
void print_points(SF::Point *pts, int npts, int eidx)
void read_el_scale_vec(const char *file, mesh_t mt, SF::vector< double > &el_scale, int &el_scale_dpn)
sf_mesh & get_mesh(const mesh_t gt)
Get a mesh by specifying the gridID.
SF::scattering * get_permutation(const int mesh_id, const int perm_id, const int dpn)
Get the PETSC to canonical permutation scattering for a given mesh and number of dpn.
vec3< V > cross(const vec3< V > &a, const vec3< V > &b)
const char * get_mesh_type_name(mesh_t t)
get a char* to the name of a mesh type
bool phys_defined(int physreg)
function to check if certain physics are defined
void get_conductivity_evals(const elecMaterial &emat, const bool is_bath, double *evals)
SF::scattering * register_permutation(const int mesh_id, const int perm_id, const int dpn)
Register a permutation between two orderings for a mesh.
void log_msg(FILE_SPEC out, int level, unsigned char flag, const char *fmt,...)
mesh_t
The enum identifying the different meshes we might want to load.
int get_preferred_int_order(SF::elem_t &etype, int mat_type)
int get_size(MPI_Comm comm=PETSC_COMM_WORLD)
void get_conductivity(const double *evals, const SF::Point *f, const SF::Point *s, SF::dmat< double > &cond)
#define PHYSREG_INTRA_ELEC
#define ELEM_PETSC_TO_CANONICAL
Permute algebraic element data from PETSC to canonical ordering.
SF::vector< RegionSpecs > regions
array with region params
SF::vector< double > el_scale
optionally provided per-element params scale
SF::vector< int > regionIDs
elemental region IDs (multiple tags are grouped in one region)
int el_scale_dpn
0=disabled, 1=isotropic scalar, 3=anisotropic (sl, st, sn) per element
region based variations of arbitrary material parameters
physMaterial * material
material parameter description
double ExVal[3]
extracellular conductivity eigenvalues
cond_t g
rule to build conductivity tensor
double InVal[3]
intracellular conductivity eigenvalues
double BathVal[3]
bath conductivity eigenvalues
physMat_t material_type
ID of physics material.