18 #define ELEC_STIFFNESS 1
48 int rank; MPI_Comm_rank(mesh.
comm, &rank);
54 fd = fopen(file,
"r");
58 fgets(buf,
sizeof(buf), fd);
62 int dpn_candidate;
char rest[4];
63 if (sscanf(buf,
"%d %3s", &dpn_candidate, rest) == 1 && (dpn_candidate == 1 || dpn_candidate == 3)) {
67 dpn = (sscanf(buf,
"%f %f %f", v, v+1, v+2) == 3) ? 3 : 1;
68 fseek(fd, 0, SEEK_SET);
72 MPI_Bcast(&dpn, 1, MPI_INT, 0, mesh.
comm);
77 if (rank == 0) fclose(fd);
79 if (nrd != (
size_t)(mesh.
g_numelem * dpn)) {
80 log_msg(0, 4, 0,
"%s error: %s scale file has wrong size (expected %zu elements * dpn=%d); skipping",
105 const char* msg_start)
108 printf(
"\n%s", msg_start);
111 printf(
"gregion[%d], ", *reg);
118 printf(
"\nVolume: %g", vol);
122 printf(
", fib: (%g, %g, %g), she: (%g, %g, %g), G: (%g, %g, %g)",
123 fib.
x, fib.
y, fib.
z, she.x, she.y, she.z, eVals[0]*1e3, eVals[1]*1e3, eVals[2]*1e3);
133 if(is_bath ==
false) {
136 evals[0] = emat.
InVal[0], evals[1] = emat.
InVal[1], evals[2] = emat.
InVal[2];
140 evals[0] = emat.
ExVal[0], evals[1] = emat.
ExVal[1], evals[2] = emat.
ExVal[2];
168 double gl = evals[0], gt = evals[1], gn = evals[2];
175 cond[0][0] += gt, cond[1][1] += gt, cond[2][2] += gt;
190 for(
int i=0; i<npts; i++){
191 if(pts[i].x!=pts[i].x or pts[i].y!=pts[i].y or pts[i].z!=pts[i].z){
192 printf(
" eidx = %d print_points ( %g %g %g ) \n", eidx, pts[i].x, pts[i].y, pts[i].z);
222 eVals[0] *= s; eVals[1] *= s; eVals[2] *= s;
225 double s = material.
el_scale[3*eidx];
226 eVals[0] *= s; eVals[1] *= s; eVals[2] *= s;
228 eVals[0] *= material.
el_scale[3*eidx];
229 eVals[1] *= material.
el_scale[3*eidx + 1];
230 eVals[2] *= material.
el_scale[3*eidx + 2];
249 buff.
assign(ndof, ndof, 0.0);
255 bool have_nan =
false;
258 for(
int iidx=0; iidx < nint; iidx++)
268 memcpy(Jbuff.
data(), J, 9*
sizeof(
double));
269 std::string j_name =
"J_" + std::to_string(iidx);
270 Jbuff.
disp(j_name.c_str());
275 double dx = w[iidx] * detj;
278 for (
int k = 0; k < ndof; k++) {
280 double skx = gshape[1][k], sky = gshape[2][k], skz = gshape[3][k];
281 double cx = cond[0][0] * skx + cond[0][1] * sky + cond[0][2] * skz;
282 double cy = cond[1][0] * skx + cond[1][1] * sky + cond[1][2] * skz;
283 double cz = cond[2][0] * skx + cond[2][1] * sky + cond[2][2] * skz;
285 for (
int l = 0; l < ndof; l++) {
287 double slx = gshape[1][l], sly = gshape[2][l], slz = gshape[3][l];
288 double val = - (cx*slx + cy * sly + cz * slz) * dx;
291 if(val != val) have_nan =
true;
298 printf(
"\n vol: %g \n\n", vol);
299 buff.
disp(
"Element Matrix:");
323 buff.
assign(ndof, ndof, 0.0);
328 bool have_nan =
false;
335 for(
int iidx=0; iidx < nint; iidx++)
343 double dx = w[iidx] * detj;
346 for (
int k = 0; k < ndof; k++) {
347 double sk = shape[0][k];
348 for (
int l = 0; l < ndof; l++) {
349 double sl = shape[0][l];
350 double val = sk * sl * dx;
353 if(val != val) have_nan =
true;
359 printf(
"\n vol: %g \n\n", vol);
360 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.