[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Getfem-commits] r4585 - in /trunk/getfem/src: getfem/getfem_models.h ge
From: |
andriy . andreykiv |
Subject: |
[Getfem-commits] r4585 - in /trunk/getfem/src: getfem/getfem_models.h getfem_models.cc |
Date: |
Thu, 03 Apr 2014 13:06:12 -0000 |
Author: andrico
Date: Thu Apr 3 15:06:11 2014
New Revision: 4585
URL: http://svn.gna.org/viewcvs/getfem?rev=4585&view=rev
Log:
added pre- and post- assembly in methods to virtual_brick that
will be called in serial before and after asm_real(complex)_tangent_terms
These methods can be used, for instance, to add Neumann terms, which cannot be
parallelized
Modified:
trunk/getfem/src/getfem/getfem_models.h
trunk/getfem/src/getfem_models.cc
Modified: trunk/getfem/src/getfem/getfem_models.h
URL:
http://svn.gna.org/viewcvs/getfem/trunk/getfem/src/getfem/getfem_models.h?rev=4585&r1=4584&r2=4585&view=diff
==============================================================================
--- trunk/getfem/src/getfem/getfem_models.h (original)
+++ trunk/getfem/src/getfem/getfem_models.h Thu Apr 3 15:06:11 2014
@@ -1043,6 +1043,19 @@
{ BRICK_NOT_INIT; return compute_each_time; }
const std::string &brick_name(void) const { BRICK_NOT_INIT; return name; }
+
+ /**Assembly of bricks real tangent terms.
+ In case of Getfem's compilation with OpenMP option,
+ this method is executed on multiple threads.
+ The parallelism is provided by distributing all tangent matrices and
+ vectors and accumulating them later into the original. Additionally,
+ by default, all mesh_region objects, participating in the assembly, are
also
+ partitioned. In order to avoid data race conditions, this method should
not
+ modify any data simultaneously accessible from multiple threads. In case
+ this is unavoidable, the race can be prevented by distributing this data
+ (of type T) between the threads via getfem::omp_distribute<T> (prefered
method) or
+ protected from concurrent access with mutexes (e.g. getfem::omp_lock) or
OpenMP
+ critical section. */
virtual void asm_real_tangent_terms(const model &, size_type,
const model::varnamelist &,
const model::varnamelist &,
@@ -1053,6 +1066,19 @@
size_type, build_version) const
{ GMM_ASSERT1(false, "Brick has no real tangent terms !"); }
+
+ /**Assembly of bricks complex tangent terms.
+ In case of Getfem's compilation with OpenMP option,
+ this method is executed on multiple threads.
+ The parallelism is provided by distributing all tangent matrices and
+ vectors and accumulating them later into the original. Additionally,
+ by default, all mesh_region objects, participating in the assembly, are
also
+ partitioned. In order to avoid data race conditions, this method should
not
+ modify any data simultaneously accessible from multiple threads. In case
+ this is unavoidable, the race can be prevented by distributing this data
+ (of type T) between the threads via getfem::omp_distribute<T> (prefered
method) or
+ protected from concurrent access with mutexes (e.g. getfem::omp_lock) or
OpenMP
+ critical section. */
virtual void asm_complex_tangent_terms(const model &, size_type,
const model::varnamelist &,
const model::varnamelist &,
@@ -1062,6 +1088,59 @@
model::complex_veclist &,
size_type, build_version) const
{ GMM_ASSERT1(false, "Brick has no complex tangent terms !"); }
+
+
+ /**Peform any pre assembly action for real term assembly. The purpose of
this method
+ is to do any action that cannot be peformed in the main assembly routines
in parallel.
+ Possible action can be modification of the model object, cashing some data
that cannot be
+ distributed etc. */
+ virtual void real_pre_assembly_in_serial(const model &, size_type,
+ const model::varnamelist &,
+ const model::varnamelist &,
+ const model::mimlist &,
+ model::real_matlist &,
+ model::real_veclist &,
+ model::real_veclist &,
+ size_type, build_version) const { };
+
+ /**Peform any pre assembly action for comple term assembly. The purpose of
this method
+ is to do any action that cannot be peformed in the main assembly routines
in parallel.
+ Possible action can be modification of the model object, cashing some data
that cannot be
+ distributed etc. */
+ virtual void complex_pre_assembly_in_serial(const model &, size_type,
+ const model::varnamelist &,
+ const model::varnamelist &,
+ const model::mimlist &,
+ model::complex_matlist &,
+ model::complex_veclist &,
+ model::complex_veclist &,
+ size_type, build_version) const { };
+
+ /**Peform any post assembly action for real terms. The purpose of this
method
+ is to do any action that cannot be peformed in the main assembly routines
in parallel.
+ Possible action can be modification of the model object, cashing some data
that cannot be
+ distributed etc. */
+ virtual void real_post_assembly_in_serial(const model &, size_type,
+ const model::varnamelist &,
+ const model::varnamelist &,
+ const model::mimlist &,
+ model::real_matlist &,
+ model::real_veclist &,
+ model::real_veclist &,
+ size_type, build_version) const { };
+
+ /**Peform any post assembly action for complex terms. The purpose of this
method
+ is to do any action that cannot be peformed in the main assembly routines
in parallel.
+ Possible action can be modification of the model object, cashing some data
that cannot be
+ distributed etc. */
+ virtual void complex_post_assembly_in_serial(const model &, size_type,
+ const model::varnamelist &,
+ const model::varnamelist &,
+ const model::mimlist &,
+ model::complex_matlist &,
+ model::complex_veclist &,
+ model::complex_veclist &,
+ size_type, build_version) const { };
virtual scalar_type asm_real_pseudo_potential(const model &, size_type,
Modified: trunk/getfem/src/getfem_models.cc
URL:
http://svn.gna.org/viewcvs/getfem/trunk/getfem/src/getfem_models.cc?rev=4585&r1=4584&r2=4585&view=diff
==============================================================================
--- trunk/getfem/src/getfem_models.cc (original)
+++ trunk/getfem/src/getfem_models.cc Thu Apr 3 15:06:11 2014
@@ -847,50 +847,108 @@
void model::brick_call(size_type ib, build_version version,
- size_type rhs_ind) const {
+ size_type rhs_ind) const
+ {
const brick_description &brick = bricks[ib];
bool cplx = is_complex() && brick.pbr->is_complex();
brick_init(ib, version, rhs_ind);
+ scalar_type time = gmm::uclock_sec();
+
if (cplx)
- brick.pbr->asm_complex_tangent_terms(*this, ib, brick.vlist, brick.dlist,
+ {
+ brick.pbr->complex_pre_assembly_in_serial(*this, ib, brick.vlist,
brick.dlist,
brick.mims,
brick.cmatlist,
brick.cveclist[rhs_ind],
brick.cveclist_sym[rhs_ind],
brick.region, version);
- else{
-
+ /*distributing the resulting vectors and matrices
+ for individual threads.*/
+ {//brackets are needed because list_distro has constructor/destructor
+ //semantics (as in RAII)
+ list_distro<complex_matlist> cmatlist(brick.cmatlist);
+ list_distro<complex_veclist> cveclist(brick.cveclist[rhs_ind]);
+ list_distro<complex_veclist>
cveclist_sym(brick.cveclist_sym[rhs_ind]);
+ GMM_TRACE2("Matrix distribution took "<< gmm::uclock_sec()-time<<"
s.");
+ time = gmm::uclock_sec();
+ /*running the assembly in parallel*/
+ gmm::standard_locale locale;
+ open_mp_is_running_properly check;
+ #pragma omp parallel default(shared)
+ {
+ #pragma omp for schedule(static)
+ for(size_type i=0;i<num_threads();i++)
+ {
+ brick.pbr->asm_complex_tangent_terms(*this, ib, brick.vlist,
brick.dlist,
+ brick.mims,
+ cmatlist,
+ cveclist,
+ cveclist_sym,
+ brick.region, version);
+ }
+ }
+ }
+ brick.pbr->complex_post_assembly_in_serial(*this, ib, brick.vlist,
brick.dlist,
+ brick.mims,
+ brick.cmatlist,
+ brick.cveclist[rhs_ind],
+ brick.cveclist_sym[rhs_ind],
+ brick.region, version);
+
+ }
+
+ else //not cplx
+
+ {
+ brick.pbr->real_pre_assembly_in_serial(*this, ib, brick.vlist,
brick.dlist,
+ brick.mims,
+ brick.rmatlist,
+ brick.rveclist[rhs_ind],
+ brick.rveclist_sym[rhs_ind],
+ brick.region, version);
+ {
/*distributing the resulting vectors and matrices
for individual threads.*/
- scalar_type time = gmm::uclock_sec();
- list_distro<real_matlist> rmatlist(brick.rmatlist);
- list_distro<real_veclist> rveclist(brick.rveclist[rhs_ind]);
- list_distro<real_veclist> rveclist_sym(brick.rveclist_sym[rhs_ind]);
- GMM_TRACE2("Matrix distribution took "<< gmm::uclock_sec()-time<<" s.");
- time = gmm::uclock_sec();
+ list_distro<real_matlist> rmatlist(brick.rmatlist);
+ list_distro<real_veclist> rveclist(brick.rveclist[rhs_ind]);
+ list_distro<real_veclist>
rveclist_sym(brick.rveclist_sym[rhs_ind]);
+ GMM_TRACE2("Matrix distribution took "<< gmm::uclock_sec()-time<<"
s.");
+ time = gmm::uclock_sec();
/*running the assembly in parallel*/
- gmm::standard_locale locale;
- open_mp_is_running_properly check;
-#pragma omp parallel default(shared)
- {
-#pragma omp for schedule(static)
- for(size_type i=0;i<num_threads();i++){
- brick.pbr->asm_real_tangent_terms(*this, ib, brick.vlist,
brick.dlist,
- brick.mims,
- rmatlist,
- rveclist,
- rveclist_sym,
- brick.region,
- version);
- }
- }
- double assembly_time = gmm::uclock_sec()-time;
- GMM_TRACE2("Assembly time "<< assembly_time<<" s.");
- }
+ gmm::standard_locale locale;
+ open_mp_is_running_properly check;
+ #pragma omp parallel default(shared)
+ {
+ #pragma omp for schedule(static)
+ for(size_type i=0;i<num_threads();i++)
+ {
+ brick.pbr->asm_real_tangent_terms(*this, ib, brick.vlist,
brick.dlist,
+ brick.mims,
+ rmatlist,
+ rveclist,
+ rveclist_sym,
+ brick.region,
+ version);
+ }
+ }
+ }
+ brick.pbr->real_post_assembly_in_serial(*this, ib, brick.vlist,
brick.dlist,
+ brick.mims,
+ brick.rmatlist,
+ brick.rveclist[rhs_ind],
+ brick.rveclist_sym[rhs_ind],
+ brick.region, version);
+ }
+
+ GMM_TRACE2("Assembly time "<< gmm::uclock_sec()-time<<" s.");
}
+
+
+
+
void model::set_dispatch_coeff(void) {
for (dal::bv_visitor ib(active_bricks); !ib.finished(); ++ib) {
@@ -2503,6 +2561,46 @@
} else
GMM_ASSERT1(false, "Bad format generic elliptic brick coefficient");
+ }
+
+ virtual void real_post_assembly_in_serial(const model &md, size_type ib,
+ const model::varnamelist &vl,
+ const model::varnamelist &dl,
+ const model::mimlist &mims,
+ model::real_matlist &matl,
+ model::real_veclist &,
+ model::real_veclist &,
+ size_type region,
+ build_version) const
+ {
+ const model_real_plain_vector *A = 0;
+ const mesh_fem *mf_a = 0;
+ if (dl.size() > 0)
+ {
+ A = &(md.real_variable(dl[0]));
+ mf_a = md.pmesh_fem_of_variable(dl[0]);
+ }
+ pNeumann_elem_term pNt = new generic_elliptic_Neumann_elem_term(mf_a, A);
+ md.add_Neumann_term(pNt, vl[0], ib);
+ }
+
+ virtual void complex_post_assembly_in_serial(const model &md, size_type ib,
+ const model::varnamelist &vl,
+ const model::varnamelist &dl,
+ const model::mimlist &mims,
+ model::complex_matlist &matl,
+ model::complex_veclist &,
+ model::complex_veclist &,
+ size_type region,
+ build_version) const
+ {
+ const model_real_plain_vector *A = 0;
+ const mesh_fem *mf_a = 0;
+ if (dl.size() > 0)
+ {
+ A = &(md.real_variable(dl[0]));
+ mf_a = md.pmesh_fem_of_variable(dl[0]);
+ }
pNeumann_elem_term pNt = new generic_elliptic_Neumann_elem_term(mf_a, A);
md.add_Neumann_term(pNt, vl[0], ib);
}
@@ -5514,11 +5612,8 @@
asm_stiffness_matrix_for_homogeneous_linear_elasticity
(matl[0], mim, mf_u, *lambda, *mu, rg);
-
- pNeumann_elem_term pNt = new iso_lin_elasticity_Neumann_elem_term
- (mf_lambda, lambda, mf_mu, mu);
- md.add_Neumann_term(pNt, vl[0], ib);
- }
+ }
+
if (dl.size() == 3) { // Pre-constraints given by an "initial"
// displacement u0. Means that the computed displacement will be u - u0
@@ -5527,6 +5622,33 @@
gmm::mult(matl[0],
gmm::scaled(md.real_variable(dl[2]), scalar_type(-1)),
vecl[0]);
+ }
+ }
+
+ virtual void real_post_assembly_in_serial(const model &md, size_type ib,
+ const model::varnamelist &vl,
+ const model::varnamelist &dl,
+ const model::mimlist &mims,
+ model::real_matlist &matl,
+ model::real_veclist &,
+ model::real_veclist &,
+ size_type region,
+ build_version version) const
+ {
+ bool recompute_matrix = !((version & model::BUILD_ON_DATA_CHANGE) != 0)
+ || md.is_var_newer_than_brick(dl[0], ib)
+ || md.is_var_newer_than_brick(dl[1], ib);
+
+ if (recompute_matrix)
+ {
+ const mesh_fem *mf_lambda = md.pmesh_fem_of_variable(dl[0]);
+ const model_real_plain_vector *lambda = &(md.real_variable(dl[0]));
+ const mesh_fem *mf_mu = md.pmesh_fem_of_variable(dl[1]);
+ const model_real_plain_vector *mu = &(md.real_variable(dl[1]));
+
+ pNeumann_elem_term pNt = new
iso_lin_elasticity_Neumann_elem_term
+ (mf_lambda, lambda, mf_mu, mu);
+ md.add_Neumann_term(pNt, vl[0], ib);
}
}
@@ -5749,12 +5871,6 @@
gmm::clear(matl[0]);
asm_stokes_B(matl[0], mim, mf_u, mf_p, rg);
- pNeumann_elem_term pNt = new lin_incomp_Neumann_elem_term
- (md.version_number_of_data_variable( vl[1]), &mf_p,
- &(md.real_variable(vl[1])), vl[1]);
- md.add_Neumann_term(pNt, vl[0], ib);
- md.add_auxilliary_variables_of_Neumann_terms(vl[0], vl[1]);
-
if (penalized) {
gmm::clear(matl[1]);
if (mf_data) {
@@ -5768,6 +5884,26 @@
}
}
+
+
+ virtual void real_post_assembly_in_serial(const model &md, size_type ib,
+ const model::varnamelist &vl,
+ const model::varnamelist &dl,
+ const model::mimlist &mims,
+ model::real_matlist &matl,
+ model::real_veclist &,
+ model::real_veclist &,
+ size_type region,
+ build_version) const
+ {
+ const mesh_fem &mf_p = md.mesh_fem_of_variable(vl[1]);
+ pNeumann_elem_term pNt = new lin_incomp_Neumann_elem_term
+ (md.version_number_of_data_variable( vl[1]), &mf_p,
+ &(md.real_variable(vl[1])), vl[1]);
+ md.add_Neumann_term(pNt, vl[0], ib);
+ md.add_auxilliary_variables_of_Neumann_terms(vl[0], vl[1]);
+ }
+
linear_incompressibility_brick(void) {
set_flags("Linear incompressibility brick",
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Getfem-commits] r4585 - in /trunk/getfem/src: getfem/getfem_models.h getfem_models.cc,
andriy . andreykiv <=